广告广告位招商联系 ads@iiunion.comA5 · 728×90(移动端 320×100) · 参考价 ¥300/月了解详情 →

PostgreSQL 长事务拖垮 VACUUM?从 pg_stat_activity 定位

Started by Internet_Notes · 2026-11-04 01:01 UTC · 4 views · 1 replies
I Member
PostgreSQL 表越跑越慢,VACUUM 跑了也没用,先别怀疑硬件,大概率是长事务拖住了清理。我的定位流程很固定。
第一,看 pg_stat_activity。找 state 长时间是 idle in transaction 或 active 的会话,xact_start 越老越可疑。一个挂起的事务会钉住 xmin,VACUUM 不敢回收它之后的所有死元组,表膨胀就是这么来的。
第二,确认膨胀证据。看 pg_stat_user_tables 的 n_dead_tup 和 last_autovacuum,死元组堆积、自动清理很久没成功,就是对上号了。再结合表大小和实际行数,膨胀比例一算就有数。
第三,定位长事务来源。应用侧最常见的是连接池里拿了连接没提交、后台任务开了事务忘了关、交互式会话挂着不退出。按 application_name 和 client_addr 分组,来源很快收敛到一两个服务。
第四,处理分两步。先和业务方确认能不能终止,确认后 pg_terminate_backend 结束长事务;再手动 VACUUM ANALYZE 跑一次,看死元组是否下去。直接调大 autovacuum 参数而不清长事务,等于没治。
第五,防复发。连接池加空闲事务超时、后台任务事务加超时兜底、慢事务告警按 xact_start 年龄触发,这三项上了,长事务基本能早发现。
你那边遇到过 VACUUM 清理不下去的情况吗?最后是长事务,还是参数问题?
I Editorial
长事务拖住 VACUUM 的确是表膨胀常见根因。定位时先看 pg_stat_activity 里 xact_start 很老的 idle in transaction,再对 n_dead_tup 与 last_autovacuum。连接池借出未归还、后台任务开事务忘提交、交互会话挂着,是三类高频来源。处理上先温和终止罪魁会话,再跑一次针对性 VACUUM;同时把 idle_in_transaction_session_timeout 和语句超时配上,比每次人工救火稳。应用侧避免在事务里做远程调用和等人交互。
广告广告位招商联系 ads@iiunion.comA6 · 728×90(移动端 320×100) · 参考价 ¥200/月了解详情 →
Log in or register to reply.