MathJax

MathJax-2

MathJax-3

Google Code Prettify

置頂入手筆記

EnterproseDB Quickstart — 快速入門筆記

由於考慮採用 EnterpriseDB 或是直接用 PostgreSQL 的人,通常需要一些入手的資料。這邊紀錄便提供相關快速上手的簡單筆記 ~ 這篇筆記以 資料庫安裝完畢後的快速使用 為目標,基本紀錄登入使用的範例:

2016年7月29日 星期五

PostgreSQL 9.5 的 pg_rewind 工具操作筆記

設置 Streaming Replication 的用途主要是以複寫資料庫作為備份,在工作主機下線時,可以切換(promoting)到其他備份頂替工作。

但是切換後,回復 Streaming Replication 就是首要工作。有時候,這個設置就會變得有點累人:舊的工作機資料已經沒辦法直接和現在運作的資料庫銜接,需要重新從全備份開始,設置 Streaming Replication 才行。資料量大的狀況下,從全備份開始就會耗費不短的時間。
Note:由於 PostgreSQL 的交易紀錄有標記 Timeline,Promoting 之後,Timeline 便脫勾了。因此 Promoting 之後的新舊工作機資料,無法用來建立 Streaming Replication。

在 PostgreSQL 9.5 版,提供了一個叫 pg_rewind 的工具,這工具便能善用舊的工作機資料,和目前線上工作的資料庫銜接資料差異。使的再次建立 Streaming Replication 不用從 pg_basebackup 開始,減輕再次建置 Streaming Replication  的麻煩,更快恢復 Streaming Replication。

pg_rewind 利用比較新舊工作機的交易日誌 WAL,標記兩份資料庫 $PGDATA 的差異並補上,於後就可以啟動 Streaming Replication。

以下練習,將在同一台電腦上開啟兩個之間有 streaming replication 的 Postgres cluster 進行演練。演練中也加上 Physical Replication Slot,便不再去特別點出。

以下為這次練習的設置環境

DB Cluster 資料夾位置
port
WAL archived 目錄
工作的 instance db1
/home/postgres/pgsql/db1/
5432
/home/postgres/pgWALs/db1/
備份的 instance db2
/home/postgres/pgsql/db2/
5433
/home/postgres/pgWALs/db2/


1) Rewinding 相關前置設定
要使用 pg_rewind 功能,需要在設定檔中啟用交易日誌檔 WAL 相關的功能:這需要在建立 Streaming Replication 之前就設置好。
/home/postgres/pgsql/db1/postgresql.conf
port = 5432
wal_level = hot_standby
full_page_writes = on     # Rewinding 所需參數
wal_log_hints = on        # Rewinding 所需參數
archive_mode = on       # Rewinding 所需參數
archive_command = 'cp %p /home/postgres/pgWALs/db1/%f'   # Rewinding 所需參數
max_wal_senders = 3
max_replication_slots = 1
hot_standby = on          # 在 Standby Instance 上面才會載入

2) 接著便繼續完成 Streaming Replication 的設置
[postgres@pgvm ~]$ # db1 的設定
[postgres@pgvm ~]$ echo "host  replication  repuser  127.0.0.1/32  trust" >> /home/postgres/pgsql/db1/pg_hba.conf
[postgres@pgvm ~]$ pg_ctl -D ~/pgsql/db1/ restart
[postgres@pgvm ~]$ psql -p 5432 -c "CREATE USER repuser WITH REPLICATION;"
[postgres@pgvm ~]$ psql -p 5432 -c "SELECT pg_create_physical_replication_slot('myslot1');"
[postgres@pgvm ~]$ # 建立 db2
[postgres@pgvm ~]$ pg_basebackup -h 127.0.0.1 -p 5433 -D ~/pgsql/db2 -U repuser -v -P
[postgres@pgvm ~]$ vi /home/postgres/pgsql/db2/postgresql.conf
port = 5433
archive_command = 'cp %p /home/postgres/pgWALs/db2/%f'
[postgres@pgvm ~]$ vi /home/postgres/pgsql/db2/recovery.conf
standby_mode = 'on'
primary_conninfo = 'host=127.0.0.1 port=5432 user=repuser'
restore_command = 'cp /home/postgres/pgWALs/db1/%f %p'
primary_slot_name = 'myslot1'
trigger_file = '/home/postgres/pg_trigger'
[postgres@pgvm ~]$ pg_ctl -D ~/pgsql/db2/ start

以上便將 Streaming Replication 建立完畢。不熟悉的人,可以參考另一篇 Streaming Replication 的筆記。

3) 在已經建立好的 Streaming Replication 中,在備份程序上執行 promote,使的 streaming replication 結束複寫連線(切換 Timeline),並使的備份機可以接替工作機運作:
[postgres@pgvm ~]$ pg_ctl -D ~/pgsql/db2/ promote

由於現在是執行 promote,db1 其實還在運作。但一般在切換後,db1 便不再工作,而現在db1 還在執行,所以在此把 db1 關掉。
[postgres@pgvm ~]$ pg_ctl -D ~/pgsql/db1/ stop

4) 執行 pg_rewind 之前 ...
一般來說,db2 會工作一段時間之後,才會去進行回復 Streaming Replication 的設置(因為不可能資料庫異常一發生,就馬上去處理 … ),因此 db02 已經會產生一些交易了。於是在這裡我產生一些資料到 db2 裡面,模擬執行 pg_rewind 之前已經產生的交易。
[postgres@pgvm ~]$ psql -p 5433 -c "CREATE TABLE test2 AS SELECT * FROM pg_description, pg_class;"

這個指令在空的 instance 上,會產生約莫 1GB 的資料大小 ...,足以模擬前述狀況了。

5) pg_rewind 前置作業
由於 pg_rewind 需要比對新舊資料庫的 WAL 交易日誌,找出分歧點,並設置 Timeline。所以在執行 pg_rewind 之前,我們需要提供足夠的 WAL 檔案。
[postgres@pgvm ~]$ # 把 db1 切換前產生的 WAL 移回 db1/pg_xlog
[postgres@pgvm ~]$ mv ~/pgWALs/db1/* ~/pgsql/db1/pg_xlog/
[postgres@pgvm ~]$ # 把 db2 切換後產生的 WAL 「複製到」
[postgres@pgvm ~]$ # db1/pg_xlog 裡(不是 db2/pg_xlog/!)
[postgres@pgvm ~]$ cp ~/pgWALs/db2/* ~/pgsql/db1/pg_xlog/

上面複製了新舊的 WAL 備份檔到 db1 的 pg_xlog/。這是為了提供追溯比對交易分歧點之用。目前沒有方式估計究竟需要回溯多久的 WAL 備份檔,只知道越快進行 pg_rewind,所需的 WAL archives 檔越少。
另外,運作中的 DB Master (db2)的 pg_xlog/ 目錄會清理(Rotation),所以得將 db2 的 WAL archives 都塞到舊的 DB Master (db1)的 pg_xlog/ 裡面,而非複製回 db2 的 pg_xlog/ 裡。

6) 執行 pg_rewind:這個指令,要在 db1 所在的主機上執行,並指定到連線到目前工作中的 db2
[postgres@pgvm ~]$ pg_rewind -D ~/pgsql/db1/ --source-server="host=localhost port=5433 user=postgres dbname=postgres" -P

這個過程,pg_rewind 會從原先留在 db1、db2 雙邊 pg_xlog/ 裡,最新的 WAL 檔開始回溯比較,再比較到新舊 Master 的 WAL archives(剛剛已經都被我們複製到 db1/pg_xlog/ 裡面了),直至分歧點,放上標籤,並開始複製需要的「差異資料」內容。

7) 修改 db1 設定檔內容:pg_rewind 會連同設定檔一起「同步」到 db1,所以 db1 上舊的設定檔就被 db2 的蓋掉了,於是要作一些必要調整。

/home/postgres/pgsql/db1/postgresql.conf
port = 5432
archive_command = 'cp %p /home/postgres/pgWALs/db1/%f'

把 db1 上的 recovery.done 更名為 reocvery.conf 並修改內容
[postgres@pgvm ~]$ mv ~/pgsql/db1/recovery.done ~/pgsql/db1/recovery.conf
[postgres@pgvm ~]$ vi ~/pgsql/db1/recovery.conf
primary_conninfo = 'host=127.0.0.1 port=5433 user=repuser'
restore_command = 'cp /home/enterprisedb/pgWALs/db2/%f %p'

8) 啟動 db1,成為 db2 的複寫備份
[postgres@pgvm ~]$ pg_ctl -D ~/pgsql/db1/ start

這過程中,如同一般 Streaming Replication 一樣,會進行交易日誌的重演(Replay),然後進入同步的唯讀模式

9) 檢查 Streaming Replication 狀態
就像檢視一般 Streaming Replication 同步一樣,連線到 db2 上檢視 Streaming Replication
[postgres@pgvm ~]$ psql -p 5433 -c "SELECT * FROM pg_stat_replication;"

檢視切換資料庫後的狀況
  • db1 目前狀況工作程序
[postgres]$ pg_controldata -D /home/postgres/pgsql/db1/ | grep "cluster state"
Database cluster state:               in archive recovery

  • db2 instance(現在是工作機了)
[postgres]$ pg_controldata -D /home/postgres/pgsql/db2/ | grep "cluster state"
Database cluster state:               in production

以上可見, Streaming Replication 已經再次設置成功了。
以上就是 pg_rewind 的操作範例。


最後再提醒一下,
(1)要使用 pg_rewind 功能,需要在新舊 Master 資料庫上,有分別留下 WAL 交易日誌,才能正常操作。
(2)此外,pg_rewind 還不會回溯到 WAL Archives,因此資料庫脫勾時間過得久了,pg_rewind 就不夠幫忙了:需要把「足夠的」舊資料庫 WAL 交易日誌檔,「以及新資料庫的 WAL 交易日誌檔」,放進去準備要進行 Rewinding 的 pg_xlog/ (Old Master)裡面才行。至於這個「足夠」是多少... 可能得等其他專家來解謎了。或是期待 pg_rewind 可以提供追溯 WAL archive 目錄的功能了。
(3)其實這個工具,在 PostgreSQL 9.5 之前就存在了,只是還沒正式納入 PostgreSQL 工具裡面而已。

雖然目前有上述複製 WAL 檔案的小小不便,但相較於之前都得把 db1 打掉重練,有了這個 pg_rewind,看起來就好多了...


參考資料


相關:Logical Decoding 功能

沒有留言:

張貼留言