CodeGym /コース /SQL SELF /復元後のデータ整合性チェック

復元後のデータ整合性チェック

SQL SELF
レベル 44 , レッスン 1
使用可能

データベースの復元って、実はそんなに簡単じゃないんだよね。一見うまくいったように見えても、後からログにエラーが出てきたり、テーブルが消えてたり、データが怪しく見えたりすることもある。だからこそ、復元した後は必ず「本当に大丈夫か?」ってチェックするのが超大事なんだ。

たまに、データの一部が復元されてないこともある。例えば、バックアップファイルが壊れてた場合とか。テーブルの構造が崩れることもあるし、外部キーが消えたり、インデックスがなくなったり、変な値が入ってたりもする。ぱっと見は普通でも、ログを見たら「実はこのDB、ちょっとヤバいかも」ってヒントが隠れてることも。

整合性チェックは、修理後の車検みたいなもん。ちょっと時間かけてでも「ちゃんと動く」って確認した方が、後で本番環境で突然トラブルに遭うより絶対いいよ。

復元ログの分析

pg_restoreでデータを復元すると、PostgreSQLは必ずログを出してくれる。このログには、復元プロセスのいろんな情報が詰まってて、警告やエラーも全部ここに出る。例えば、ログファイルを指定してコマンドを実行する場合はこんな感じ:

pg_restore -U username -d database_name backup_file.dump > restore_log.txt 2>&1

> restore_log.txt 2>&1に注目してね。これは標準出力もエラーも全部一つのファイルにまとめてくれる。

ログで何を探せばいい?

  1. エラー。 "ERROR"や"FATAL"みたいなキーワードに注目しよう。例:

    ERROR:  relation "students" does not exist
    
  2. 警告。 たまに"WARNING"って警告が出ることもある。致命的じゃないけど、ちゃんと読んでおいた方がいい。何か問題のサインかも:

    WARNING:  no privileges could be granted for table "grades"
    
  3. データの不一致。 重要なオブジェクト(テーブル、インデックス、外部キー)が全部復元されてるかチェックしよう。

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_idcoursesテーブルに存在しないってこと。

どうやって直す? たぶんcoursesテーブルのデータが壊れてるか、復元されてない。足りない行を手動で追加するか、もう一度復元し直す必要があるよ。

整合性チェックにチェックサムを使う

バックアップファイルが復元前後で壊れてないか確かめたいなら、チェックサムを使うのがオススメ。

チェックサムっていうのは、ファイルの内容を表す小さな数字のこと。ファイルが1ビットでも変わると、チェックサムも変わる。これでファイルが壊れてないか分かるんだ。

チェックサムを作るにはmd5sumコマンドが便利。例えば:

md5sum backup_file.dump

結果はこんな感じになる:

4c9b5f5d31ae2b53e9e3d56dfedc3fe4  backup_file.dump

チェックサムの比較

もし事前にファイルのチェックサムを記録しておいたら、今のと比べてみよう:

md5sum -c checksum.md5

checksum.md5ファイルには、チェックサムとファイル名が書いてあるはず:

4c9b5f5d31ae2b53e9e3d56dfedc3fe4  backup_file.dump

チェックサムが一致したらOKって出るし、違ったらファイルが壊れてるってこと。

データベースレベルでのデータチェック

チェックサムやログだけじゃなくて、実際にデータ自体が大丈夫かも確認しよう。よくやるチェックはこんな感じ:

  1. 行数の比較

テーブルの行数を、復元前と後で比べてみよう。例えば:

-- studentsテーブルの行数をカウント
SELECT COUNT(*) FROM students;

行数が違ったら、復元が完全じゃなかったってこと。

  1. キーの整合性チェック

テーブル間のリレーションを確認して、外部キーがちゃんと機能してるか見てみよう:

-- コースに登録されてる学生をチェック
SELECT *
FROM enrollments e
LEFT JOIN courses c
ON e.course_id = c.course_id
WHERE c.course_id IS NULL;

このクエリで結果が返ってきたら、enrollmentsテーブルに存在しないコースIDが入ってる行があるってこと。

  1. 元データとの比較

もしデータのコピー(例えば別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を完全復元できたんだ。

整合性チェックのまとめ

復元後のデータ整合性チェックの締めとして、次のことをやろう:

  1. ログを見てエラーや警告がないか確認。
  2. チェックサムでファイル破損がないかチェック。
  3. DBのデータを行数リレーションの整合性で比較。
  4. 何か問題があったら、エラーを調べて復元プロセスをやり直そう。

これで、しっかりチェックして「データがちゃんと復元できた!」って自信を持てるはず。DB管理で一番大事なのは、やっぱりバックアップへの信頼だよね!

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION