问题
有一个 info_track 表用来临时存储告警推送数据,逻辑处理完成后,会执行 Delete 语句删除对应的记录。
问题:项目现场运行了几个月后,发现磁盘空间莫名占用了过多的存储,> 100GB,且无法释放。
生产环境出现了问题,心里当时咯噔一下,不妙,有个隐藏 bug 没有测出来。这不得赶紧沉下心来分析排查,经过抽丝剥茧逐步排查,功夫不负有心人,最终定位到是 info_track 这个表数据量大,执行 delete 删除后,虽然记录确实被删除了,但磁盘上 .ibd 文件大小并没有被释放。
既然定位到问题了,那就好解决。
解决方法
当时我们采用增加一个定时 job 的方法来修复该问题:每月定时对这个表执行一次 truncate table 操作。
这是好几年前的一个项目,各位朋友别吐槽解决方法的合理性,以解决问题优先,哈哈~
根因分析:
truncate table 命令将快速删除数据表中的所有记录,保留数据表结构,但会清理磁盘 .ibd 空间,即数据不可以恢复。
delete from 命令也是快速删除数据表中的所有记录,保留数据表结构,但 .ibd 文件不会清理,需要的时候,数据可以回滚恢复。
问题验证
以 45 环境 info_operate_log 表为例进行演示,该表总共有 3229 条记录。
1、登录服务器查看 mysql 表空间磁盘占用情况
# cd /var/lib/kubelet/pods/a5077c96-e7bf-11e8-bc9b-ac1f6b928894/volumes/kubernetes.io~local-volume/local-pv-e40a818a/mysql/senseguard# du –hsl *
info_operate_log.ibd 占用磁盘空间为 9.0M
2、DELETE info_operate_log
3、查看磁盘占用情况
Info_operate_log.ibd 磁盘空间还是 9.0M
4、TRUNCATE TABLE info_operate_log
5、再次查看磁盘占用情况
Info_operate_log.ibd 占用空间只有 80K 了,清理成功。