在PG9.6版本时,只能支持基于优先级的同步备库方式。
在PG10及以后版本中,引入了 synchronous_standby_names 这种基于 Quorum的同步复制优选提交的机制。
同步复制支持一个或者更多个同步后备服务器,事务将会等待,直到所有同步后备服务器都确认收到了它们的数据为止。事务必须等待其回复的同步后备的数量由synchronous_standby_names指定。这个参数还指定一个后备服务器名称及方法(FIRST和ANY)的列表来从列出的后备中选取同步后备。
方法FIRST指定一种基于优先的同步复制并且让事务提交等待,直到它们的WAL记录被复制到基于优先级选中的所要求数量的同步后备上为止。在列表中出现较早的后备被给予较高的优先级,并且将被考虑为同步后备。其他在这个列表中位置靠后的后备服务器表示可能的同步后备。如果任何当前的同步后备由于任何原因断开连接,它将立刻被下一个最高优先级的后备所替代。
基于优先级的多同步后备的synchronous_standby_names示例1:
synchronous_standby_names = 's1, s2'
在这个例子中,s1是同步备库,s2为潜在同步备库,当s1不可用时,s2升级为同步备库
基于优先级的多同步后备的synchronous_standby_names示例2:
synchronous_standby_names = 'FIRST 2 (s1, s2, s3)'
在这个例子中,如果有四个后备服务器s1、s2、s3和s4在运行,列表前两个后备服务器s1和s2将被选中为同步后备。
主库提交事务时,必须要等s1和s2都接收并写入WAL日志文件才能返回给客户端成功。
s3是一个潜在的同步后备,当s1或s2中的任何一个失效, 它将升级为同步备库。
s4则是一个异步后备因为它的名字不在列表中。
基于Quorum数量的同步复制 示例:
synchronous_standby_names的基于规定数量的多同步后备的例子:
synchronous_standby_names = 'ANY 2 (s1, s2, s3)'
在这个例子中,如果有四台后备服务器s1、s2、s3以及s4正在运行,事务提交将会等待来自s1 s2 s3中至少任意两台后备服务器的回复。
s4是一台异步后备,因为它的名字不在该列表中。
后备服务器的同步状态可以使用pg_stat_replication视图查看。
当一台后备服务器第一次附加到主服务器时,它将处于一种还没有正确同步的状态。这被描述为追赶模式。一旦后备服务器和主服务器之间的迟滞第一次变成零,我们就来到了实时的流式状态。在后备服务器被创建之后的很长一段时间内可能都是追赶模式。如果后备服务器被关闭,则追赶周期将被增加,增加量由后备服务器被关闭的时间长度决定。只有当后备服务器到达流式状态后,它才能成为一台同步后备。这种状态可以使用pg_stat_replication视图查看。
注意:
如果在提交正在等待确认时主服务器重启,那些正在等待的事务将在主数据库恢复时被标记为完全提交。没有办法确认所有后备服务器已经收到了在主服务器崩溃时所有还未处理的 WAL 数据。某些事务可能不会在后备服务器上显示为已提交,即使它们在主服务器上显示为已提交。我们提供的保证是:在 WAL 数据已经被所有后备服务器安全地收到之前,应用将不会收到一个事务成功提交的显式确认。
实验部分:
一主两备的流复制实验(集群使用patroni搭建,它会自动构建同步复制节点):
postgres=# select pid,usename,application_name,client_addr,state,sync_state,sync_priority from pg_stat_replication ;
pid | usename | application_name | client_addr | state | sync_state | sync_priority
-------+------------+------------------+---------------+-----------+------------+---------------
58691 | replicator | pg_node3 | 192.168.2.189 | streaming | sync | 1
58712 | replicator | pg_node2 | 192.168.2.188 | streaming | potential | 1
(2 rows)
说明:
sync 表示同步库
potential 表示潜在同步库
在 patroni 构建的PG流复制集群中,我的配置是已经开启了基于优先级多备库的方式。 因此我们可以任意关闭1个standby节点,但是如果我们关闭全部的standby节点后,会造成主节点的修改阻塞。
下面是我自建的基于Quorum的同步备库演示贴图(因为我在patroni里面没找到哪里配的支持Quorum。。。暂时也懒得找了):
修改 postgresql.conf 的如下内容:
synchronous_standby_names = 'ANY 2 (pg_node2,pg_node3)'
然后重载pg的配置文件:
pg_ctl reload
然后在主库查询配置是否生效:
postgres=# show synchronous_standby_names ;
synchronous_standby_names
---------------------------
ANY 2 (pg_node2, pg_node3)
(1 row)
这时候,在主库查看到的如下:
postgres=# select pid,usename,application_name,client_addr,state,sync_state,sync_priority from pg_stat_replication ;
pid | usename | application_name | client_addr | state | sync_state | sync_priority
-------+------------+------------------+---------------+-----------+------------+---------------
65373 | replicator | pg_node3 | 192.168.2.189 | streaming | quorum | 1
65375 | replicator | pg_node2 | 192.168.2.188 | streaming | quorum | 1
(2 rows)
图上可以看出,2个standby节点的sync_state都是 quorum的,并且 sync_priority 优先级都是1 (基于Quorum的同步备库 sync_prioriy的值对备库无影响,可忽略)
接着关闭一个同步备库 pg_node2 ,这时候我们去主库插入数据,可看到被阻塞了。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。