PostgreSQL: PostgreSQL 同步流复制和异步流复制的控制参数
问题背景:
问:为什么我设置的同步流复制,主库提交之后备库查不到数据呢?
答:估计是你设置的同步级别不够高~
问:还分同步级别?同步模式不就是保证两边数据一致的吗?怎么还会出现主库能查到数据备库查不到数据的情况呢?查询pg_stat_replication里边显示sync不就是代表数据一致吗?
答:pg同步流复制和异步流复制关键在于两个参数:
synchronous_standby_names 控制哪些standby被应用同步策略,该参数使用方法不在此赘述;
synchronous_commit控制同步策略级别。
你以为的同步可能不是你以为的同步。
即使是通过pg_stat_replication查询出sync_state列值为sync也不一定是真正的同步。
下边通过一个图片和表格来直观提现什么时候是同步,什么时候是异步,及不同等级之间的区别。
synchronous_commit参数:
同步等级 | 设定值 | 概述 | 保证范围 |
---|---|---|---|
同步 | remote_apply | 应用发起提交后,等到在备库上应用WAL(更新数据)后,它将返回COMMIT响应,并且可以在备库上进行引用。由于完全保证了数据同步,因此它适合需要备库始终保持最新数据的负载分配场景。 | 1-9 |
同步 | on(默认) | 应用发起提交后,在备库上写入WAL之后,返回COMMIT响应。该选项是性能和可靠性之间的最佳平衡。 | 1-6 |
准同步的 | remote_write | 应用发起提交后,等到WAL已传输到备库后,返回COMMIT响应。 | 1-5 |
异步 | local | 应用发起提交后,写入主库WAL之后,返回COMMIT响应。 | 1-2 |
异步 | off | 应用发起提交后,直接返回COMMIT响应,而无需等待主库WAL完成写入。 | 1 |
最后举个例子,主库设置synchronous_commit为on,备库设置recovery_min_apply_delay = ‘1d’。
这样就会出现主库pg_stat_replication查询出sync_state列值为sync,提交一条数据后备库查不到的现象。
参考:
PostgreSQL 14.1 手册 第 20 章 服务器配置 20.5. 预写式日志
表 20.1 概括了 synchronous_commit 设置的能力.
表 20.1. synchronous_commit Modes
同步提交设置 | 本地持久提交 | PG 崩溃后备用持久提交 | 操作系统崩溃后的备用持久提交 | 备用查询一致性 |
remote_apply | • | • | • | • |
on | • | • | • | |
remote_write | • | • | ||
local | • | |||
off |