PostgreSQL码农集散地

组提交到底能不能提升性能?

本期播客

PostgreSQL 19 preview - 可观测性补丁: 组提交到底能不能优化性能?

正常情况下, 数据库为了确保用户对数据库修改操作的持久化, 在事务结束后需要先确保WAL日志buffer已经刷到持久化存储设备后, 才会返回给用户已提交成功.

那么问题来了, 每个事务结束都要发起持久化操作, 会显著增加存放WAL日志的存储设备的IO, 把IO打爆!

为了解决这个问题, PG数据库设计了分组提交的功能, 当有多个事务(有参数可配置)同时处于提交状态时, 不需要每个事务都发起持久化IO请求, 而是聚集到一起, 减少物理IO.

这个手段通常适合于活跃连接较多的高并发小事务工作负载.

但是到底应该设置多少个同时等待的事务, 等待多久呢? 设置不佳会不会影响性能呢?

现在PostgreSQL 19有可观测补丁了!

可观测性补丁: 组提交到底能不能优化性能?

https://github.com/postgres/postgres/commit/3cb5808bd11c5a7ef697922335f7642f643a4e7f

Add wait event for the group commit delay before WAL flush  
Author: Rafia Sabih <[email protected]>  
Reviewed-by: Sami Imseih <[email protected]>  
Discussion: https://www.postgresql.org/message-id/CA%2BFpmFf-hWXtrC0Q3Cr_Xo78zuP_M_VC5xgWPOYOkwqOD0T8eg@mail.gmail.com  

这个补丁的目的是:在 PostgreSQL 的组提交(group commit)延迟等待期间添加一个等待事件(wait event)。

补丁解读

1. 提交信息总结 (Commit Message Summary):

  • 标题: Add wait event for the group commit delay before WAL flush.
  • 作者: Rafia Sabih
  • 目的: 在 WAL 刷新(WAL flush)之前的组提交延迟等待期间,报告一个等待事件。

2. 核心改动 (Key Changes):

这个补丁涉及两个文件,都与 PostgreSQL 的 WAL(Write-Ahead Logging)处理和活动监控有关。

文件 A: src/backend/access/transam/xlog.c

这是 WAL 刷新的核心逻辑文件。改动发生在 XLogFlush 函数中处理组提交延迟(CommitDelay)的部分。

@@ -2884,7 +2884,9 @@ XLogFlush(XLogRecPtr record)  
if (CommitDelay > 0 && enableFsync &&  
   MinimumActiveBackends(CommitSiblings))  
  {  
+  pgstat_report_wait_start(WAIT_EVENT_COMMIT_DELAY);  
   pg_usleep(CommitDelay);  
+  pgstat_report_wait_end();  

/*  
    * Re-check how far we can now flush the WAL. It's generally not  
  • 新增了 pgstat_report_wait_start(WAIT_EVENT_COMMIT_DELAY): 在进程开始执行 pg_usleep(CommitDelay)(即等待组提交延迟)之前,报告开始等待 COMMIT_DELAY 事件。
  • 新增了 pgstat_report_wait_end(): 在延迟等待结束后,报告等待事件结束。

意义: 这使得 DBA 或性能分析工具可以通过 pg_stat_activity 视图观察到事务进程是否正在等待组提交延迟。如果一个进程处于这个等待事件中,就说明它正在等待其他事务聚集起来一起执行 WAL 刷新,这是 commit_delay 设置的预期行为。

文件 B: src/backend/utils/activity/wait_event_names.txt

这个文件定义了所有可以报告的等待事件的名称。

@@ -175,6 +175,7 @@ Section: ClassName - WaitEventTimeout  

 BASE_BACKUP_THROTTLE "Waiting during base backup when throttling activity."
 CHECKPOINT_WRITE_DELAY "Waiting between writes while performing a checkpoint."
+COMMIT_DELAY "Waiting for commit delay before WAL flush."
 PG_SLEEP "Waiting due to a call to <function>pg_sleep</function> or a sibling function."
 RECOVERY_APPLY_DELAY "Waiting to apply WAL during recovery because of a delay setting."
 RECOVERY_RETRIEVE_RETRY_INTERVAL "Waiting during recovery when WAL data is not available from any source (<filename>pg_wal</filename>, archive or stream)."
  • 新增了 COMMIT_DELAY 事件的定义: 明确了 COMMIT_DELAY 等待事件的描述为 "Waiting for commit delay before WAL flush."(等待 WAL 刷新前的提交延迟)。

总结

这个补丁是一项可观测性(Observability)增强功能。它没有改变 PostgreSQL 的组提交或 WAL 刷新的行为,而是增加了对现有行为的监控和诊断能力。

在应用此补丁后,用户可以更清晰地诊断为什么某些事务提交(commit)操作耗时较长:如果进程显示在 COMMIT_DELAY 等待事件中,那么慢的原因就是配置的组提交延迟(commit_delay)在生效,而不是 WAL 刷新本身慢,这有助于调优和故障排除。