災難有很多種:硬體掛掉、突然斷電、code 出 bug,或是很常見的,有個不小心的 admin 把資料庫刪掉了,想說「清一下舊的東西」。這時候備份跟熟練的還原流程就是你的「魔法棒」。
我們來拆解還原流程,一步一步來,就像組 IKEA 櫃子一樣:不要慌,照著步驟來。
步驟 1. 分析災難原因
在你衝去還原資料之前,先搞清楚到底發生什麼事。
是 application 還是資料庫出錯?
去看一下你的 application 跟 PostgreSQL 的 log(通常在/var/log/postgresql/或你系統的類似目錄)。找找有沒有 error 的線索。硬體壞掉?
如果伺服器真的壞了(像是硬碟出問題),先確定硬體沒事。如果硬碟壞了,換一顆,然後從備份還原。網路或存取問題?
如果是網路造成的災難——你的伺服器大概暫時不用還原資料。人為失誤:
老實說...是不是有人執行了DROP DATABASE?如果是,還有救,趕快從備份還原。
記得,搞清楚災難原因,未來才比較不會再踩雷。
步驟 2. 檢查備份可用性
現在要確認我們有正確的 backup。找出你用 pg_dump 或 pg_basebackup 做的最新備份。檢查一下有沒有壞掉。如果你還不會怎麼檢查,這邊快速複習一下:
- 用
ls -l看一下檔案大小。如果檔案超小,有可能有問題。 - 用
file指令檢查檔案。例如:
你應該會看到這個檔案是 SQL dump 的資訊。file backup_file.sql
如果是 tar 壓縮檔,檢查能不能解開:
tar -tf backup.tar
沒 error?太好了!可以繼續下一步。
步驟 3. 關閉 PostgreSQL
還原前一定要先把 PostgreSQL server 關掉,這樣比較安全。用這個指令(要有 server admin 權限):
sudo systemctl stop postgresql
關掉資料庫可以確保沒有其他 process 來亂。
步驟 4. 準備新的資料庫來還原
如果你的資料庫整個被刪掉或壞掉,先新建一個。指令範例:
createdb -U postgres new_database
把 new_database 換成你自己的資料庫名稱。
步驟 5. 還原備份
來看兩種主要的還原情境:
如果你用 SQL backup(
pg_dump): 還原用這個指令psql -U username -d new_database -f backup_file.sql
username— 你的 PostgreSQL 使用者。new_database— 要匯入資料的資料庫。backup_file.sql— 你的備份檔案。
- 如果你用 binary backup(
pg_basebackup或pg_dump的custom格式):
還原用這個:
注意這種備份不是純文字,是「打包」過的資料。pg_restore -U username -d new_database backup_file.dump
補充:
- 如果備份只有資料,用
--data-only。 - 只要還原 schema,加
--schema-only。
步驟 6. 啟動 PostgreSQL 並測試
還原完後,啟動 server:
sudo systemctl start postgresql
現在要測試一下。用 psql 或 pgAdmin 連進去,查幾筆資料看看:
SELECT * FROM your_table_name LIMIT 10;
如果看起來都正常,恭喜你,資料救回來了!
步驟 7. 檢查資料完整性
還原後一定要檢查資料有沒有壞掉。例如:
比對 table 筆數跟備份:
跟備份裡的記錄比一下(如果有的話)。SELECT COUNT(*) FROM your_table_name;用 checksum 檢查: 如果你之前有算過 table 的 checksum,現在可以比對看看:
md5sum backup_file.sql檢查 table 之間的關聯: 確認還原後 FOREIGN KEY 都還正常。
步驟 8. 測試你的 application
現在測試一下你的 application,看看用這個資料庫有沒有問題。跑一下主要流程。有 error 嗎?畫面都正常嗎?
實際還原錯誤案例
來看幾個實戰 case,讓你知道怎麼避開地雷:
PostgreSQL 版本不相容。
假設你 backup 是在 12 版做的,結果 server 升到 15 版。還原時就會出錯。
解法:用跟 backup 一樣的 PostgreSQL 版本,或去看官方文件的相容性說明:PostgreSQL Documentation。備份檔壞掉。
如果你的備份壞了,部分資料可能救不回來。
解法:多做幾份備份(像是多存幾個版本)。還原單一 table 出錯。
如果你只還原一個 table,但其他依賴(像 foreign key)沒還原,會出錯。
解法:table 要照順序還原,先還原 parent table。
GO TO FULL VERSION