CodeGym /課程 /SQL SELF /恢復後的資料完整性檢查

恢復後的資料完整性檢查

SQL SELF
等級 44 , 課堂 1
開放

恢復資料庫這件事其實沒那麼簡單:看起來好像都 OK,但 log 裡突然冒出錯誤,有些 table 不見了,或者資料怪怪的。這就是為什麼恢復完一定要檢查一下,確定一切真的沒問題。

有時候部分資料根本沒恢復回來——比如備份檔案壞掉了。也有可能 table 結構亂掉:foreign key 消失、index 不見,或是出現奇怪的值。就算表面上看起來正常,log 也可能暗示資料庫其實有點毛病。

完整性檢查就像修車後的安全檢查。花點時間確認一切正常,總比之後在 production 遇到大問題好。

恢復 log 的分析

你用 pg_restore 恢復資料時,PostgreSQL 一定會產生 log。log 裡有很多有用的資訊,包括警告和錯誤。這裡有個指定 log 檔案的指令範例:

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

注意 > restore_log.txt 2>&1 —— 這會把標準輸出和錯誤都導到同一個檔案。

log 裡要找什麼?

  1. 錯誤。 注意像 "ERROR" 或 "FATAL" 這種關鍵字。舉例:

    ERROR:  關聯 "students" 不存在
    
  2. 警告。 有時你會看到 "WARNING"。雖然不是致命問題,還是建議看一下——可能有潛在狀況:

    WARNING:  無法為 table "grades" 設定權限
    
  3. 資料不一致。 檢查所有重要的物件有沒有恢復:table、index、foreign key。

grep 快速檢查

如果 log 檔超長(有時長得跟《戰爭與和平》一樣),可以用 grep 搜尋關鍵字:

grep -i "error" restore_log.txt
grep -i "warning" restore_log.txt

log 錯誤解析

來看個 log 裡的真實例子:

ERROR:  關聯 "enrollments" 的 constraint "fk_student_course" 不存在
DETAIL:  Key (course_id)=(2) 不在 table "courses" 裡。

這個錯誤在說什麼? 它表示 PostgreSQL 嘗試在 enrollments table 裡恢復一筆資料,但對應的 course_idcourses table 裡根本不存在。

怎麼解決? 可能 courses table 的資料壞掉或沒恢復。你得手動補上缺的資料,或是重跑一次恢復。

用 checksum 檢查完整性

如果你想確定備份檔案在恢復前後都沒壞,可以用 checksum。

checksum 就是一個小數字,代表檔案內容。只要檔案有一點點變動,checksum 也會變。這樣就能知道檔案有沒有壞掉。

產生 checksum 可以用 md5sum 工具。指令範例:

md5sum backup_file.dump

結果會像這樣:

4c9b5f5d31ae2b53e9e3d56dfedc3fe4  backup_file.dump

比對 checksum

如果你之前有記下檔案的 checksum,可以跟現在的比對:

md5sum -c checksum.md5

checksum.md5 檔案要包含 checksum 跟檔名:

4c9b5f5d31ae2b53e9e3d56dfedc3fe4  backup_file.dump

如果 checksum 一樣,會看到 OK。不一樣就代表檔案壞了。

資料庫層級的資料檢查

checksum 跟 log 都很重要,但怎麼確定資料本身沒問題?這裡有幾個標準步驟:

  1. 比對 row 數量

比對 table 裡的 row 數量,恢復前後要一樣。例如:

-- 計算 students table 的 row 數
SELECT COUNT(*) FROM students;

如果數量不一樣,代表恢復不完整。

  1. 檢查 key 的完整性

檢查 table 之間的關聯,確保所有 foreign key 都正常:

-- 檢查有選課的學生
SELECT *
FROM enrollments e
LEFT JOIN courses c
ON e.course_id = c.course_id
WHERE c.course_id IS NULL;

如果這個查詢有結果,代表 enrollments 裡有些 row 找不到對應的課程。

  1. 跟原始資料比對

如果你有資料的備份(比如另一個 database 的 dump),可以比對查詢結果:

-- 檢查 courses table 的資料
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

但分析 log 時發現恢復失敗:

ERROR:  無法建立檔案 "base/16385/pg_internal.init": 裝置空間不足

這代表硬碟空間用完了。清出空間、重跑恢復後,他又發現有些 table 沒恢復。幸好他有事先產生 checksum,也有設定 WAL 歸檔,最後才把 database 完全救回來。

完整性檢查總結

最後,恢復後的完整性檢查請記得:

  1. 檢查 log,看有沒有錯誤或警告。
  2. checksum,確認檔案沒壞。
  3. 比對 database 的 row 數關聯完整性
  4. 如果有問題,分析錯誤訊息,重跑恢復流程。

現在你已經完全可以仔細檢查,確保資料真的恢復到你想要的狀態。畢竟,database 管理最重要的就是對備份有信心!

2
任務
SQL SELF, 等級 44, 課堂 1
上鎖
檢查還原後的資料列數量
檢查還原後的資料列數量
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION