MariaDB講座 / 別のデータベースへ復元してバックアップを検証する

バックアップは別の空データベースへ復元し、定義、行、制約と業務合計で検証します。実行前にDBを切り替える命令や削除文を調べ、最初のエラーで止めて、部分復元を成功と混同しないようにします。

接続時のDB名だけを信用しない

ダンプ内のCREATE DATABASE、USEや完全修飾名は、接続で選んだDBの外へ作業を向け得ます。生成元、版とオプションを確認し、DROP TABLEが含まれることも考えます。データのあるDBを復元試験先にしません。

ダンプ条件、確定済み注文の復元と照合します。ファイル、未使用の空対象、実行の第一エラー、定義・件数・内容・業務値を別々に確認します。

この記事専用の元DBを準備する

管理者がrestore47_sourceとrestore47_targetが未使用か確認します。前の記事とは独立した完全例です。別の記事のSQLファイルを使うなら、その実際の表名と基準へ合わせます。

CREATE DATABASE restore47_source CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE restore47_source;
CREATE TABLE c47_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 c47_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 c47_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_c47_order_customer FOREIGN KEY (customer_id)
  REFERENCES c47_customers(customer_id) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE c47_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_c47_item_order FOREIGN KEY (order_id)
  REFERENCES c47_orders(order_id) ON DELETE RESTRICT,
 CONSTRAINT fk_c47_item_product FOREIGN KEY (product_id)
  REFERENCES c47_products(product_id) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO c47_customers VALUES
 (1,'김민수','서울'),(2,'이서연','부산'),
 (3,'박지우','서울'),(4,'최하늘','대전');
INSERT INTO c47_products VALUES
 (1,'노트','문구',3500,20),(2,'볼펜','문구',1500,50),
 (3,'머그컵','생활',8000,12),(4,'스탠드','생활',25000,5);
INSERT INTO c47_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 c47_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);

顧客名と都市、商品名は原文の韓国語サンプルを保っています。商品1~4はノート、ペン、マグカップ、ライト、顧客1・3はソウル、2は釜山、4は大田です。UTF-8で保存・接続し、IDと数値で結果を照合します。

実習アカウントへ必要な二領域だけを与え、空の復元先を作ります。

GRANT ALL PRIVILEGES ON restore47_source.* TO 'course_user'@'127.0.0.1';
CREATE DATABASE restore47_target CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
GRANT ALL PRIVILEGES ON restore47_target.* TO 'course_user'@'127.0.0.1';

新しいファイルへバックアップする

Windowsでは端末で実行します。

New-Item -ItemType Directory -Path 'C:/mariadb-lab' -Force | Out-Null
$courseBackupPath='C:/mariadb-lab/restore47-source.sql'
if (Test-Path -LiteralPath $courseBackupPath) { throw 'Choose a new backup filename.' }
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=$courseBackupPath restore47_source
if ($LASTEXITCODE -ne 0) { throw 'Backup failed; do not restore this file.' }
Get-Item -LiteralPath $courseBackupPath | Select-Object Name,Length
Get-FileHash -LiteralPath $courseBackupPath -Algorithm SHA256

Ubuntuなら次を代わりに使い、実際のファイル位置を記録します。

mkdir -p "$HOME/mariadb-lab"
(
  umask 077
  set -C
  backup_file="$HOME/mariadb-lab/restore47-source.sql"
  if 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 restore47_source > "$backup_file"; then
    test -s "$backup_file" || exit 1
    sha256sum "$backup_file"
  else
    printf '%s\n' 'Backup failed; preserve the partial file for diagnosis.' >&2
    exit 1
  fi
)

既存の出力先なら停止します。途中ファイルを復元せず、診断して新名へ再試行します。サイズとハッシュは証拠の一部で、復旧可能性そのものではありません。TLS検証に失敗したらクライアントとサーバーの版、名前、CAと必要証明書を調べます。

空の対象へ互換性のあるクライアントで接続する

端末から接続します。

mariadb --abort-source-on-error --protocol=tcp --host=127.0.0.1 --port=3306 --user=course_user --password --default-character-set=utf8mb4 restore47_target

接続内で実際のDBと空の表一覧を確認してから、信頼するファイルを実行します。

SELECT VERSION(),DATABASE();
SHOW TABLES;
SOURCE C:/mariadb-lab/restore47-source.sql;

新しいダンプは古いMariaDBやMySQLクライアントが理解しないsandbox指示を含む場合があります。未知の指示を慣例的に消さず、対応するMariaDBのダンプ・クライアントを選びます。

Ubuntuの復元は実パスへ読み替える

同じ対象へ接続し、learnerは実際のユーザー名へ変えます。

mariadb --abort-source-on-error --protocol=tcp --host=127.0.0.1 --port=3306 --user=course_user --password --default-character-set=utf8mb4 restore47_target
SELECT DATABASE();
SHOW TABLES;
SOURCE /home/learner/mariadb-lab/restore47-source.sql;

同じ対象でWindows版と両方を実行しません。--abort-source-on-errorは後続を止めますが、すでに作成・確定したものを戻しません。失敗後は原因を直して新しい空の対象でやり直します。

定義・行・制約・金額を比較する

復元先で実行します。

SELECT TABLE_NAME,TABLE_TYPE FROM information_schema.TABLES
WHERE TABLE_SCHEMA='restore47_target' ORDER BY TABLE_NAME;
SELECT (SELECT COUNT(*) FROM restore47_target.c47_customers) AS customers,
 (SELECT COUNT(*) FROM restore47_target.c47_products) AS products,
 (SELECT COUNT(*) FROM restore47_target.c47_orders) AS orders_count,
 (SELECT COUNT(*) FROM restore47_target.c47_items) AS detail_rows;
SELECT SUM(i.quantity*i.unit_price) AS paid_goods
FROM restore47_target.c47_orders o
JOIN restore47_target.c47_items i ON i.order_id=o.order_id WHERE o.status='paid';
SHOW CREATE TABLE restore47_target.c47_items;

四つの基本表、件数4・4・4・6、paid合計39000を期待します。主キー、外部キー、数量・価格のCHECKもSHOW CREATE TABLEで読みます。件数一致だけでは内容一致にならないため、主キーごとの元行と重要なJOINも比較します。

本番ではビュー、ルーチン、トリガー、イベントの定義と動作、定義者・呼出者も確認します。DBダンプが全アカウント、権限、サーバー設定を復元するとは限りません。

途中失敗を残して判断する

構文、権限、DEFINERや文字コードのエラーは、いくつかの作成後に起きる場合があります。--forceで通して成功とせず、エラーと部分状態を記録します。外部キー検査を勝手に切って隠さず、ダンプが保存・復元する設定も確認します。

DDL全体は普通の一トランザクションではありません。実切替やアプリケーション遮断、後続書き込み防止は別手順です。版、ハッシュ、対象、実行時間と検証結果を残し、完了まで元DBとバックアップを保持します。この記事はDBを自動削除しません。

関連する公式リファレンス