CONFIGURATION PARAMETER预写式日志 / 设置
synchronous_commit
指定数据库服务器向客户端返回“成功”指示之前,必须完成多少 WAL 处理。
Sets the current transaction's synchronization level.
枚举 会话 引入 8.3 现存至 20 devel 0 次默认值变更
- 类型
- 枚举enum
- 上下文
- 会话任何用户都可在会话内用 SET 修改
- 默认值
on- 枚举值
local, remote_write, remote_apply, on, off- 分类
- 预写式日志 / 设置
- 引入版本
- 8.3
- 状态
- 现存
版本轨迹
相对 PostgreSQL 17 无变化。
默认值变迁
已记录的默认值在 PostgreSQL 9.0–19 之间未变。带单位的取值换算成了可读形式,原始的 boot_val 与单位写在悬浮提示里。
手册说明
指定数据库服务器向客户端返回“成功”指示之前,必须完成多少 WAL 处理。有效值为 remote_apply、on(默认值)、remote_write、local 和 off。
如果 synchronous_standby_names 为空,只有 on 和 off 两种设置有意义;remote_apply、remote_write 和 local 提供的本地同步级别都与 on 相同。所有非 off 模式在本地都会等待 WAL 刷写到磁盘。在 off 模式下则无需等待,因此,向客户端报告成功后,可能还要经过一段时间,才能保证事务不会因服务器崩溃而丢失。(最大延迟为 wal_writer_delay 的三倍。)与 fsync 不同,将此参数设为 off 不会带来数据库不一致的风险:操作系统或数据库崩溃可能会使一些最近报告已提交的事务丢失,但数据库状态会与这些事务已正常中止时完全相同。因此,当性能比完全确保事务持久性更重要时,关闭 synchronous_commit 可以是一种有用的替代方案。更多讨论见第 28.4 节。
如果 synchronous_standby_names 非空,synchronous_commit 还控制事务提交是否等待备库处理其 WAL 记录。
设为 remote_apply 时,提交会等待当前同步备库回复,确认已收到并应用该事务的提交记录,使其对备库上的查询可见,并且已将其写入备库的持久存储。由于需要等待 WAL 重放,这会比之前的设置产生大得多的提交延迟。设为 on 时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其刷写到持久存储。这能保证事务不会丢失,除非主库和所有同步备库的数据库存储都损坏。设为 remote_write 时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其写入各自的文件系统。此设置能保证备库上的 PostgreSQL 实例崩溃时数据不丢失,但不能保证备库发生操作系统级别崩溃时数据不丢失,因为数据未必已写入备库的持久存储。设为 local 时,提交会等待本地刷盘,但不等待复制。使用同步复制时通常不希望采用这种设置,提供它是为了使选项完整。
此参数可以随时更改;每个事务的行为由提交时生效的设置决定。因此,让一些事务同步提交、另一些事务异步提交是可行且有用的。例如,当默认设置要求同步提交时,可以在一个包含多条语句的事务中执行 SET LOCAL synchronous_commit TO OFF,使该事务异步提交。
表 19.1 汇总了 synchronous_commit 各种设置具备的能力。
表 19.1. synchronous_commit 模式
| synchronous_commit 设置 | 本地提交持久性 | PG 崩溃后备库提交持久性 | OS 崩溃后备库提交持久性 | 备库查询一致性 |
|---|---|---|---|---|
| remote_apply | • | • | • | • |
| on | • | • | • | |
| remote_write | • | • | ||
| local | • | |||
| off |
机制详解
除 off 外的所有模式都会等待本地 WAL 刷入持久存储。off 可以在本地持久化之前返回成功;崩溃可能丢失最近已确认的事务,但恢复后的数据库仍保持事务一致性,不会产生 fsync = off 那类结构损坏风险。
当 synchronous_standby_names 选定同步备库时,remote_write 等待备库接收并写入操作系统,on 等待备库持久化刷新,remote_apply 还要等待重放并对查询可见;local 只等待本地持久化。如果没有选中同步备库,这些远程模式不会增加远程保证。
事务采用提交开始时生效的值。应用可以对单个事务使用 SET LOCAL,使关键事务和可重建事务在同一服务器上采用不同持久性策略。
调优建议
按典型负载给出的取值思路,不是放之四海皆准的配方:实际取值要看数据量、并发度与硬件。
-
OLTP在线事务处理
全局默认保持 on。仅对明确可重建的事务使用 off;只有提交后必须立即在同步备库读到结果时才使用 remote_apply,并把网络往返和备库健康纳入延迟预算。
-
OLAP分析与批处理
可重复执行的批量导入可在事务内使用 off,前提是能够接受最后一小段未刷盘数据丢失并可重跑。目录变更、交接标记和对外宣布完成的记录仍应同步提交。
-
小规格低配实例与开发机
保持 on。小型系统通常得不到足以抵消语义风险的全局降级收益,应只优化个别非关键任务。
常见问题
- 把 synchronous_commit = off 与 fsync = off 混为一谈;前者风险是近期数据丢失,不是结构损坏。
- 没有选定同步备库时仍期待 remote_write、on 或 remote_apply 提供远程等待。
- 使用 remote_write 却假设备库能抵御操作系统崩溃。
- 同步备库不可用时没有 HA 处置方案,导致提交无限等待。
- 连接池中使用会话级 SET 而未使用 SET LOCAL 或重置纪律,造成设置泄漏。
演化历史
相邻两个大版本之间的差异,新的在前。版本号链到该版的快照。
-
PostgreSQL 9.6 ← 9.5 属性变更
枚举值
local, remote_write, on, offlocal, remote_write, remote_apply, on, off -
PostgreSQL 9.2 ← 9.1 属性变更
枚举值
local, on, offlocal, remote_write, on, off -
PostgreSQL 9.1 ← 9.0 属性变更
类型
布尔枚举枚举值(无)local, on, off简述Sets immediate fsync at commit.Sets the current transaction's synchronization level. -
PostgreSQL 8.3 ← 8.2 新增此参数
PostgreSQL 8.3 起可用
逐版本快照
每个收录版本里的 7 项事实,与上一个存在的版本不同的格子带底色。版本号链到该版。
| 版本 | 默认值 | 单位 | 上下文 | 类型 | 最小值 | 最大值 | 枚举值 |
|---|---|---|---|---|---|---|---|
| 8.3 | — | — | — | 布尔 |
— | — | — |
| 8.4 | — | — | — | 布尔 |
— | — | — |
| 9.0 | on |
— |
会话 |
布尔 |
— |
— |
— |
| 9.1 | on |
— |
会话 |
枚举 |
— |
— |
local, on, off |
| 9.2 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, on, off |
| 9.3 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, on, off |
| 9.4 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, on, off |
| 9.5 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, on, off |
| 9.6 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, remote_apply, on, off |
| 10 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, remote_apply, on, off |
| 11 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, remote_apply, on, off |
| 12 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, remote_apply, on, off |
| 13 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, remote_apply, on, off |
| 14 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, remote_apply, on, off |
| 15 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, remote_apply, on, off |
| 16 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, remote_apply, on, off |
| 17 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, remote_apply, on, off |
| 18 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, remote_apply, on, off |
| 19 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, remote_apply, on, off |
| 20 | — | — | — | 枚举 |
— | — | — |
参考资料
同类参数
| 参数 | 类型 | 上下文 | 默认值 | 版本变动 | 最近变更 |
|---|---|---|---|---|---|
| 设置 15 | |||||
commit_delay |
整数 | 会话(超级用户) | 0 |
9.31 次 | |
| 设置 commit_delay 会在发起 WAL 刷盘之前添加时间延迟。 | 现存 | ||||
commit_siblings |
整数 | 会话 | 5 |
9.11 次 | |
| 执行 commit_delay 延迟前要求的并发活动事务的最小数目。 | 现存 | ||||
fsync |
布尔 | 重载生效 | on |
— | |
| 如果打开这个参数,PostgreSQL 服务器将尝试确保更新被物理地写入到磁盘,做法是发出 fsync() 系统调用或者使用多种等价的方法(见 wal_sync_method)。 | 现存 | ||||
full_page_writes |
布尔 | 重载生效 | on |
— | |
| 启用此参数时,PostgreSQL 服务器会在检查点之后首次修改每个磁盘页面时,将该页面的全部内容写入 WAL。 | 现存 | ||||
synchronous_commit |
枚举 | 会话 | on |
9.63 次 | |
| 指定数据库服务器向客户端返回“成功”指示之前,必须完成多少 WAL 处理。 | 现存 | ||||
wal_buffers |
整数 | 重启生效 | -1 8kB |
9.11 次 | |
| 用于还未写入磁盘的 WAL 数据的共享内存量。 | 现存 | ||||
wal_compression |
枚举 | 会话(超级用户) | off |
151 次 | |
| 此参数启用使用指定的压缩方法对 WAL 进行压缩。 | 现存 | ||||
wal_init_zero |
布尔 | 会话(超级用户) | on |
— | |
| 如果设置为 on(默认值),此选项会导致新的 WAL 文件被零填充。 | 现存 | ||||
wal_level |
枚举 | 重启生效 | replica |
103 次 | |
| wal_level 决定多少信息写入到 WAL 中。 | 现存 | ||||
wal_log_hints |
布尔 | 重启生效 | off |
— | |
| 当这个参数为 on 时,PostgreSQL 服务器在检查点之后首次修改页面时把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 | 现存 | ||||
wal_recycle |
布尔 | 会话(超级用户) | on |
— | |
| 如果设置为 on(默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 | 现存 | ||||
wal_skip_threshold |
整数 | 会话 | 2 MiB |
— | |
| 当 wal_level 为 minimal,且事务在创建或重写永久关系后提交时,此设置决定如何持久保存新数据。 | 现存 | ||||
wal_sync_method |
枚举 | 重载生效 | fdatasync |
8.41 次 | |
| 用于将 WAL 更新强制写入磁盘的方法。 | 现存 | ||||
wal_writer_delay |
整数 | 重载生效 | 200 ms |
— | |
| 指定 WAL 写入器刷写 WAL 的频繁程度,以时间为单位。 | 现存 | ||||
wal_writer_flush_after |
整数 | 重载生效 | 1 MiB (128 × 8kB) |
— | |
| 指定 WAL 写入器刷写 WAL 的频繁程度,按数据量衡量。 | 现存 | ||||