postgresql warm standby
异步流复制
要求
- 至少两台机器,一台master, 其余的全是maid
- 所有机器的
$PGDATA
都必须相同,(在maid上从master拷贝即可)
这里使用一个mater (192.168.1.1) 和一个 maid (192.168.1.2) 来举例
master 设置
第一步
初始化 PGDATA
$ ls
master/
$ pg_ctl -D master initdb
第二步
修改postgresql.conf
- 设置
wal_level = replica
- 设置
max_wal_sender
为maid的数量,(例如有3个maid就设置为3,设置多一点也没关系)
- 如果系统支持tcp keepalive(Linux都支持)那么设置这几个选项(尽量设置60秒以内,减少数据丢失)
tcp_keepalives_idle
,tcp_keepalives_interval
,tcp_keepalives_count
帮助master及时发现连接断掉
第三步
启动数据库
$ ls
master/
$ pg_ctl -D master start
登录数据库创建复制用的用户
$ psql
postgres# CREATE ROLE maid REPLICATION LOGIN ENCRYPTED PASSWORD 'maid';
为maid
用户创建复制slot
postgres# SELECT * FROM pg_create_physical_replication_slot('maid_slot');
创建复制slot的原因是因为master会回收WAL(write ahead log)分段,但这时maid可能还没有接收到这个数据。
其实解决这个问题有两个方法:
- 一种是把wal_keep_segments
设置得足够大,这样可以保证分段不会太早被回收
- 另一种是设置replication slot,这种方式数据库会自动的发现WAL是否应该被回收,(我们这里用这种)
第四步
修改 pg_hba.conf
追加如下行,让maid可以通过刚创建的maid
用户连接到master
host replication maid 192.168.1.2/32 md5
其中maid
为 master 中创建的用户,192.168.1.2
为maid机器的ip,md5
是验证方式
第五步
重启master
$ ls
master/
$ pg_ctl -D master restart
maid 设置
第一步
复制master的 PGDATA 目录到本机,如果有postmaster.pid,那么删掉它。 如:
# master (192.168.1.1)
$ tar cfJ master.txz master
$ scp master.txz root@192.168.1.2/srv
# maid (192.168.1.2)
$ cd /srv
$ tar xf master.txz
$ mv master maid
$ cd maid
$ rm -f postmaster.pid
第二步
创建 maid/recovery.conf
填充以下类容
standby_mode = 'on'
# master中的maid用户
primary_conninfo = 'host=192.168.1.1 user=maid password=maid port=5432'
# 在master数据库中创建的 replication slot
primary_slot_name = 'maid_slot'
# 设置为 latest 将恢复到备份中找到的最新时间轴
recovery_target_timeline = 'latest'
# 如果master挂了,需要切换maid到master 创建这文件即可自动切换
trigger_file = '/tmp/pg_trigger'
第三步
启动maid
$ pg_ctl -D maid start
同步流复制
同样要求master和maid的PGDATA一致,这里以同一台机器为例。 master 监听 5432 端口, maid 监听 5433 端口
master
配置与异步流复制相同,另外需要设置 synchronous_standby_names = '*'
以及 synchronous_commit = on
maid
由于在同一台机器上,所以需要修改监听端口,这里改为 5433,其余配置和异步流复制完全一致。
如果多个有maid备份且synchronous_standby_names
有优先级考虑的话,可以在recovery.conf
中给每个maid指定一个应用名,如:
primary_conninfo = 'application_name=maid_1 host=192.168.1.1 user=maid password=maid port=5432'
这时 synchronous_standby_name
可以指定规则,详见这里
结果举例:
同步:
postgres=# select * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid | 11552
usesysid | 16384
usename | maid
application_name | maid_1
client_addr | 127.0.0.1
client_hostname |
client_port | 40082
backend_start | 2020-03-06 13:27:59.558948+08
backend_xmin |
state | streaming
sent_lsn | 0/16CE440
write_lsn | 0/16CE440
flush_lsn | 0/16CE440
replay_lsn | 0/16CE440
write_lag |
flush_lag |
replay_lag |
sync_priority | 1
sync_state | sync
postgres=#
异步(注释掉以上master中的更改):
postgres=# select * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid | 7271
usesysid | 16384
usename | maid
application_name | maid_1
client_addr | 127.0.0.1
client_hostname |
client_port | 47306
backend_start | 2020-03-06 16:55:07.339901+08
backend_xmin |
state | streaming
sent_lsn | 0/16CD4F0
write_lsn | 0/16CD4F0
flush_lsn | 0/16CD4F0
replay_lsn | 0/16CD4F0
write_lag |
flush_lag |
replay_lag |
sync_priority | 0
sync_state | async
异步和同步的区别
同步需要在master配置中开启synchronous_commit
及设置 synchronous_standby_names
。
流复制默认是异步的,好处是可用性高,坏处是容易丢失更多数据。
同步的好处是master会确认一个事务是否已经同步到了一个或多个standby(由 synchronous_standby_names 配置),坏处是可用性低。
参考
https://www.postgresql.org/docs/10/warm-standby.html
注意
Windows 不支持 tcp_keepalives_count 选项