postgresql 长事务导致未vacuum

发布时间 2023-09-26 15:28:00作者: 章怀柔
故障发生

Postgresql某系统数据库反馈数据库慢,使用Pgbadger 分析慢日志发现以下SQL执行消耗较高,执行时间平均2S。

 

分析索引表上列msg_source存在索引,该表可以正常走索引。既然能走索引,PG中考虑就是表死元组过多了。

 


一、分析表的死元组:表有273852002 行死元组未清理,分析为表死元组过多影响查询速度。查看表上last_autovacuum 已做但是没有生效。手动vacuum也没有生效,存在长事务影响vacuum回收。

 

二、长事务如下:

 

 

发现长事务是11月17日连接上来的,距离今天已经三天了,并没有被postgre系统进程杀死。手动将长事务杀死后,再次vacuum表,执行成功。对比回收前和回收后的执行计划。

 

 

优化前3.9S,优化后4ms。至此优化完成。问题延伸

但是又产生一个新的疑惑,数据库设置了 idle_in_transaction_session_timeout 参数为20S,为什么没有杀死长事务会话。后面测试了几次idle in transaction会话,都能被系统杀死,这个问题无法复现,成为了悬案,后面遇到再研究。

转载自:https://www.modb.pro/db/198865