CONFIGURATION PARAMETER预写式日志 / 设置
synchronous_commit
设置当前事务提交时使用的同步级别。
Sets the current transaction's synchronization level.
枚举 会话 引入 9.0(基线) 现存至 20 devel 0 次默认值变更
- 类型
- 枚举enum
- 上下文
- 会话任何用户都可在会话内用 SET 修改
- 默认值
on- 枚举值
local, remote_write, remote_apply, on, off- 分类
- 预写式日志 / 设置
- 引入版本
- 9.0(基线)
- 状态
- 现存
版本轨迹
相对 PostgreSQL 17 无变化。
默认值变迁
默认值自 PostgreSQL 9.0 起没有变过。带单位的取值换算成了可读形式,原始的 boot_val 与单位写在悬浮提示里。
手册说明
指定数据库服务器返回“success”指示给客户端之前,必须要完成多少WAL处理。 合法的值为remote_apply, on(默认值), remote_write,local, 和 off。
如果synchronous_standby_names为空,则唯一有意义的设置为on 和 off ; remote_apply,remote_write 和 local都提供与on相同的本地同步级别。 所有非off模式的本地行为都是等待WAL的本地刷新到磁盘。 在 off模式,无需等待,因此在向客户端报告成功和以后保证事务安全防止服务器崩溃之间可能会出现延迟。 当设置为off时,在向客户端报告成功和真正保证事务不会被服务器崩溃威胁之间会有延迟(最大的延迟是wal_writer_delay的三倍)。 不同于fsync,将这个参数设置为off不会产生数据库不一致性的风险:一个操作系统或数据库崩溃可能会造成一些最近据说已提交的事务丢失,但数据库状态是一致的,就像这些事务已经被干净地中止。 因此,当性能比完全确保事务的持久性更重要时,关闭synchronous_commit可以作为一个有效的代替手段。更多讨论见Section 28.4。
如果synchronous_standby_names为非空,synchronous_commit也控制是否事务提交将等待它们的 WAL 记录在备库上被处理。
当设置为 remote_apply 时,提交将等待,直到来自当前同步备库的答复显示他们已收到事务的提交记录并应用了它,以便它变得对备库上的查询可见,并写入备库上的持久存储。 这将导致比以前的设置更大的提交延迟,因为它等待 WAL 重放(replay)。 当设置为on时,提交将等待,直到来自于当前同步的备库的回复显示它们已经收到了事务的提交记录并将其刷入了磁盘。 这保证事务将不会被丢失,除非主库和所有同步备库都遭受到了数据库存储损坏的问题。 当这个参数被设置为remote_write时,提交将等待,直到来自当前的同步备库的回复指示它们已经收到了该事务的提交记录并且已经把该记录写到它们的文件系统,这种设置保证数据得以保存,在PostgreSQL的备库实例崩溃时,但是不能保证备库遭受操作系统级别崩溃时数据能被保持,因为数据不一定必须要在备库上达到持久存储。 设置local会导致提交等待本地刷写到磁盘,而不是复制。在使用同步复制时这通常是不可取的,但是为了完整性提供了这个选项。
这个参数可以随时被修改;任何一个事务的行为由其提交时生效的设置决定。因此,可以同步提交一些事务,同时异步提交其他事务。例如,当默认是相反时,实现一个单一多语句事务的异步提交,在事务中发出SET LOCAL synchronous_commit TO OFF。
Table 19.1 概括了 synchronous_commit 设置的能力.
Table 19.1. synchronous_commit Modes
| synchronous_commit setting | local durable 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 20 ← 19 沿用 19
事实沿用 19
-
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.
逐版本快照
每个收录版本里的 7 项事实,与上一个存在的版本不同的格子带底色。版本号链到该版。
| 版本 | 默认值 | 单位 | 上下文 | 类型 | 最小值 | 最大值 | 枚举值 |
|---|---|---|---|---|---|---|---|
| 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 沿用 | on |
— |
会话 |
枚举 |
— |
— |
local, remote_write, remote_apply, on, off |
参考资料
同类参数
| 参数 | 类型 | 上下文 | 默认值 | 版本变动 | 最近变更 |
|---|---|---|---|---|---|
| 设置 15 | |||||
commit_delay |
整数 | 会话(超级用户) | 0 |
9.31 次 | |
| 设置事务提交与将 WAL 刷入磁盘之间的延迟(微秒)。 | 现存 | ||||
commit_siblings |
整数 | 会话 | 5 |
9.11 次 | |
| 设置启用 commit_delay 前所需的并发活动事务最低数量。 | 现存 | ||||
fsync |
布尔 | 重载生效 | on |
— | |
| 强制将更新同步到磁盘。 | 现存 | ||||
full_page_writes |
布尔 | 重载生效 | on |
— | |
| 检查点后页面首次修改时将完整页面写入 WAL。 | 现存 | ||||
synchronous_commit |
枚举 | 会话 | on |
9.63 次 | |
| 设置当前事务提交时使用的同步级别。 | 现存 | ||||
wal_buffers |
整数 | 重启生效 | -1 8kB |
9.11 次 | |
| 设置共享内存中用于 WAL 的磁盘页缓冲区数量。 | 现存 | ||||
wal_compression |
枚举 | 会话(超级用户) | off |
151 次 | |
| 使用指定方法压缩写入 WAL 的整页映像。 | 现存 | ||||
wal_init_zero |
布尔 | 会话(超级用户) | on |
— | |
| 新 WAL 文件首次使用前先写零。 | 现存 | ||||
wal_level |
枚举 | 重启生效 | replica |
103 次 | |
| 设置写入 WAL 的信息级别。 | 现存 | ||||
wal_log_hints |
布尔 | 重启生效 | off |
— | |
| 页面在检查点后首次发生非关键修改时也将完整页面写入 WAL。 | 现存 | ||||
wal_recycle |
布尔 | 会话(超级用户) | on |
— | |
| 通过重命名复用 WAL 文件。 | 现存 | ||||
wal_skip_threshold |
整数 | 会话 | 2 MiB |
— | |
| 设置用 fsync 新文件代替写 WAL 的最小文件规模。 | 现存 | ||||
wal_sync_method |
枚举 | 重载生效 | fdatasync |
— | |
| 选择将 WAL 更新强制写入磁盘的方法。 | 现存 | ||||
wal_writer_delay |
整数 | 重载生效 | 200 ms |
— | |
| 设置 WAL writer 两次刷写之间的时间。 | 现存 | ||||
wal_writer_flush_after |
整数 | 重载生效 | 1 MiB (128 × 8kB) |
— | |
| 设置触发 WAL writer 刷盘的写出 WAL 数量。 | 现存 | ||||