synchronous_commit与synchronous_standby_names
单实例即只有主无备
单机器synchronous_commit=off
vi /usr/local/pgsql/pgsql_data/postgresql.conf 搜 synchronous_commit
synchronous_commit = off
单机器synchronous_commit=on|local|remote_apply|remote_write
vi /usr/local/pgsql/pgsql_data/postgresql.conf 搜 synchronous_commit
synchronous_commit=local
synchronous_commit=remote_write
synchronous_commit=on
synchronous_commit=remote_apply
主从环境
synchronous_standby_names未被设置时表示异步
vi /usr/local/pgsql/pgsql_data/postgresql.conf 搜 synchronous_commit
synchronous_commit=local|on|remote_write|remote_apply
synchronous_standby_names设置为同步
下面列的从宽松到严谨
synchronous_standby_names为同步synchronous_commit=local(异步)
表示写入本地磁盘即可,不用理会是否有备库
synchronous_standby_names为同步synchronous_commit=remote_write
remote_write 表示本地wal已落盘,备库的wal还在备库操作系统缓存中,也就是说只有一份持久化的wal,响应时间较低
如果备库操作系统异常宕机就有已传送的wal丢失风险
synchronous_standby_names为同步synchronous_commit=on
on表示本地wal已落盘,备库的wal也已落盘,有两份持久化的wal,但备库此时还没有完成重做。这个选项带来的事务响应时间较高
synchronous_standby_names为同步synchronous_commit=remote_apply
remote_apply 表示本地wal已落盘,备库wal已落盘并且已经完成重做,这个设置保证了拥有两份持久化的wal,同时备库也已经完成了重做。查询结果与主节点保持一致
这个选项带来的事务响应时间最高
wal_receiver关于推送时间点
- 是以wal record为单位的,还是以page为单位?
应该是record为单位,某个操作产生了wal日志record(每次插入都会产生一条record,而不是一个事务一个,一个事务可能产生多条record,及时最后没有提交,也会同步到备库,事务的终止也会产生一条record),会有一个LSN,通过pg_current_wal_location查看。而这个record也会同步更新到备库,而不是等待该事务commit时才去将事务产生的所有record同步 - wal日志怎么触发将一个新的record发送到备库
插入一条数据,会产生一条record,该record在wal_buffer中,等落盘到wal日志之后在(xlog.c中的XLogBackgroundFlush中会激活日志发送),再读取wal日志变化,往tcp队列中加。
落盘参数
触发wal_buffer刷盘的操作有
- commit操作
- checkpoint,会确commit的日志已经落盘
- wal_writer_delay时间到达,且产生的日志已经超过了 wal_writer_flush_after的设置量才刷盘
高级特性
场景一局部设置WAL落盘细节推送的时间点
SET LOCAL synchronous_commit TO OFF;
当有临时批量任务时可以这样设置,这样局部事务可向备库异步的方式同步,而其他重要的事务以同步的方式向备库同步。
其它参数说明
- recovery_min_apply_delay
.recovery.conf里增加该参数,延迟拷贝,目的为了能提供机会纠正数据丢失错误
场景1: synchronous_commit=on 并且 recovery_min_apply_delay = 1min
standby去查询,发现还是会需要1min后才能查到这条数据synchronous_commit 配置为on时 和 异步流复制是一致的
场景2: synchronous_commit=remote_apply 并且 recovery_min_apply_delay = 1min
我们在主库上插入一条数据,主库会hang住等待1min(等待从库完成apply操作)后,然后才能返回执行成功or失败的结果 会造成主库上面的事务的提交的阻塞
参考地址
https://blog.csdn.net/ctypyb2002/article/details/82657372