pg_rewind

走向將來 pg_rewind {.center}

小次郎@飛象翻譯  origin By Giuseppe Broccolo (第二象限)

原文連接sql

PostgreSQL 9.5 之後pg_rewind 可讓舊的主, 追隨提高的備庫,並繼續跟進.數據庫

因爲在這期間,提高的備庫(此時已經成爲primary)擁有了本身的時間線(qιuqιu☄:startupxlog timeline+1)。 在switchover過程,集羣不能正常工做的場景中,這時會用到pg_rewind服務器

你經歷過"腦裂"的切換過程麼?post

若是目標是切換角色的主節點和備節點 你最終獲得兩個兩個獨立的主節點, 每個擁有一個獨立的時間線, 這時PG dba在HA的狀況下,pg_rewind 就能夠派得上用場 !翻譯

在PostgreSQL 9.5之前,那裏是這個問題只有一個解決辦法︰rest

從新追隨新的主作一次新的基礎備份(basebackup),並將他做爲一個新的備用節點加入HA集羣中去, 通常來講,這也不是一個問題, 若是你的數據庫比較大, 假設你有數百GBs 的數據,這時,這樣的操做很容易致使停機時間比較長。postgresql

在時間的數據庫還原到之前的點能夠建立能夠用不一樣的方式處理一些複雜性。 對於深刻解釋的演變和PostgreSQL的 容錯組件, 你能夠 Gulcin 關於 PostgreSQL 容錯能力的演變系列文章 其中提到了 pg_rewind 使用時間旅行特徵中的演變。code

pg_rewind 的工做原理server

pg_rewind 掃描"舊"Master 節點的 PGDATA 目錄,在切換到新的時間線的過程當中, 標記出這些時間內更改的數據塊, 而後從提高的主(原先爲從設備)複製只有這些塊。blog

而後,這用於替換所作的更改。

做爲一個"抵押品"效應,配置文件也會從提高的Master狀態中去複製 (因此DBA必需要當心處理, 可以讓這個節點可以融入到HA集羣中去) 這樣,就不須要對PGDATA作一次徹底同步。

要作到這一點,就要擁有舊主 switchover 前的最後時刻產生的全部WALs。 經過比較數據的狀態存在於 PGDATA 的塊與登陸 WALs 的變化,找出改變並標記。 一旦肯定更改的數據塊,WALs 重演,模仿時間線的 rewind("倒帶")。

此外︰

實例必須在初始化時使用 "-k"(或 --data-checksums)參數

啓用 wal_log_hints參數

在PostgreSQL 9.5之前,必要的WALs從最後一個檢查點開始,而且不能在這個時間線以後,

爲了更好地理解它是如何工做的,能夠以以下Master節點情景爲示列︰

# Set PATH variable
export PATH=/usr/pgsql-9.5/bin:${PATH}

# This is the directory where we will be working on
# Feel free to change it and the rest of the script
# will adapt itself
WORKDIR=/var/lib/pgsql/9.5

# Environment variables for PGDATA and archive directories
MASTER_PGDATA=${WORKDIR}/master
STANDBY1_PGDATA=${WORKDIR}/standby1
ARCHIVE_DIR=${WORKDIR}/archive

# Initialise the cluster
initdb --data-checksums -D ${MASTER_PGDATA}

# Basic configuration of PostgreSQL
cat >> ${MASTER_PGDATA}/postgresql.conf <<EOF
archive_command = 'cp %p ${ARCHIVE_DIR}/%f'
archive_mode = on
wal_level = hot_standby
max_wal_senders = 10
min_wal_size = '32MB'
max_wal_size = '32MB'
hot_standby = on
wal_log_hints = on
EOF

cat >> ${MASTER_PGDATA}/pg_hba.conf <<EOF
# Trust local access for replication
# BE CAREFUL WHEN DOING THIS IN PRODUCTION
local replication replication trust
EOF

# Create the archive directory
mkdir -p ${ARCHIVE_DIR}

# Start the master
pg_ctl -D ${MASTER_PGDATA} -l ${WORKDIR}/master.log start

# Create the replication user
psql -c "CREATE USER replication WITH replication"

(注: 少許的WAL保持在主),而後待機狀態︰

# Create the first standby
pg_basebackup -D ${STANDBY1_PGDATA} -R -c fast -U replication -x

cat >> ${STANDBY1_PGDATA}/postgresql.conf <<EOF
port = 5433
EOF

# Start the first standby 啓動備庫
pg_ctl -D ${STANDBY1_PGDATA} -l ${WORKDIR}/standby1.log start

讓咱們在主庫插入一些數據。能夠看到備機也是從(熱)備機狀態。

如今提高備機,脫離Master節點,使用命令以下︰

pg_ctl -D ${STANDBY1_PGDATA} promote

如今若是你更新的大師,沒有更改將可見從待機狀態。 此外,在歸檔文件 / 目錄就能夠看到文件 00000002.history, 這代表在備機提高期間,時間線發生了變化。

如今讓咱們"倒帶"主人,並使其跟進提高待機狀態︰

~$ pg_ctl -D ${MASTER_PGDATA} stop
waiting for server to shut down.... done
server stopped
~$ pg_rewind --target-pgdata=${MASTER_PGDATA} \
    --source-server="port=5433 user=postgres dbname=postgres"

注意:在這裏,對於鏈接到源服務器 — — 提高待機狀態 — — 咱們使用 postgres 用戶,由於 pg_rewind 須要超級用戶的身份檢查數據塊

若是 max_wal_size 參數不是足夠大,以保持所需的 WALs 到 pg_xlog / 備用服務器的目錄中,我已經故意作了決定以前,相似於如下的錯誤能夠獲得︰

The servers diverged at WAL position 0/3015938 on timeline 1.
could not open file "/var/lib/pgsql/9.5/master/pg_xlog/000000010000000000000002": No such file or directory

could not find previous WAL record at 0/3015938
Failure, exiting

如今,有兩種可能的方式來解決這個問題: (小次郎注:經過後面的評論,咱們發現第二個方法不可行,不可行(=@__@=)?)

手動檢查缺乏的範圍,在歸檔中,開始從一個列出的錯誤消息,而後將它們複製到 pg_xlog / 目錄的主人

在 recovery.conf 和 PGDATA 的主人,在地方中添加適當的 restore_command,因此 pg_rewind 會自動地尋找失蹤 WALs

第二個選項多是最合適的方法。例如,想一想,是否你有沃爾瑪檔案由酒保︰ 你能基地 restore_command 要使用 get 沃爾瑪功能的酒保,由加布裏埃這篇有趣的文章所述。這樣作的時候,酒保將用做沃爾瑪集線器,提供必要的沃爾瑪文件,到 pg_rewind。

一旦檢索到失蹤的範圍,你能夠再次運行 pg_rewind 命令和如下消息應確保一切正常工做︰

~$ pg_rewind --target-pgdata=${MASTER_PGDATA} \
    --source-server="port=5433 user=postgres dbname=postgres"
servers diverged at WAL position 0/3015938 on timeline 1
rewinding from last common checkpoint at 0/3000140 on timeline 1
Done!

請記住,這個操做只是不多的塊複製(這是在修復腦裂(次郎注:those changed during the split-brain),即使您的數據庫大小是數以百計的 GBs! 記住,配置文件也會被複制,在"降級"的Master節點數據目錄中的recovery.conf也已經被覆蓋了.

  • 更改該實例是在哪裏在 postgresql.conf 監聽的端口 (在咱們的示例中, 將其設置爲5432)

  • 爲了使降級的主庫能夠鏈接到提高的主庫上去,須要在主庫更改recovery.conf文件中的primary_conninfo

完成此操做後,啓動降級的Master節點,它將將開始跟進提高的備機(即新的主),而後將其待機反過來。

你但願擁有一個一個更復雜的HA集羣嗎?不用擔憂!

第2部分將深刻剖析PostgreSQL 9.5 中的pg_rewind!

評論翻譯:

lesovsky: 請注意,pg_rewind 僅適用萬一當老主人中止正確,和那裏是沒有辦法倒帶若是已經崩潰,SIGKILL'ed 或相似。

Vladimir:

在 recovery.conf 和 PGDATA 的主人,在地方中添加適當的 restore_command,因此 pg_rewind 會自動地尋找失蹤 WALs

這真的管用嗎?好像是,關於這些pg_rewind 源代碼沒有說起到這一塊呢?

嗨,Vladimir,

 是的,這的確存在誤導性: 後來通過嘗試,這我意識到它不能以這種方式工做(
 但錯誤地沒有改變了書面的部分 — — 太晚如今!傷心表情 :()。

 不管如何,Barman 的get-wal 特性是真的頗有趣(此處是廣告),
 任何狀況下,均可以從歸檔中檢索到須要的WALs,而且能夠單獨使用
 若是給pg_rewind 添加個補丁就nice 了,讓其支持從相似"restore_command"的參數中檢索歸檔

不過,謝謝指出問題。

Alexander:

若是主庫已經奔潰,還有沒有辦法rewind,SIGKILL'ed 或相似。

也不是徹底無藥可救了,還有一種解決辦法:(救死馬的方法麼?) 1) 從"pg_xlog/archive_status"中刪除文件 2) 在單用戶模式下啓動您的數據庫 (postgres -single -D -c archive_mode =-c archive_command = false)。 3) 執行檢查點 "checkpoint" 4) 按下 Ctrl + D 離開單用戶模式。

瞧,如今你有乾淨關閉,pg_rewind 應該工做 表情嘚瑟笑 :)

博主回覆:

   嗨,Alexander

   謝謝你提供的這個過程。以前沒嘗試過啊,(小次郎注:你厲害),
   這真的對於任何類型的Master節點故障管用麼?不管如何,做爲已經突出顯示到萊紹夫斯基,
   我在這裏考慮的場景是* switchover *,主庫正常的關閉,沒有考慮到 failover。
本站公眾號
   歡迎關注本站公眾號,獲取更多信息