關於叢集節點 timeline 不一致的處理方式
本文出處:https://www.modb.pro/db/400223
在 PostgreSQL/MogDB/openGauss 資料庫日常維護過程中,如果多次對資料庫進行角色切換,可能會出現 timeline 不一致的情況,導致備庫不能正常加入到資料庫叢集,現在以 PG 為例對這些可能發生的情況進行復現,並進行整理。
timeline 介紹
為了將基於時間點恢復後生成的 WAL 記錄序列與初始資料庫歷史中產生的 WAL 記錄序列區分開來,避免原來的 wal 檔案被覆蓋,同時也為了避免管理混亂,PostgreSQL 資料庫引入了“時間線”的概念,使其可以透過備份恢復到任何之前的狀態,包括早先被放棄的時間線分支中的狀態。
當一次歸檔恢復完成,一個新的時間線被建立來標識恢復之後生成的 WAL 記錄序列。時間線 ID 號是 WAL 段檔名的一部分,因此一個新的時間線不會重寫由之前的時間線生成的 WAL 資料。
場景一
--主庫日誌
ERROR: requested starting point 0/8000000 on timeline 1 is not in this server's history
DETAIL: This server's history forked from timeline 1 at 0/6018D98.
STATEMENT: START_REPLICATION 0/8000000 TIMELINE 1
--備庫日誌
LOG: new timeline 2 forked off current database system timeline 1 before current recovery point 0/80000A0
FATAL: could not start WAL streaming: ERROR: requested starting point 0/8000000 on timeline 1 is not in this server's history
DETAIL: This server's history forked from timeline 1 at 0/6018D98.
發生場景
備庫 promote 為主庫,源主庫以備庫的方式重新加入叢集
以備份的方式恢復為新主庫,源主庫以備庫的方式加入叢集
處理方式
重建備庫,適用資料量較小的資料庫
藉助 pg_rewind 工具,推薦使用這種方式 pg_rewind 會把所有的配置檔案都覆蓋,建議提前做好備份 並在啟動前新增 recovery.conf 或 standby.signal 檔案
pg_rewind 相關報錯
pg_rewind: fatal: target server needs to use either data checksums or "wal_log_hints = on"
即使資料庫已經開啟了wal_log_hints = on,依然報這個錯,這時需要以primary的形式重啟一下資料庫。
pg_rewind: source and target cluster are on the same timeline
pg_rewind: no rewind required
主備時間線一致,無法直接使用,這時需要讓目標節點先以備庫的方式執行,然後透過promote提升為主節點,增加timeline,再次執行pg_rewind
pg_rewind: fatal: could not find common ancestor of the source and target cluster's timelines
建議直接重建備庫
場景二
--備庫啟動失敗
LOG: entering standby mode
FATAL: requested timeline 2 is not a child of this server's history
DETAIL: Latest checkpoint is at 0/8000028 on timeline 1, but in the history of the requested timeline, the server forked off from that timeline at 0/6018D98.
LOG: startup process (PID 1059) exited with exit code 1
發生場景
在場景一中啟動資料庫,會將新主庫的 00000002.history 傳輸到備庫本地
[postgres@bogon pg_wal]$ ls -l
total 49160
-rw-------. 1 postgres postgres 332 May 5 20:52 000000010000000000000004.00000028.backup
-rw-------. 1 postgres postgres 16777216 May 6 08:54 000000010000000000000008
-rw-------. 1 postgres postgres 16777216 May 6 08:49 000000010000000000000009
-rw-------. 1 postgres postgres 16777216 May 6 08:54 00000001000000000000000A
-rw-------. 1 postgres postgres 32 May 6 08:58 00000002.history
drwx------. 2 postgres postgres 88 May 6 08:58 archive_status
處理方式
將pg_wal、archive_status 和 歸檔目錄 中的 00000002.history 刪除即可
[postgres@bogon pg_wal]$ rm -f 00000002.history
[postgres@bogon pg_wal]$ cd archive_status/
[postgres@bogon archive_status]$ ls -l
total 0
-rw-------. 1 postgres postgres 0 May 5 20:52 000000010000000000000004.00000028.backup.done
-rw-------. 1 postgres postgres 0 May 6 08:58 00000002.history.done
[postgres@bogon archive_status]$ rm -rf *
[postgres@bogon archive_status]$
場景三
LOG: started streaming WAL from primary at 0/7000000 on timeline 2
FATAL: could not receive data from WAL stream: ERROR: requested starting point 0/7000000 is ahead of the WAL flush position of this server 0/601A5D8
cp: cannot stat ‘/data/pgarchive/00000003.history’: No such file or directory
cp: cannot stat ‘/data/pgarchive/000000020000000000000007’: No such file or directory
發生場景
備庫以單機(未加入叢集,以 primary 的角色)的方式啟動過,雖然時間線沒變,但是 wal 檔案已經不一致
處理方式 此時由於備庫的需要從 0/7000000 開始進行重放,已經比主庫的 0/601A5D8 提前,說明此時資料庫已經不一致。 嘗試過修改透過 pg_resetwal 修改 timeline,也嘗試過透過 pg_switch_wal()切換 wal 檔案,依然無法透過 pg_rewind 進行處理,原因是 wal 不連續,只能選擇重建
--修改timeline
postgres=# SELECT timeline_id,redo_wal_file FROM pg_control_checkpoint();
timeline_id | redo_wal_file
-------------+--------------------------
2 | 00000002000000000000000F
(1 row)
$pg_resetwal -l 000000030000000000000010 /data/pgdata14/
Write-ahead log reset
--修改時間線
postgres=# SELECT timeline_id,redo_wal_file FROM pg_control_checkpoint();
timeline_id | redo_wal_file
-------------+--------------------------
3 | 000000030000000000000012
(1 row)
--切換wal
postgres=# select pg_switch_wal();
$ pg_ctl promote -D /data/pgdata14
總結
備庫在執行過程中,以 promote 的方式提升為主,即使有資料寫入,只要 wal 完整,也可以使用 pg_rewind 回退. 在 pg_rewind 完成後啟動,注意修改引數檔案、hba 檔案、清理歸檔日誌及新增 standby.signal/recovery.conf
備庫在執行過程中,以主庫的方式重啟過,即使沒有任何操作,也沒有辦法回退,只能重建 只要中間以主庫執行過,wal 就沒有辦法連續了