恢復資料庫這件事其實沒那麼簡單:看起來好像都 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 裡要找什麼?
錯誤。 注意像 "ERROR" 或 "FATAL" 這種關鍵字。舉例:
ERROR: 關聯 "students" 不存在警告。 有時你會看到 "WARNING"。雖然不是致命問題,還是建議看一下——可能有潛在狀況:
WARNING: 無法為 table "grades" 設定權限資料不一致。 檢查所有重要的物件有沒有恢復: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_id 在 courses 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 都很重要,但怎麼確定資料本身沒問題?這裡有幾個標準步驟:
- 比對 row 數量
比對 table 裡的 row 數量,恢復前後要一樣。例如:
-- 計算 students table 的 row 數
SELECT COUNT(*) FROM students;
如果數量不一樣,代表恢復不完整。
- 檢查 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 找不到對應的課程。
- 跟原始資料比對
如果你有資料的備份(比如另一個 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 完全救回來。
完整性檢查總結
最後,恢復後的完整性檢查請記得:
- 檢查 log,看有沒有錯誤或警告。
- 用 checksum,確認檔案沒壞。
- 比對 database 的 row 數 和 關聯完整性。
- 如果有問題,分析錯誤訊息,重跑恢復流程。
現在你已經完全可以仔細檢查,確保資料真的恢復到你想要的狀態。畢竟,database 管理最重要的就是對備份有信心!
GO TO FULL VERSION