PG数据库死亡元组过多导致查询慢优化方法

发布于 2021-09-22 07:49

集团云改数转战略背景下,随着越来越多的平台系统上云去O,很多系统数据库采用了PGPostgresSQL)数据库。在使用PG数据库时,会发现有时候查询速度非常慢,以往很快就查询出来的,结果需要数十秒才行,检查发现没有锁,这时候一般都是表的死元组太多导致的。本文通过因为死亡元组过多导致数据库查询响应慢,从而引发IPTV3.0平台C1模板工单下发失败的案例,介绍PG数据库死亡元组清理及业务程序优化的方法。

一、PG数据库死亡元组介绍

PostgreSQLdelete操作时,数据集(也叫做元组、tuples)是没有立即从数据文件中移除的,仅仅是通过在行头部设置xmax做一个删除标记。update操作也是一样的,在postgresql中可以看作是先deleteinsert

这是PostgreSQL MVCC的基本思想之一,因为它允许在不同进程之间只进行最小的锁定就可以实现更大的并发性。这个MVCC实现的缺点是它会留下被标记删除的死亡元组(dead tuples),即使在所有事务完成之后依然存在。

如果不清理掉那些dead tuples(对任何事务都是不可见的)将会永远留在数据文件中,浪费磁盘空间,对于表来说,有过多的删除和更新,dead tuples很容易占绝大部分磁盘空间。而且dead tuples也会在索引中存在,更会加重磁盘空间的浪费。这是在PostgreSQL中常说的膨胀(bloat),需要处理的数据查询越多,查询的速度就越慢。
二、IPTV3.0平台EPG频繁更新引发查询慢问题案例

(一)问题描述

某天下午,号百与百视通等合作方反馈IPTV3.0平台C1接口出现工单失败。
(二)定位过程

1.检查接口机日志发现C1工单任务正常,任务已入库。

2.检查CP日志发现有SQL超时日志。

3.手工执行SQL语句发现执行也比较慢:

分析发现数据库epgserver表的死亡元组过多(800W+),CPM丢弃模板应用任务,未通知到EPG,最终导致C1工单失败:

事务信息检查

5.进一步分析发现数据库master也存在startup的僵尸进程:FTP

查询statup对应的时间节点和pid

建链成功后断开,下面建链后5秒才auth,出现startup

主机上最近2次的startup

(三)原因分析

经过进一步排查分析,引发C1接口失败的原因主要有:

1、PG数据库中epgserver表的死亡元组过多(800W+),导致数据库更新操作返回超时。

2、由于epgserver表的死亡元组过多,正常的数据库自动vcauum清理操作速度赶不上死亡元组生成速度,导致死亡元组积压越来越多,最终导致表查询变慢。

3、CP存在代码逻辑需要优化,原来的机制为EPG每3秒上报一次心跳(心跳中带着在线用户数信息),如果本次心跳中的在线用户数比上次的在线用户数多,就会立即更新到数据库,造成频繁地写数据库。
(四)优化措施
为了减少业务程序对PG数据库表更新频率,减少死亡元组生成速度,我们制定了相关优化措施,调整epgserver表更新机制,CP根据EPG的心跳,来决定是否将EPG的信息更新到数据库。

1EPG的状态发生变更,立即更新。

2EPG的在线用户跨越最大用户数的80%(例如从79%上升到80%以上,或者从80%以上降低到79%),立即更新。

3EPG的在线用户数大于等于最大用户数的80%并且本次的在线用户数比上次的在线用户数多,立即更新。

4EPG的本次在线用户数跟上次相比,变化大于最大用户数的30%,立即更新。

5、如果不满足上述四个条件,EPG固定5分钟更新一次,减少更新频率。
三、总结


图文原创 / 省公司供稿

编辑 /盐城公司运维宣传团队

本文来自网络或网友投稿,如有侵犯您的权益,请发邮件至:aisoutu@outlook.com 我们将第一时间删除。

相关素材