REPMGR (Replication Manager)
設定 Repmgr 來管理 Postgres 伺服器集群的複製與故障轉移(Failover)。
主要安裝 repmgr 後,會有兩個工具: repmgr 及 repmgrd。
- repmgr 負責協調 postgres 的操作
- repmgrd 負責背景執行;負責監視節點複製、故障轉移等相關操作。
梳理目的
設定 Postgres 中的 repmgr ,讓資料庫有叢集節點提供服務;降低服務可靠性問題。 而 repmgr 負責只是高可用的一部分;可用池則是由其餘的工具達成
節點角色:
- Primary Node: 寫入節點
- Standby Node: 從屬節點(同步 Primary Node的資料,會記錄上游是哪一台 Primary)
- priority: 設定該數值,數值越大為優先級越高(如果故障的話,轉移的優先度)
- Witness Node: 見證節點(當進行 Primary 投票時擔任投票員之一,本身不同步 Primary 資料; 避免”腦裂”情況)
- 投票?: 當主節點(Primary) 發生異常了,開始進行 Failover 那這時候就是節點需要共識出誰是主要的主節點。
設定流程:
由於流程上會有 Primary 和 Standby 所以如果是都要處理的流程,使用
(通用流程)標註起來。
作業流程: (Base On Debian 12)
- (通用流程) 安裝 Postgres (Postgres 17) (略)
- (通用流程) 設定 pg_hba.conf
/etc/postgresql/17/main/pg_hba.conf - (通用流程) 設定 Postgres 的設定檔案
/etc/postgresql/17/main/conf.d/setting.conf - (通用流程) 設定 repmgr 設定檔
/etc/postgresql-common/repmgr.conf - (通用流程) 設定 Postgres 中的使用者(建立 repmgr 使用者與對應資料庫)
- 設定 Primary Node.
- 執行 Standby Node.
/etc/postgresql/17/main/conf.d/setting.conf
listen_addresses = '*'
shared_preload_libraries = 'repmgr'
max_wal_senders = 10 # 最大 WAL 發送者數量
max_replication_slots = 10 # 最大複製槽數量
wal_level = 'replica' # WAL 級別
wal_log_hints = on # WAL 日誌提示
archive_mode = on # 啟用歸檔模式
archive_command = '/bin/true' # 彙檔命令
hot_standby = on # 指定 PostgreSQL 備用服務器可以處理只讀查詢,即使備份處理過程仍在進行中。
/etc/postgresql/17/main/pg_hba.conf 須根據自己網路環境設定對應的配置
# (略)
# CONN_TYPE DATABASE USER ADDRESS CREDIT (scram-sha-256, md5, trust, ...etc)
host all all 192.168.0.10/32 trust
host replication all 192.168.0.10/32 trust
/etc/postgresql-common/repmgr.conf
設定這些參數原則上就是幾個參數要記得一定要修改調整檢查:
- node_id: 必須唯一不可重複
- node_name: 辨識用(可用末IP或是增加主機名來辨識)
- pg_bindir: pg binary放的位置
- conninfo: 連線資訊(放自己的連線資訊)
- data_directory: pg data存放的位置;與 pg 自己設定檔的位置一樣
- promote_command: standby 拉升為 primary 的指令
- follow_command: 其餘 standby 重新 follow 的指令
- priority: 更換 primary 的優先數值
################################################
# Event notification settings
# %n - node name
# %e - event name
# %s - event severity
# %t - event timestamp
# %d - event description
# %p - primary node name
# %R - primary node conninfo
# %S - standby node name
# %T - standby node conninfo
################################################
event_notification_command='/usr/local/bin/repmgr-event-handler.sh %n %e %s "%t" "%d"'
################################################
# Basic Information
################################################
node_id=10
node_name=vm-10
pg_bindir='/usr/lib/postgresql/17/bin'
conninfo='host=192.168.0.10 user=repmgr dbname=repmgr connect_timeout=5 port=5432' # self pg connection.
data_directory='/var/lib/postgresql/17/main/'
################################################
# Logging Management
################################################
log_level='INFO'
log_file='/var/log/postgresql/repmgr.log'
log_status_interval=10 # 多久寫一次log
# log_facility=STDERR
################################################
# failover 設定
################################################
failover='automatic'
promote_command='/usr/bin/repmgr standby promote -f /etc/postgresql-common/repmgr.conf --log-to-file'
follow_command='/usr/bin/repmgr standby follow -f /etc/postgresql-common/repmgr.conf --log-level DEBUG --upstream-node-id=%n'
################################################
# High Availability
################################################
location='default'
priority=100
monitoring_history=no # 是否將監控資料寫入 monitoring_history 表內
reconnect_interval=5 # 故障轉移前,嘗試重新連接的間隔(單位:秒)
reconnect_attempts=3 # 故障轉移前,嘗試重新連接的次數
pg_basebackup_options=''
monitor_interval_secs=2
use_replication_slots=true
connection_check_type='ping' # ping: repmgr 使用 PGPing() 測試連線
# connection: 嘗試與節點建立新的連線
# query: 通過現有連現在節點上執行 SQL 語句
################################################
# Service Management
################################################
service_start_command='sudo systemctl start postgresql'
service_stop_command='sudo systemctl stop postgresql'
service_restart_command='sudo systemctl restart postgresql'
service_reload_command='sudo systemctl reload postgresql'
################################################
# Considerations
################################################
# 非同步查詢的超時時間設定(async_query_timeout)
# -> 查詢可以運行多久才被判定為超時
async_query_timeout='20'
# 主服務可見性共識 (primary_visibility_consensus):
# 當從屬節點連接不到主節點時,詢問其他服務最後一次看到主服務的時間。當 Witness 可以連接到主服務則代表主服務還存活,並且可以正常讀寫;此時不觸發新的選舉。 https://www.repmgr.org/docs/current/repmgrd-primary-visibility-consensus.html
primary_visibility_consensus=true
# 節點升級的可容忍時間 (promote_check_timeout)
promote_check_timeout=30
# 主節點(primary node)或監控系統處於「降級模式」時的監控超時時間設定。
degraded_monitoring_timeout=5 # Service control commands
由於 Primary, Standby 的 repmgr.conf 相似;主要就是上述的設定項目要記得檢查修改即可。
設定 Postgres 中的使用者(建立 repmgr 使用者與對應資料庫)
CREATE USER repmgr WITH SUPERUSER REPLICATION PASSWORD 'repmgr' ;
CREATE DATABASE repmgr OWNER repmgr;
設定 Primary Node (repmgr primary register)
設定完上述的設定後,透過 repmgr primary register 註冊當下節點為主節點。
sudo -u postgres repmgr primary register
設定 Standby Node (repmgr standby register)
--dry-run測試執行語句-F強制執行備份指令
sudo -u postgres repmgr -h 192.168.0.10 -p5432 -U repmgr -d repmgr standby clone --dry-run
sudo -u postgres repmgr -h 192.168.0.10 -p5432 -U repmgr -d repmgr standby clone -F
sudo -u postgres repmgr standby register
確認集群狀態:
sudo -u postgres repmgr cluster show
故障轉移機制
當 Primary 失效時,repmgrd 會:
- 等待
reconnect_interval * reconnect_attempts秒 - 根據
priority值選舉新Primary - 觸發
promote_command - 其他節點自動執行
follow_command
常見問題:
- repmgr 備份失敗? 檢查 pg_hba.conf 是否允許存取。(replication 的設定也要檢查)
- 節點切換異常? 檢查 postgres 是否有權限重啟指令。
- log 怎麼沒有資料? 確認資料夾是否存在、權限是否正常指派
後言:
對於設定 repmgr 這個工具來說,我遇到了很多奇奇怪怪的問題,並且也不太確定一堆新名詞的意思; 只能邊設定邊記錄起來,在日後再繼續填坑。
- WAL(Write-Ahead Logging)機制類似MySQL的redo log
- archive_mode 啟用歸檔模式
- archive_command 彙檔命令