postgresql13.6流復制主從同步
安裝好PG之后,如果給線上業務使用,至少得弄個主從,否則主庫掛了,就可能導致業務長時間受影響。下面來看看怎么配置PG主從。
環境描述:
- PG版本:13.6
- 主庫IP:172.16.103.225
- 從庫IP:172.16.103.226
- 數據目錄:/postgresql/pgdata
搭建主從(流復制)步驟:
- 在主庫創建同步用戶,并授權, (最好提前做好主備切換的權限配置,提前規劃好pg_hba.conf, 以便后面主備切換)
- 在從庫(下面也稱standby)上安裝好PG軟件,安裝跟主庫一樣(保持目錄一致性),刪除掉pgdata(數據目錄)和archive(歸檔目錄)下的文件,注意這里是操作從庫的,不要干了主庫!!
- 在從庫上使用
pg_basebackup命令去搭建同步 - 啟動從庫
具體操作命令
- 主庫上創建用戶,授權
postgres=# CREATE ROLE replica login replication encrypted password 'repl_6534';
CREATE ROLE
- 配置
pg_hba.conf, 允許從庫訪問
$ vim pg_hba.conf
host replication all 172.16.103.225/32 md5
host replication all 172.16.103.226/32 md5
postgres=# select pg_reload_conf(); # 重載一下配置文件
- 從庫上執行pg_basebackup去搭建同步
$ pg_basebackup -h 172.16.103.225 -U replica -p 5432 -F p -X s -v -P -R -D /postgresql/pgdata
Password:
pg_basebackup: initiating base backup, waiting for checkpoint to complete
WARNING: skipping special file "./.s.PGSQL.5432"
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/1B000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: created temporary replication slot "pg_basebackup_28111"
WARNING: skipping special file "./.s.PGSQL.5432"pgdata/backup_label )
32338/32338 kB (100%), 1/1 tablespace
pg_basebackup: write-ahead log end point: 0/1B000100
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: syncing data to disk ...
pg_basebackup: renaming backup_manifest.tmp to backup_manifest
pg_basebackup: base backup completed
- 啟動從庫
$ pg_ctl start -l /postgresql/pg_log/pg.log
waiting for server to start.... done
server started
查看數據庫同步信息
1. 操作系統上進程
主庫上會多一個walsender的進程
$ ps -ef | grep postgres | grep send
pgsql 7854 18709 0 11:19 ? 00:00:00 postgres: walsender replica 172.16.103.226(12836) streaming 0/1C0003E0
從庫上會有一個walreceiver的進程
$ ps -ef | grep postgres
pgsql 30471 1 0 11:19 ? 00:00:00 /postgresql/pg13/bin/postgres
pgsql 30472 30471 0 11:19 ? 00:00:00 postgres: startup recovering 00000001000000000000001C
pgsql 30473 30471 0 11:19 ? 00:00:00 postgres: checkpointer
pgsql 30474 30471 0 11:19 ? 00:00:00 postgres: background writer
pgsql 30475 30471 0 11:19 ? 00:00:00 postgres: stats collector
pgsql 30476 30471 0 11:19 ? 00:00:00 postgres: walreceiver
2. 數據庫表中的信息
postgres=# SELECT pg_is_in_recovery();
主庫上返回f, 從庫上返回t。
在主庫上,查詢表pg_stat_replication 可以看到從庫同步的狀態
postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_replication;
pid | 7854
usesysid | 16436
usename | replica
application_name | walreceiver
client_addr | 172.16.103.226
client_hostname |
client_port | 12836
backend_start | 2023-12-22 11:19:53.781303+08
backend_xmin |
state | streaming
sent_lsn | 0/1C0003E0
write_lsn | 0/1C0003E0
flush_lsn | 0/1C0003E0
replay_lsn | 0/1C0003E0
write_lag |
flush_lag |
replay_lag |
sync_priority | 0
sync_state | async
reply_time | 2023-12-22 11:24:24.29878+08
從庫上可以查看 pg_stat_wal_receiver表查看同步狀態
postgres=# select * from pg_stat_wal_receiver;
pid | 30476
status | streaming
receive_start_lsn | 0/1C000000
receive_start_tli | 1
written_lsn | 0/1C0003E0
flushed_lsn | 0/1C000000
received_tli | 1
last_msg_send_time | 2023-12-22 11:32:25.206129+08
last_msg_receipt_time | 2023-12-22 11:32:25.206617+08
latest_end_lsn | 0/1C0003E0
latest_end_time | 2023-12-22 11:19:53.783906+08
slot_name |
sender_host | 172.16.103.225
sender_port | 5432
conninfo | user=replica password=******** channel_binding=disable dbname=replication host=172.16.103.225 port=5432 fallback_application_name=walreceiver sslmode=disable sslcompression=0 ssl_min_protocol_version=TLSv1.2 gssencmode=disable krbsrvname=postgres target_session_attrs=any
需要注意的是,并不是說只有主庫的pg_stat_replication有信息,從庫一定沒有,假如是一個級聯的環境的話,那從庫(它是某個從庫的主庫)也是有輸出的。
pg_stat_replication表的幾個字段的解釋如下:
sent_lsn: 發送到standby的最后一個wal位置(還未write)。write_lsn: 寫到standby操作系統上的最后一個wal位置(還未flush)。flush_lsn: 刷新到standby磁盤上的最后一個wal位置(到達disk)。replay_lsn: standby上重放的最后的事務日志位置(此時用戶可見)。
select pg_current_wal_lsn();
是當前的wal_lsn, 也就是可以說主備延遲的字節數可以用pg_current_wal_lsn() - replay_lsn 得到。
主備切換步驟
- 關閉主庫
- 從庫上執行
pg_ctl promote提升為主庫 - 應用配置重連新主庫(原備庫)【也可以提前規劃好VIP, 把VIP切換到新主庫】
- 原主庫上創建
standby.signal文件, 配置postgresql.auto.conf文件, 以同步新主庫 - 啟動原主庫,原主庫變成了新從庫
注意:異步情況下,如果主庫宕機,切換從庫的話,可能會有數據丟失。
主備切換具體操作命令
- 模擬主庫宕機,直接停掉, 主庫執行
$ pg_ctl stop -m immediate
waiting for server to shut down.... done
server stopped
此時,從庫上執行select * from pg_stat_wal_receiver; 的話,已經沒有輸出。 日志會有同步報錯信息。
- 從庫上執行
$ pg_ctl promote
waiting for server to promote.... done
server promoted
查看數據庫日志的話,可以看到以下信息
2023-12-22 11:45:44.835 CST [30472] LOG: received promote request
2023-12-22 11:45:44.835 CST [30472] LOG: redo done at 0/1C0003A8
2023-12-22 11:45:44.837 CST [30472] LOG: selected new timeline ID: 2
2023-12-22 11:45:44.883 CST [30472] LOG: archive recovery complete
2023-12-22 11:45:44.889 CST [30471] LOG: database system is ready to accept connections
原從庫上的standby.signal文件也已經沒了。
3. 原主庫上創建standby.signal文件,把它變成新主庫的從庫
$ cd /postgresql/pgdata # 這個是我DB的數據目錄,上面所說的postgresql.conf/postgresql.auto.conf/pg_hba.conf 均在該目錄下
$ touch standby.signal
- 參考原來的從庫的postgresql.auto.conf文件,配置老主庫從新從庫
$ vim postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=replica password=repl_6534 channel_binding=disable host=172.16.103.226 port=5432 sslmode=disable sslcompression=0 ssl_min_protocol_version=TLSv1.2 gssencmode=disable krbsrvname=postgres target_session_attrs=any'
- 啟動原主庫(新從庫)
$ pg_ctl start
$ psql
psql (13.6)
Type "help" for help.
postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_wal_receiver;
pid | 5776
status | streaming
receive_start_lsn | 0/1C000000
receive_start_tli | 2
written_lsn | 0/1C0026C8
flushed_lsn | 0/1C000000
received_tli | 2
last_msg_send_time | 2023-12-22 14:21:05.444004+08
last_msg_receipt_time | 2023-12-22 14:21:05.444451+08
latest_end_lsn | 0/1C0026C8
latest_end_time | 2023-12-22 14:20:35.378922+08
slot_name |
sender_host | 172.16.103.226
sender_port | 5432
conninfo | user=replica password=******** channel_binding=disable dbname=replication host=172.16.103.226 port=5432 fallback_application_name=walreceiver sslmode=disable sslcompression=0 ssl_min_protocol_version=TLSv1.2 gssencmode=disable krbsrvname=postgres target_session_attrs=any
postgres=#

浙公網安備 33010602011771號