Postgresql数据库磁盘快速增长的一个可能原因
结论
Postgresql中发现磁盘占用空间莫名快速增长时,有一种可能是因为pg_stat_activity
中有异常的很久之前的查询导致的。
持续时间特别长的查询会导致Postgresql不停的维护该查询之后所有更新的数据记录,导致表大小快速的膨胀。
过程
起因
AWS上一套系统的RDS之前从Postgresql 9.5升级到了9.6。升级之后跑的好好的,突然在1月中接到警报,说磁盘不足。
很好奇,这是一个访问量不大的网站, 之前记得一百多个G空间的。怎么突然就警报空间不足了。
调查
登录AWS Console一看,吓了一跳,RDS的数据库剩余磁盘容量,2个星期内从180G下降到80G。空间下降这么快,肯定是哪边出了问题。
使用psql
登录后台,查看了各表的大小
发现一个名为listings
表的size异常的大。
首先第一反应,手动执行命令vacuum VERBOSE analyze listings
来尝试清理listings
表。
在输出结果中发现了奇怪的地方,xxxxxxx dead row versions cannot be removed yet.
。提示有几百万条旧记录无法被删除。
解决
网上一通找,在Vacuum not removing dead tuples中找到了原因。
检查pg_stat_activity
中的sql,发现一个运行了长达两星期的listings查询, 为了维护该transaction,Postgresql不得不将后续所有数据的更新都保存了下来,导致了大量的磁盘消耗。
使用SELECT pg_terminate_backend PID
杀死了这个查询。然后再使用vacuum VERBOSE analyze listings
命名清理listings
表,磁盘容量恢复到130个G。
疑问
至今还是不知道是什么原因导致一个查询可以在客户端已经terminate的情况下,在数据库端执行了两个多星期还没有被终结。即使是全表都扫一遍撑死也就几分钟的事情。