docker搭建postgresql9.4主從同步複製集羣
參考文章:
- Docker + PostgreSQL 主從環境搭建
https://yq.aliyun.com/articles/641773
- postgresql9.5主從複製部署文檔
https://blog.51cto.com/wn2100/2238996
- PostgreSQL建立Hot Standby的Replication機制
https://note.qidong.name/2018/09/postgresql-hot-standby/
- PostgreSQL-11.3-主從流複製+手動主備切換
https://my.oschina.net/u/4206387/blog/3103570
一、環境說明
-
Docker
-
Ubuntu/CentOS
-
PostgreSQL v9.4
-
使用的docker搭建postgres9.4主從環境(一主一從環境);
我的主節點:172.19.32.62 ,對外端口5500
從節點:172.19.32.73,對外端口5501
1. 運行PostgreSQL
主庫和從庫執行docker命令,構建相應的容器。注意我的docker容器是在不同的主機節點上的。
1.1 主庫
docker run -d --name fct-pgmaster \
-p 5500:5432 \
-e POSTGRES_PASSWORD=postgres \
-v /root/fct/postgresql-cluster/pgmaster:/var/lib/postgresql/data \
-d postgres:9.4
1.2 從庫
docker run -d --name fct-pgslave1 \
-p 5501:5432 \
-e POSTGRES_PASSWORD=postgres \
-v /root/fct/postgresql-cluster/pgslave1:/var/lib/postgresql/data \
-d postgres:9.4
進入以上主、從庫對應的實際掛載目錄執行下面的操作
2. 配置master(主庫)
2.1 編輯pg_hba.conf,在最下面添加如下:
// replication_username: 複製賬號; slave_ip: 從庫所在的服務器ip
host replication replica 172.19.32.73/32 md5
其中,replication表示複製權限;
replica表示節點之間複製的賬號;
172.19.32.73/32 表示要複製的賬號是 172.19.32.73,即從節點的賬號
2.2 編輯postgresql.conf,更改如下:
listen_addresses = '*'
max_connections = 100 # (change requires restart)
wal_level = hot_standby # minimal, archive, hot_standby, or logical
# (change requires restart)
#fsync = on # turns forced synchronization on or off
synchronous_commit = local # synchronization level;
max_wal_senders = 32 # max number of walsender processes
# (change requires restart)
wal_keep_segments = 64 # in logfile segments, 16MB each; 0 disables
wal_sender_timeout = 60s # in milliseconds; 0 disables
synchronous_standby_names = '*'
hot_standby = on # "on" allows queries during recovery
注意,我配置的配置項中某些並不是必須的,每一項的含義需要自己按照提示去理解體會。
2.3 進入容器,登錄PostgreSQL,創建複製賬號並驗證:
# 1.進入容器
docker exec -it fct-pgmaster /bin/bash
# 2.連接PostgreSQL
psql -U postgres -p 5500
# 3.創建用戶
set synchronous_commit =off;
#replication_username: 對應上面設置的複製賬號; replication_username_password: 認證密碼
create role replica login replication encrypted password 'replica';
# 4.驗證用戶
\du
2.4 重啓主節點容器,使配置生效
#重啓容器
docker restart fct-pgmaster
#啓動容器之後,需要查看容器的日誌輸出中是否有錯誤
docker logs fct-pgmaster
3. 配置Slave(從庫)
3.1 編輯postgresql.conf(親測,非必須),更改如下:
hot_standby_feedback = on
3.2 新建recovery.conf,添加如下內容:(該步驟不用做,跳過,在第4步驟中可以自動生產recovery.conf文件)
standby_mode = 'on'
#replication_username: 複製賬號(同主庫); master_ip: 主庫所在的服務器ip; master_port: 主庫端口; replication_username_password: 認證密碼
primary_conninfo = 'host=172.19.32.62 port=5500 user=replica password=replica'
4. 同步主從庫數據及測試
4.1同步主從庫數據(必須)
pg_basebackup命令
進入從節點容器中,執行直接執行,清除從節點中的數據(該步驟必須的!)
rm -rf /var/lib/postgresql/data/
如果出現如下錯誤:
root@f42b3ae4014c:/# rm -rf /var/lib/postgresql/data
rm: cannot remove '/var/lib/postgresql/data': Device or resource busy
則建議,直接刪除容器外的掛盤目錄,這裏是/root/fct/postgresql-cluster/pgslave1,直接執行;
然後在容器中執行備份命令,此時會將主節點中的數據同步到當前從節點的數據目錄中;
pg_basebackup -h 172.19.32.62 -p 5500 -U replica -F p -x -P -R -D /var/lib/postgresql/data/ -l postgresbackup20190129
執行完後結果如下,會有進度條顯示執行成功!
root@29e514bcfa3c:/# pg_basebackup -h 172.19.32.62 -p 5500 -U replica -F p -x -P -R -D /var/lib/postgresql/data/ -l postgresbackup20190129
Password:
36643/36643 kB (100%), 1/1 tablespace
**注意事項1:**命令中的-U replica
執行的用戶名是replica
,這是前面創建配置的節點數據複製的用戶名角色和密碼;不是使用的前面的postgres
的賬號密碼!切記!
(執行完之後,容器自動退出;)
此時在從庫的外部容器掛載目錄下會自動常見相應的pg_hba.conf文件和recovery.conf文件。
recovery.conf文件內容如下:
standby_mode = 'on'
primary_conninfo = 'user=replica password=replica host=172.19.32.62 port=5500 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'
注意事項2:pg_basebackup命令從屬於容器的命令,需要在容器內部執行,並且指明-U replica的複製權限的用戶名;注意master節點的對外端口-p 5500也要指定正確。
4.2 先後啓動主庫、從庫服務
每次修改相應的配置時候,要想使得配置生效,需要重啓容器。
docker restart fct-pgmaster
docker restart fct-pgslave
注意:啓動容器之後,需要查看容器的日誌輸出中是否有錯誤
docker logs fct-pgmaster
docker logs fct-pgslave
4.3 連接測試
1.查看同步節點狀態是否成功
查看主從同步是否成功的命令psql -U postgres -x -c "select * from pg_stat_replication;"
操作步驟如下:
// 進入主庫容器
docker exec -it fct-pgmaster /bin/bash
// 查看複製狀態
root@e78673f448d0:/# psql -U postgres -h 172.19.32.62 -p 5500 -x -c "select * from pg_stat_replication;"
Password for user postgres:
-[ RECORD 1 ]----+------------------------------
pid | 838
usesysid | 16384
usename | replica
application_name | walreceiver
client_addr | 172.19.32.73
client_hostname |
client_port | 55582
backend_start | 2019-10-28 06:38:33.303482+00
backend_xmin |
state | streaming
sent_location | 0/3000138
write_location | 0/3000138
flush_location | 0/3000138
replay_location | 0/3000100
sync_priority | 1
sync_state | sync
root@e78673f448d0:/# psql -U postgres -h 172.19.32.62 -p 5500
Password for user postgres:
psql (9.4.21)
Type "help" for help.
postgres=# select client_addr,sync_state from pg_stat_replication;
client_addr | sync_state
--------------+------------
172.19.32.73 | sync
(1 row)
2.查看slave節點的外部掛載目錄下時候有如下文件recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=repl password=repl host=172.19.32.62 port=5510 sslmode=prefer sslcompression=0 krbsrvname=postgres target_session_attrs=any'
#或者自己配置:
standby_mode = 'on'
#replication_username: 複製賬號(同主庫); master_ip: 主庫所在的服務器ip; master_port: 主庫端口; replication_username_password: 認證密碼
primary_conninfo = 'host=172.19.32.62 port=5500 user=replica password=replica'
recovery_target_timeline = 'latest'
5.常見錯誤總結:
1.DETAIL: The primary’s identifier is , the standby’s identifier is
FATAL: database system identifier differs between the primary and standby
DETAIL: The primary's identifier is 6752676860246843428, the standby's identifier is 6752661973687021603.
這是因爲從庫沒有與主庫的數據同步,導致啓動時候報錯!
確保數據同步,是必須做的步驟 !
2.hot standby is not possible because wal_level was not set to “hot_standby” or higher on the master server
FATAL: hot standby is not possible because wal_level was not set to "hot_standby" or higher on the master server
HINT: Either set wal_level to "hot_standby" on the master, or turn off hot_standby here.
修改配置文件中相關選項, 按照配置項提示修改即可。
補充知識:
pg_basebackup -h 172.19.32.62 -p 5500 -U replica -F p -x -P -R -D /var/lib/postgresql/data/ -l postgresbackup20190129
備份過程實際上就是從主庫的data目錄裏物理拷貝數據的過程。
參數說明
-F 指定了輸出的格式,支持p(原樣輸出)或者t(tar格式輸出)。
-x 表示備份開始後,啓動另一個流複製連接從主庫接收WAL日誌。
-p 表示允許在備份的過程中實時的打印備份的進度。
-R 表示會在備份結束後自動生成recovery.conf文件,這樣就避免了手動創建。
-D 指定把備份寫到哪個目錄,注意:在做基礎備份之前從庫的數據目錄需要手動清空。
-1 表示指定一個備份的標識。