透過repmgr建立replication
本章節將透過repmgr,建立兩節點之間的基礎Streaming Replication,如下圖所示:
[on master、slave]
安裝相關套件
~$ sudo add-apt-repository "deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main"
~$ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
~$ sudo apt-get update && sudo apt-get install postgresql-10 postgresql-10-repmgr postgresql-server-dev-10
將叢集中節點加入/etc/hosts
~$ sudo vim /etc/hosts
node1 node1-IP
node2 node2-IP
由於master、slave角色有彼此互相切換的可能,儘量不要使用master、slave之類的命名原則,建議採node1、node2之方式。
編輯postgresql 設定檔
master, slave兩邊需要一致,請在postgresql.conf中找到相關設定。
~$ sudo vim /etc/postgresql/10/main/postgresql.conf
max_connections = 1024
listen_addresses = '*'
max_wal_senders = 10
wal_level = hot_standby
#只會生效在standyby host, 但master, slave角色會交換,建議兩邊保留一致設定
hot_standby = on
archive_mode = on
#預設是/bin/true,這是雞肋,一定要改掉!
archive_command = 'test ! -f /opt/pgbackup/archive/%f && cp %p /opt/pgbackup/archive/%f'
wal_log_hints = on
建立WAL archive 資料夾
~$ sudo mkdir -p /opt/pgbackup/archive; sudo chown -R postgres:postgres /opt/pgbackup;
將所有節點加入ph_hba.conf
注意!master, slave兩邊需要一致。
~$ sudo vim /etc/postgresql/10/main/pg_hba.conf
local replication repmgr trust
host replication repmgr 127.0.0.1/32 trust
host replication repmgr 192.168.252.50/32 trust
host replication repmgr 192.168.252.51/32 trust
local repmgr repmgr trust
host repmgr repmgr 127.0.0.1/32 trust
host repmgr repmgr 192.168.252.50/32 trust
host repmgr repmgr 192.168.252.51/32 trust
加入pg_ctl搜尋路徑
因Debian/Ubuntu環境已使用pg__ctlcluster取代pg_ctl功能,但repmgr主要是過pg_ctl來控制服務,這會造成repmgr在promote、switchover等功能的失效。不過還好Debian/Ubuntu package仍有帶pg_ctl,我們只需要把它加進搜尋路徑當中即可。
~$ sudo vim /etc/profile.d/repmgr-utils.sh
#加入
PATH=$PATH:/usr/lib/postgresql/10/bin
#登出再登入,確定pg_ctl有在搜尋路徑中並被執行
~$ pg_catl
pg_ctl: no operation specified
Try "pg_ctl --help" for more information.
~$ sudo su postgres
postgres@nodex ~$ vi .bashrc
#加入
PATH=$PATH:/usr/lib/postgresql/10/bin
#登出再登入,確定postgres身份能執行pg_ctl
postgres@nodex ~$ pg_catl
pg_ctl: no operation specified
Try "pg_ctl --help" for more information.
[on master]
設定SSH免密碼登入
user@master ~$ sudo su postgres
postgres@master ~$ mkdir ~/.ssh && cd ~/.ssh
postgres@master ~$ ssh-keygen -f ./id_rsa -t rsa -N ''&& mv id_rsa.pub authorized_keys
在slave上,先手動將master的authorized_keys內容貼上
user@slave ~$ sudo su postgres
postgres@slave ~$ mkdir ~/.ssh && cd ~/.ssh
postgres@slave ~$ vim authorized_keys
確定master上的postgres使用者可ssh連線到slave後,將~/.ssh內容全部複製到slave
postgres@master ~$ scp .ssh/* postgres@slave-ip:~/.ssh/
建立repmgr專用postgres帳號
~$ sudo su postgres
postgres@master ~$ createuser -s repmgr
postgres@master ~$ createdb repmgr -O repmgr
建立repmgr.conf
視不同平台編譯參數,repmgr預設會吃到的設定檔路徑也不太一樣,可透過-f/--config-file
參數手動指定設定擋路徑。若沒有指定路徑,會依下列路徑搜尋:
- 目前資料夾
- /etc/repmgr.conf
pg_config --sysconfdir 回報之路徑(pg_config需要安裝postgresql-server-dev-10)
為管理方便,統一使用/etc/repmgr.conf這個路徑
~$ sudo vim /etc/repmgr.conf
cluster = 'dbc'
node = 1
node_name = 'node1'
conninfo = 'host=node1-IP user=repmgr dbname=repmgr'
pg_bindir='/usr/lib/postgresql/10/bin'
#重要!為避免matser, slave因斷線造成replication異常,請務必開啟replication_slots 功能
use_replication_slots = 1
# log level, DEBUG, INFO, NOTICE, WARNING, ERR, ALERT, CRIT, EMERG
loglevel=NOTICE
# log 檔輸出路徑
logfile='/var/log/repmgr/repmgr.log'
建立log檔存放資料夾並設定owner為postgres
~$ sudo mkdir /var/log/repmgr
~$ sudo chown postgres: /var/log/repmgr
node1-IP --> 可以是IP或是domain name,如果在/etc/hosts有加入hostname,也可填hostname。
註冊master到repmgr
postgres@master ~$ repmgr master register
NOTICE: master node correctly registered for cluster dbc with id 1 (conninfo: host=node1-IP user=repmgr dbname=repmgr)
觀察是否成功註冊到repmgr schema中
postgres@master ~$ psql
postgres=# \connect repmgr
#將repmgr_dbc schema加入搜尋路徑中
repmgr=# ALTER USER repmgr SET search_path TO repmgr_dbc, "repmgr", public;
repmgr=# SELECT * FROM repmgr_dbc.repl_nodes;
P.S. schema名稱帶有大寫字母,需要用""把schema括住,否則會被跳脫掉。e.g. SELECT * FROM "repmgr_DBC".repl_nodes;
[on slave]
建立slave的repmgr.conf
~$ sudo vim /etc/repmgr.conf
cluster = 'dbc'
node = 2
node_name = 'node2'
conninfo = 'host=node2-IP user=repmgr dbname=repmgr'
use_replication_slots = 1
loglevel=NOTICE
logfile='/var/log/repmgr/repmgr.log'
從master clone資料到standby,開始streaming replication
停止postgresql服務,並把data全部刪掉
~$ sudo service postgresql stop
~$ sudo su postgres
postgres@slave ~$ rm -rf /var/lib/postgresql/10/main
從master clone data過來
$ repmgr -h node1-IP -U repmgr -d repmgr -D /var/lib/postgresql/10/main standby clone
NOTICE: destination directory '/path/to/node2/data/' provided
NOTICE: starting backup...
HINT: this may take some time; consider using the -c/--fast-checkpoint option
NOTICE: pg_stop_backup complete, all required WAL segments have been archived
NOTICE: standby clone (using pg_basebackup) complete
NOTICE: you can now start your PostgreSQL server
HINT: for example : pg_ctl -D /path/to/node2/data/ start
確定資料clone完成後,啟動postgresql服務
~$ sudo service postgresql start
[on master]
連到master並確認replication狀態
repmgr=# SELECT * FROM pg_stat_replication;
[on slave]
在slave上,向repmgr註冊standby host
postgres@slave ~$ repmgr standby register
NOTICE: standby node correctly registered for cluster dbc with id 2 (conninfo: host=192.168.252.51 user=repmgr dbname=repmgr)
觀察註冊狀態,看到以下畫面,表示replication已經在repmgr的掌控之中了。
repmgr=# SELECT * FROM repmgr_dbc.repl_nodes ORDER BY id;
id | type | upstream_node_id | cluster | name | conninfo | slot_name | priority | active
----+---------+------------------+---------+-------+-----------------------------------------------+---------------+----------+--------
1 | master | | dbc | node1 | host=192.168.252.50 user=repmgr dbname=repmgr | repmgr_slot_1 | 100 | t
2 | standby | 1 | dbc | node2 | host=192.168.252.51 user=repmgr dbname=repmgr | repmgr_slot_2 | 100 | t
(2 rows)