场景描述:同样的系统部署在3个环境中,(问题表P) 正常的增长范围应该是是每天1M,某一天线上问题说是系统宕机了,然后看了一下系统状态日志,磁盘空间满了。
处理流程:
- 日志本来是7天循环的,先手动删除了一下。
- 有一张数据备份表,和业务流程日志表,这两个是可以删除的,然后进行了truncate。
释放了10几个G的空间,然后启动服务,开始排查问题。
- select pg_size_pretty(pg_relation_size('table_name'));查看了表物理空间大小,发现有一张P表达到了300G,然后第二天观察了一下,发现一天增长了近5G的数据。这个P表的数据是从其他表中计算插入的,对比三个环境的基础数据O表,数据量大小和增量相差不大,另外两张P表每天也就增量1M。
- 初步怀疑是因为这个表有删除动作导致的物理空间没有释放(GP 删除和修改数据,都会占用双倍的物理空间,不会进行释放)。当时连 count 命令都不能执行完成,扫描代价太高了。
- 当时漏掉了一个操作,看一下数据倾斜好了,本身分布键是比较均匀的,当时试下segment问题好了,现在没办法复现了。
- 最后决定方案就是,停机执行真空操作,但是要想释放空间就要vacuum full,这个指令也是极其耗时。服务也不能挺的太久,后来决定基于 mysql 大表变更方案 进行改动。
- 本地 I5 4核,13G 真空耗费57分钟。(生产8核 320G ,10小时以内,具体时间没有统计到,应该很短)动作本身不耗费物理空间所以不用考虑剩余磁盘空间问题,内存也没有波动。
- 停机。
- 修改表名
- 建立新表,创建新表索引
- 执行真空
- 预期时间内如果执行完成,直接删除新表,将老表名称变更回去。
- 如果预期时间内不能完成,则正常启动项目,等真空完成,增量数据回老表。
结果:
- 预期时间内真空完成,P表由320G →59M
- 真空前每天增量1G+,现在每天增量1M
- count操作可以执行
- 直接删除新表,恢复老表 正常启动项目。