データベースの復元って、実はそんなに簡単じゃないんだよね。一見うまくいったように見えても、後からログにエラーが出てきたり、テーブルが消えてたり、データが怪しく見えたりすることもある。だからこそ、復元した後は必ず「本当に大丈夫か?」ってチェックするのが超大事なんだ。
たまに、データの一部が復元されてないこともある。例えば、バックアップファイルが壊れてた場合とか。テーブルの構造が崩れることもあるし、外部キーが消えたり、インデックスがなくなったり、変な値が入ってたりもする。ぱっと見は普通でも、ログを見たら「実はこのDB、ちょっとヤバいかも」ってヒントが隠れてることも。
整合性チェックは、修理後の車検みたいなもん。ちょっと時間かけてでも「ちゃんと動く」って確認した方が、後で本番環境で突然トラブルに遭うより絶対いいよ。
復元ログの分析
pg_restoreでデータを復元すると、PostgreSQLは必ずログを出してくれる。このログには、復元プロセスのいろんな情報が詰まってて、警告やエラーも全部ここに出る。例えば、ログファイルを指定してコマンドを実行する場合はこんな感じ:
pg_restore -U username -d database_name backup_file.dump > restore_log.txt 2>&1
> restore_log.txt 2>&1に注目してね。これは標準出力もエラーも全部一つのファイルにまとめてくれる。
ログで何を探せばいい?
エラー。 "ERROR"や"FATAL"みたいなキーワードに注目しよう。例:
ERROR: relation "students" does not exist警告。 たまに"WARNING"って警告が出ることもある。致命的じゃないけど、ちゃんと読んでおいた方がいい。何か問題のサインかも:
WARNING: no privileges could be granted for table "grades"データの不一致。 重要なオブジェクト(テーブル、インデックス、外部キー)が全部復元されてるかチェックしよう。
grepでサクッとチェック
ログファイルがめっちゃ長い時(「戦争と平和」並みに長いこともあるよね)、grepを使ってキーワードだけ探すのが便利:
grep -i "error" restore_log.txt
grep -i "warning" restore_log.txt
ログからエラーを読み解く
実際のログから例を見てみよう:
ERROR: constraint "fk_student_course" for relation "enrollments" does not exist
DETAIL: Key (course_id)=(2) is not present in table "courses".
このエラーは何を意味してる? これは、PostgreSQLがenrollmentsテーブルに行を復元しようとしてるけど、対応するcourse_idがcoursesテーブルに存在しないってこと。
どうやって直す? たぶんcoursesテーブルのデータが壊れてるか、復元されてない。足りない行を手動で追加するか、もう一度復元し直す必要があるよ。
整合性チェックにチェックサムを使う
バックアップファイルが復元前後で壊れてないか確かめたいなら、チェックサムを使うのがオススメ。
チェックサムっていうのは、ファイルの内容を表す小さな数字のこと。ファイルが1ビットでも変わると、チェックサムも変わる。これでファイルが壊れてないか分かるんだ。
チェックサムを作るにはmd5sumコマンドが便利。例えば:
md5sum backup_file.dump
結果はこんな感じになる:
4c9b5f5d31ae2b53e9e3d56dfedc3fe4 backup_file.dump
チェックサムの比較
もし事前にファイルのチェックサムを記録しておいたら、今のと比べてみよう:
md5sum -c checksum.md5
checksum.md5ファイルには、チェックサムとファイル名が書いてあるはず:
4c9b5f5d31ae2b53e9e3d56dfedc3fe4 backup_file.dump
チェックサムが一致したらOKって出るし、違ったらファイルが壊れてるってこと。
データベースレベルでのデータチェック
チェックサムやログだけじゃなくて、実際にデータ自体が大丈夫かも確認しよう。よくやるチェックはこんな感じ:
- 行数の比較
テーブルの行数を、復元前と後で比べてみよう。例えば:
-- studentsテーブルの行数をカウント
SELECT COUNT(*) FROM students;
行数が違ったら、復元が完全じゃなかったってこと。
- キーの整合性チェック
テーブル間のリレーションを確認して、外部キーがちゃんと機能してるか見てみよう:
-- コースに登録されてる学生をチェック
SELECT *
FROM enrollments e
LEFT JOIN courses c
ON e.course_id = c.course_id
WHERE c.course_id IS NULL;
このクエリで結果が返ってきたら、enrollmentsテーブルに存在しないコースIDが入ってる行があるってこと。
- 元データとの比較
もしデータのコピー(例えば別DBのダンプ)があるなら、SELECTで比較してみよう:
-- coursesテーブルのデータをチェック
SELECT * FROM courses WHERE course_id NOT IN (
SELECT course_id FROM courses_backup
);
実際の復元ケース
実際の話:ある日、DBAのBobがサーバ障害の後でバックアップからデータを復元しようとした。コマンドはこんな感じ:
pg_restore -U admin -d my_database my_backup.dump
でも、ログを見たら復元がエラーで止まってた:
ERROR: could not create file "base/16385/pg_internal.init": No space left on device
これはディスクの空き容量が足りなかったってこと。ディスクを空けてもう一度復元したら、今度は全部のテーブルが復元されてないことに気づいた。でも、事前にチェックサムを作っておいたのと、WALアーカイブを設定してたおかげで、Bobは無事にDBを完全復元できたんだ。
整合性チェックのまとめ
復元後のデータ整合性チェックの締めとして、次のことをやろう:
- ログを見てエラーや警告がないか確認。
- チェックサムでファイル破損がないかチェック。
- DBのデータを行数やリレーションの整合性で比較。
- 何か問題があったら、エラーを調べて復元プロセスをやり直そう。
これで、しっかりチェックして「データがちゃんと復元できた!」って自信を持てるはず。DB管理で一番大事なのは、やっぱりバックアップへの信頼だよね!
GO TO FULL VERSION