如何驗證 PostgreSQL 基礎 + WAL 備份已正確恢復
同事們試圖從 9.1 版的熱備用備份中提取 PostgreSQL 數據庫副本,但這並不可靠——我們每天都會執行它,但通常在對副本執行查詢時會出現各種錯誤。
可悲的是,我無法在網路上找到一個明確的答案,並且 PostgreSQL IRC 頻道中的一個好心人讓我直截了當 - 不支持從備用伺服器中進行這樣的備份-該版本中的盒子。
因此,為了其他可能遇到相同問題並嘗試使用Google搜尋的人的利益,我將在下面的答案中寫下我們的筆記。
答案將包含兩個部分 - 首先,恢復後在日誌中可以看到的內容,其次是一些不可接受的範例。第一部分應該是相當確定的,而第二部分基本上是隨機分類的發生在我們身上的任何事情,表明我們遇到了問題。
可接受的日誌輸出
在開始時:
2015-07-23 06:51:24 UTC LOG: database system was interrupted; last known up at 2015-07-23 02:10:42 UTC
重要的是要看到恢復的 PostgreSQL 知道它最後一次啟動的時間。我認為之所以如此,是因為這意味著它是從檢查點開始的。
xlog min recovery request … 已超過目前點
剛開始時,可能會發生其中一些:
2015-07-23 06:51:30 UTC WARNING: xlog min recovery request 1027/B0A28D98 is past current point 1027/2BE36DA8 2015-07-23 06:51:30 UTC CONTEXT: writing block 0 of relation base/117264/9551898_vm xlog redo insert: rel 1663/117264/8310261; tid 68622/40
FATAL:數據庫系統正在啟動
任何數量的這些都可能發生:
2015-07-23 06:51:24 UTC FATAL: the database system is starting up
這實際上應該是無害的,因為在我們的例子中,它們是
SELECT 1
腳本執行以檢查 PostgreSQL 是否準備就緒的自動 ping 類查詢的結果。意外的pageaddr …在日誌文件中…,段…,偏移量…
最後,是這樣的:
2015-07-23 06:52:21 UTC LOG: restored log file "0000000100001027000000B2" from archive 2015-07-23 06:52:21 UTC LOG: consistent recovery state reached at 1027/B2F8F2F8 sh: 1: cannot open ../../../wal_backup/0000000100001027000000B3: No such file 2015-07-23 06:52:21 UTC LOG: unexpected pageaddr 1027/AA000000 in log file 4135, segment 179, offset 0 2015-07-23 06:52:21 UTC LOG: redo done at 1027/B2F8F2F8 2015-07-23 06:52:21 UTC LOG: last completed transaction was at log time 2015-07-23 02:17:33.842307+00
請注意,在那之後可能會有更多的 WAL 恢復:
2015-07-23 06:52:21 UTC LOG: restored log file "0000000100001027000000B2" from archive
這僅僅意味著您提供了
recovery.conf
比嚴格必要的更多的 WAL 文件。00000002.history:沒有這樣的文件
在 WAL 展開過程的最後,有這樣的:
sh: 1: cannot open ../../../wal_backup/00000002.history: No such file 2015-07-23 06:52:21 UTC LOG: selected new timeline ID: 2 sh: 1: cannot open ../../../wal_backup/00000001.history: No such file 2015-07-23 06:52:21 UTC LOG: archive recovery complete
這顯然/希望無關緊要,因為這是恢復的數據庫(複製)開始新生命(時間線)的地方。
不可接受的日誌輸出
在開始時:
2015-07-20 12:38:31 UTC LOG: database system was interrupted while in recovery at log time 2015-07-20 01:41:22 UTC
這很關鍵——這意味著備份過程沒有在正確的時間開始——在
pg_start_backup(...)
檢查點之後——而不是數據庫正常工作並且處於某個隨機點,這意味著這種恢復更類似於恢復崩潰的數據庫。pg_toast 中缺少塊…
這表明還原不正確。作為快速修復,我們嘗試了來自http://postgresql.nabble.com/select-table-indicate-missing-chunk-number-0-for-toast-value-96635-in-pg-toast-2619-的配方td5682176.html
mydb=# vacuum analyze mytable; -- trigger the error to see the problem toast ERROR: missing chunk number 0 for toast value 13044178 in pg_toast_2619 mydb=# reindex table pg_toast.pg_toast_2619; REINDEX
這有時可以使表恢復工作狀態,但有時也不會產生這種效果。之後我們又戳了一下,以為我們發現它只是一次性的 pg_statistic :
mydb=# reindex table pg_statistic; ERROR: could not create unique index "pg_statistic_relid_att_inh_index" DETAIL: Key (starelid, staattnum, stainherit)=(884792, 34, f) is duplicated. mydb=# delete from pg_statistic; DELETE 188540 mydb=# reindex table pg_statistic; REINDEX mydb=# vacuum analyze mytable; VACUUM
右兄弟的左連結不匹配
CREATE TABLE "myschema"."mytable" ( ... ) ERROR: right sibling's left-link doesn't match: block 27 links to 21379 instead of expected 21393 in index "pg_depend_reference_index"
我們試圖通過以下方式快速繞過它:
mydb=# set zero_damaged_pages=on; SET mydb=# reindex table pg_depend; REINDEX mydb=# set zero_damaged_pages=off; SET
無法讀取文件中的塊…
2015-05-12 13:32:53 UTC ERROR: could not read block 76408 in file "pg_tblspc/4606764/PG_9.1_201105231/117264/4614269": read only 0 of 8192 bytes
這顯然是一個無賴。我們無法快速解決這個問題:
mydb=# select cl.relfilenode, nsp.nspname as schema_name, cl.relname, cl.relkind from pg_class cl join pg_namespace nsp on cl.relnamespace = nsp.oid where relfilenode = 4614269; relfilenode | schema_name | relname | relkind -------------+-------------+---------+--------- 4614269 | myschema | mytable | r (1 row) mydb=# select pg_relation_filepath('myschema.mytable'); pg_relation_filepath --------------------------------------------------- pg_tblspc/4606764/PG_9.1_201105231/117264/4614269 (1 row) % sudo ls -lah /var/lib/postgresql/9.1/main/pg_tblspc/4606764/PG_9.1_201105231/117264/4614269 -rw------- 1 postgres postgres 597M May 11 19:22 /var/lib/postgresql/9.1/main/pg_tblspc/4606764/PG_9.1_201105231/117264/4614269
這是一個很好的指標,表明太多數據正在“失去”。
重複鍵值違反唯一約束“pg_type_typname_nsp_index”
這是恢復被破壞的另一個指標:
CREATE TABLE "myschema"."mytable" ( ... ) ERROR: duplicate key value violates unique constraint "pg_type_typname_nsp_index" DETAIL: Key (typname, typnamespace)=(mytable_mycolumn_seq, 3780903) already exists.
對此的快速破解是移動序列位置:
SELECT setval('mytable_id_seq', (SELECT MAX(id) FROM mytable));