MariaDB 강좌 / mariadb-dump로 데이터베이스 백업하기
mariadb-dump는 테이블 정의와 행 등을 재생할 SQL 파일을 만드는 논리 백업 도구입니다. InnoDB의 일관된 스냅샷 옵션과 저장 경로·오류 확인을 명시하고, 파일이 생성되었다는 사실보다 별도 DB 복원이 되는지를 백업의 검증 기준으로 삼아야 합니다.
백업 범위와 복구 목표부터 정하기
이 글은 별도 학습 DB backup46_lab의 네 InnoDB 테이블을 백업합니다. 운영 인스턴스 전체, 계정·권한·서버 설정·외부 파일을 모두 보존하는 절차는 아닙니다. 장애 시 허용 가능한 데이터 손실 시점과 복구 시간을 먼저 정해야 백업 주기·보관 위치·추가 로그 전략을 선택할 수 있습니다.
| 항목 | 이 예제 | 추가 검토 |
|---|---|---|
| 데이터 | 네 InnoDB 테이블 | 다른 엔진·대용량·동시 DDL |
| 객체 | 기본 테이블과 키 | 뷰·정의자·루틴·트리거·이벤트 목록 |
| 계정·설정 | 백업 범위 밖 | 별도 권한·서버 구성 복구 |
| 검증 | 다른 DB에 복원 | 행·제약·업무 합계·접근 권한 |
이전 자료를 건드리지 않는 학습 DB 준비하기
관리자 연결에서 backup46_lab이 없는지 SHOW DATABASES로 확인하고 아래 코드를 실행합니다. 이미 있는 이름이면 중단하고 다른 실습 이름을 정합니다. CREATE OR REPLACE나 DROP DATABASE로 기존 자료를 없애지 않습니다. 이 글을 독립 실행할 수 있도록 전체 주문 데이터를 제공합니다.
CREATE DATABASE backup46_lab CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE backup46_lab; CREATE TABLE c46_customers ( customer_id INT NOT NULL PRIMARY KEY, customer_name VARCHAR(50) NOT NULL, city VARCHAR(30) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE c46_products ( product_id INT NOT NULL PRIMARY KEY, product_name VARCHAR(100) NOT NULL, category VARCHAR(30) NOT NULL, price DECIMAL(10,2) NOT NULL CHECK (price >= 0), stock INT NOT NULL CHECK (stock >= 0) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE c46_orders ( order_id INT NOT NULL PRIMARY KEY, customer_id INT NOT NULL, ordered_at DATETIME NOT NULL, status VARCHAR(20) NOT NULL, shipping_fee DECIMAL(10,2) NOT NULL DEFAULT 1000, CONSTRAINT fk_c46_order_customer FOREIGN KEY (customer_id) REFERENCES c46_customers(customer_id) ON DELETE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE c46_items ( order_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL CHECK (quantity > 0), unit_price DECIMAL(10,2) NOT NULL CHECK (unit_price >= 0), PRIMARY KEY (order_id, product_id), CONSTRAINT fk_c46_item_order FOREIGN KEY (order_id) REFERENCES c46_orders(order_id) ON DELETE RESTRICT, CONSTRAINT fk_c46_item_product FOREIGN KEY (product_id) REFERENCES c46_products(product_id) ON DELETE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; INSERT INTO c46_customers VALUES (1,'김민수','서울'),(2,'이서연','부산'), (3,'박지우','서울'),(4,'최하늘','대전'); INSERT INTO c46_products VALUES (1,'노트','문구',3500,20),(2,'볼펜','문구',1500,50), (3,'머그컵','생활',8000,12),(4,'스탠드','생활',25000,5); INSERT INTO c46_orders (order_id,customer_id,ordered_at,status,shipping_fee) VALUES (101,1,'2026-01-10 10:00:00','paid',1000), (102,1,'2026-01-20 11:00:00','paid',1000), (103,2,'2026-02-05 12:00:00','paid',1000), (104,3,'2026-02-10 13:00:00','canceled',1000); INSERT INTO c46_items VALUES (101,1,2,3500),(101,2,3,1500),(102,3,1,8000), (103,1,1,3500),(103,3,2,8000),(104,2,1,1500);
이후 명령을 course_user로 실행하려면 관리자가 이 전용 실습 DB에 필요한 권한을 부여해야 합니다. 기존 shopcourse 권한만으로 새 DB 권한이 생기지는 않습니다. 아래 ALL은 폐기 가능한 이 실습 DB에만 한정한 예이며 운영 백업 계정은 객체·옵션에 맞는 최소 권한을 따로 정합니다.
GRANT ALL PRIVILEGES ON backup46_lab.* TO 'course_user'@'127.0.0.1';
도구 버전·새 파일 경로·명령 실패 확인하기
mariadb-dump가 PATH에 있거나 설치한 bin 경로에서 실행할 수 있어야 합니다. 운영체제 터미널에서 버전을 확인하고 C:/mariadb-lab 폴더를 준비합니다. Windows PowerShell의 출력 리디렉션에 따른 인코딩 차이를 피하려고 --result-file을 사용합니다.
mariadb-dump --version mariadb --version
$backup46Path='C:/mariadb-lab/backup46-first.sql'
if (Test-Path -LiteralPath $backup46Path) { throw '새 백업 파일명을 지정하세요.' }
mariadb-dump --protocol=tcp --host=127.0.0.1 --port=3306 --user=course_user --password --default-character-set=utf8mb4 --single-transaction --quick --skip-lock-tables --result-file=C:/mariadb-lab/backup46-first.sql backup46_lab
if ($LASTEXITCODE -ne 0) { throw '백업 실패: 오류를 확인하고 파일을 검증하세요.' }
Get-Item -LiteralPath $backup46Path | Select-Object Name,Length
Get-FileHash -LiteralPath $backup46Path -Algorithm SHA256
비밀번호는 프롬프트에 입력하고 명령 문자열에 넣지 않습니다. 종료 코드가 실패하면 빈 파일이나 일부만 기록된 파일이 남았을 수 있습니다. 파일 크기가 0이 아니거나 해시가 계산된다고 완전한 복원 가능성을 보장하지는 않습니다.
single-transaction이 보장하는 조건 확인하기
--single-transaction은 InnoDB 등 트랜잭션을 지원하는 테이블의 일관된 읽기에 사용합니다. 덤프 중 ALTER·CREATE·DROP·RENAME·TRUNCATE 같은 구조 변경이 일어나면 일관성에 문제가 생길 수 있어 변경 작업과 조정해야 합니다. 비트랜잭션 엔진까지 같은 스냅샷으로 보장하지 않습니다.
--quick은 행을 순차적으로 읽도록 하고 --skip-lock-tables는 테이블 잠금 옵션과 충돌을 피하려는 이 예제의 선택입니다. 이것이 부하·잠금·네트워크 비용이 전혀 없는 백업이라는 뜻은 아닙니다. --databases를 사용하지 않아 다른 이름의 DB로 복원하는 실습을 준비합니다. mariadb-dump 옵션과 일관성 조건을 확인하세요.
테이블 밖 객체와 비밀 데이터의 보관 정책 점검하기
이 데이터에는 루틴·이벤트·트리거·뷰가 없습니다. 실제 DB에 그런 객체가 있다면 현재 버전의 덤프 옵션과 권한, 정의자 계정, 복원 후 실행 환경을 확인해야 합니다. 루틴·이벤트는 --routines·--events 등 해당 옵션을 검토하고 트리거 포함 여부도 실제 파일에서 확인합니다. 옵션 이름만 보고 모든 의존 객체가 복구된다고 단정하지 않습니다.
덤프 파일에는 업무 데이터와 정의가 들어갑니다. 접근 권한·암호화·보관 기간·별도 장애 영역의 사본을 정책에 맞게 관리하고 공개 저장소나 웹 폴더에 두지 않습니다. 같은 디스크의 파일 하나만으로 디스크 장애를 대비했다고 판단하지 않습니다.
복원 검증 전 원본을 지우지 않기
별도 빈 DB로 복원해 테이블 수·행 수·키와 업무 합계를 확인할 때까지 원본 실습 DB와 백업을 유지합니다. 원본의 고객 4명·상품 4개·주문 4건·상세 6행, paid 상품 금액 39000을 기록해 비교 기준으로 삼습니다. 이 글의 끝에서 원본 DB를 자동 삭제하지 않으며 실제 필요한 자료인지 확인한 후 별도 정리합니다.
SELECT SUM(i.quantity*i.unit_price) AS paid_goods FROM backup46_lab.c46_orders o JOIN backup46_lab.c46_items i ON i.order_id=o.order_id WHERE o.status='paid';











