PostgreSQL 19: 添加组提交延迟的等待事件

John Doe 十二月 17, 2025

虽然 PostgreSQL 很早就支持了组提交特性,但是很难通过特定的监控统计数据,对组提交的配置参数进行调优。

image

特性提交日志

在 WAL 日志刷写之前会有组提交延迟,本次为其添加等待事件。

讨论:https://www.postgresql.org/message-id/CA%2BFpmFf-hWXtrC0Q3Cr_Xo78zuP_M_VC5xgWPOYOkwqOD0T8eg@mail.gmail.com

组提交介绍

在高并发 PostgreSQL 环境中,组提交(Group Commit) 是提升事务吞吐量的一个核心机制,通过将多个事务的 WAL 预写日志批量刷盘,减少磁盘 IO 次数,降低单事务提交的性能开销。而commit_delay参数作为组提交的关键配置,允许事务在提交时等待一段短的时间(默认 0 毫秒,可手动设置),以便凑集更多并发事务一起参与组提交,进一步优化 IO 效率。

但在以往版本中,事务处于COMMIT_DELAY等待阶段时,其等待状态无法被精准识别,相关进程会被归类到“无明确等待事件”或模糊的通用等待类型中,导致 DBA 难以判断“提交延迟”是否真的由组提交等待引发,也无法量化这段等待的耗时,给性能排查和参数优化带来了困扰。

PostgreSQL 通过本次提交解决了这一问题:新增COMMIT_DELAY等待事件,专门用于标记 WAL 刷盘前的组提交延迟等待状态,让组提交延迟的监控变得直观、精准,为 DBA 优化高并发场景下的提交性能提供了一种观测手段。

当数据库开启组提交延迟(commit_delay > 0),且满足活跃事务数达到commit_siblings阈值(默认 5 个)时,事务会进入“等待组提交凑集”的阶段。此时,数据库会触发COMMIT_DELAY等待事件,记录该阶段的等待时长和相关进程状态。

示例

查询pg_stat_activity视图,监控到COMMIT_DELAY等待事件:

-- 查询当前处于 COMMIT_DELAY 等待的事务
SELECT
  pid,
  usename,
  application_name,
  query,
  wait_event,
  wait_event_type,
  state,
  now() - query_start AS query_duration
FROM pg_stat_activity 
WHERE wait_event = 'COMMIT_DELAY';

  pid  | usename | application_name |        query         | wait_event  | wait_event_type | state  | query_duration
-------+---------+------------------+----------------------+-------------+-----------------+--------+----------------
 27492 | app_user| order_service    | INSERT INTO orders...| COMMIT_DELAY| Timeout         | active | 00:00:00.008

查看当前组提交相关配置:

-- 查看 CommitDelay、CommitSiblings 配置
SELECT name, setting, unit, short_desc
FROM pg_settings
WHERE name IN ('commit_delay', 'commit_siblings', 'enable_fsync');

        name         | setting | unit | short_desc
---------------------+---------+------+--------------------------------
 commit_delay        | 2000    | us   | Sets the delay in microseconds before committing.
 commit_siblings     | 5       |      | Sets the minimum number of concurrent transactions before committing.
 enable_fsync        | on      |      | Enables or disables fsync.

调整日志配置,通过 SQL 的日志信息量化等待耗时:

ALTER SYSTEM SET log_statement_stats = on;
SELECT pg_reload_conf();

查看数据库日志,可找到类似记录:

LOG:  statement: INSERT INTO orders (user_id, goods_id, amount) VALUES (1001, 2003, 999);
LOG:  CPU: user: 0.10s, system: 0.05s, elapsed: 0.012s
LOG:  Wait event: COMMIT_DELAY (Timeout), wait duration: 0.002s

事务提交慢的核心原因是COMMIT_DELAY等待(耗时 2ms),占总提交耗时的 16.7%。可根据实际情况调整commit_delay参数(如减小延迟或关闭),或优化commit_siblings阈值。

非常不错的新特性,感谢社区的所有相关人员。

参考

提交日志:https://git.postgresql.org/pg/commitdiff/3cb5808bd11c5a7ef697922335f7642f643a4e7f