PG 19 破局可观测短板, 无损植入锁等待增量统计信息
本期播客
PG 19 又补上了一块可观测短板, 终于有锁等待增量统计信息了
数据库变慢,不一定是 SQL 写烂了,也不一定是 I/O 扛不住。
很多时候,真正把系统拖死的,是你看不见、却天天发生的锁等待。
PostgreSQL 在这次提交里,补上了一块长期存在的监控盲区:commit 4019f725。新加入的 pg_stat_lock,价值不在于“又多了一个视图”,而在于它第一次把锁行为沉淀成了可累计、可重置、可对比的统计事实。
过去不是看不到锁,而是只能“看现场”,很难“看趋势”
以前 PostgreSQL 当然能查锁。pg_locks 能看“谁在等谁”,pg_stat_activity 能看“当前会话在等什么”,log_lock_waits 能把超过 deadlock_timeout 的长等待打进日志。
问题在于,这三者都更像事故现场,不像体检报告。
你能看到一次阻塞,不代表你知道过去 24 小时里,到底是 relation 锁、transactionid 锁,还是 advisory 锁,持续在拖慢业务。
这就是很多团队长期陷入“数据库玄学”的根源:有现象,没有累计事实;有告警,没有趋势画像。
pg_stat_lock最聪明的地方,不是“多”,而是“克制”
这次新增的不是按表、按 SQL、按会话的明细追踪,而是cluster 级、按 lock type 聚合的统计。
它只有 5 列:
locktypewaitswait_timefastpath_exceededstats_reset
很多人会嫌少,但恰恰因为少,这个设计才高级。
第一性原理很简单:
监控必须服务系统,不能反噬系统。
锁管理本来就是数据库最敏感的核心路径之一。如果你为了“看得更细”而把统计做成高基数、强实时、重明细,代价很可能直接打在并发控制路径上,最后变成“为了监控锁,先把锁搞慢”。
PostgreSQL 这次没有走这条歪路,而是选择了固定大小、按 LockTagType 聚合的实现。这不是保守,这是工程克制。
最关键的认知:waits 和 wait_time 不是“所有等待都算”
这是很多人最容易误解的地方。
pg_stat_lock.waits 和 wait_time 只在两个条件同时满足时才会累计:
这次加锁最终成功了 等待时间超过了 deadlock_timeout
这意味着什么?
这意味着 pg_stat_lock 不是纳秒级示波器,也不是全量事件追踪器。
它天然会漏掉那些短而频繁的微等待,所以它不适合替代全链路性能剖析工具。但反过来说,它特别适合回答一个更有管理价值的问题:
到底是哪一类锁,在持续制造足以影响业务体验的等待?
这不是一个“抓瞬时尖峰”的工具,而是一个“做长期治理”的仪表盘。
还有一个很容易被低估的指标:fastpath_exceeded
这个字段很有杀伤力。
它统计的是:某类锁原本想走 fast-path 快速路径,但因为 fast-path 槽位不够,最终没走成的次数。
官方回归测试专门构造了一个非常现实的场景:创建一个分区表,并把分区数做到超过 max_locks_per_transaction,然后访问这个分区表,结果 relation 类型的 fastpath_exceeded 会增长。
这说明什么?
说明在重度分区、宽事务、复杂查询的系统里,你以前觉得“最近锁开销怪怪的”,现在终于能把怀疑变成证据:
是不是 fast-path 容量打穿了?是不是锁获取开始更多回落到主锁表路径了?
这类问题过去不是不存在,而是缺少一个便宜、持续、内建的观测信号。
对 DBA、架构师、开发者,各自意味着什么
对 DBA 和架构师,这不是一个排查单次事故的小玩具,而是建立“锁画像”的基础设施。
你可以按 reset 周期持续观察:
relation锁的waits/wait_time有没有抬头transactionid锁是不是在热点更新场景里持续上升advisory锁是不是已经被应用层滥用
对应用开发者,这个视图的意义同样直接:
它逼着你面对并发模型,而不是继续把一切甩锅给“数据库性能”。
如果 transactionid 等待长期偏高,问题通常不是 DBA 再加一个索引就能解决,而是你的事务边界、热点更新策略、重试机制、批处理方式出了问题。
说得更尖锐一点:
很多所谓“数据库慢”,本质上是应用并发设计粗糙。
但别神化它,它解决的是“长期缺位”,不是“一步到位”
pg_stat_lock 很有价值,但它不告诉你:
具体是哪张表 具体是哪条 SQL 具体是哪个会话
所以它不能替代 pg_locks、pg_blocking_pids()、pg_stat_activity、SQL 日志和应用 trace。
正确姿势从来不是二选一,而是分层使用:
pg_stat_lock看趋势pg_locks和pg_stat_activity看现场日志和 trace 补上下文
这才是完整的锁诊断闭环。
真正值得重视的结论
如果你的系统并发很低、锁冲突极少、schema 也不复杂,那 pg_stat_lock 的边际收益确实有限。
但只要你进入下面这些场景,它就很可能从“锦上添花”变成“运维必需品”:
高并发 OLTP 热点行更新 重度分区表 频繁 DDL 大量 advisory lock 宽事务、长事务并存
所以,这次提交不是一个“酷炫新功能”,而是 PostgreSQL 监控哲学一次非常成熟的补洞:
用足够便宜的方式,回答过去一直缺失、但生产系统又反复会问的问题。
真正优秀的数据库观测,不是把一切都采下来。
而是把最该采的、最能指导行动的信号留下来。pg_stat_lock,就是这种克制而有效的工程产物。
你怎么看?
你更期待 PostgreSQL 下一步把锁统计继续细化到 relation 级,还是认为现在这种“低开销、低基数、强实用”的设计才是正路?
参考:
PostgreSQL 官方 commit
DeepWiki: postgres/postgres
附注:文中技术表述已结合官方 commit 补丁事实与 DeepWiki 的 PostgreSQL 知识做过一致性校验。