透過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參數手動指定設定擋路徑。若沒有指定路徑,會依下列路徑搜尋:

  1. 目前資料夾
  2. /etc/repmgr.conf
  3. 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)

results matching ""

    No results matching ""