MySQL-磁盘空间释放
目录
MySQL磁盘占用分析
MySQL作为存储,很容易想到的磁盘占用主要分为以下几种:
- 日志文件
- 数据文件
- 临时文件
日志文件
众所周知,MySQL 的 binlog (二进制日志) 会记录数据库的操作,一般线上会存储至少7天。当线上业务增删改请求太频繁,或者修改的行数过多时(因为为了线上数据安全,默认会使用row格式的binlog),会导致binlog文件增长很快
磁盘清理方式
日志文件清理
- 清理 binlog 文件
# 将binlog删除到mysql-bin.001174
mysql> purge binary logs to 'mysql-bin.001174';
# 删除 2021-06-06 22:46:26 之前的binlog
mysql> purge binary logs before '2021-06-06 22:46:26';
# 将binlog自动保存时间从7天改为3天
mysql>
mysql> set global expire_logs_days=3;
数据文件清理
一般数据文件清理需要业务方的配合,毕竟是业务方的数据。这里需要注意的是,仅仅删除数据可能不会直接释放空间。此时有两种方案:
- 机器磁盘还有较大空间。此时仅仅删除数据即可,新写入的数据会填补未使用的页。
- 机器磁盘空间已经不足。需要执行重建表操作,具体操作步骤为:
# 1. 从库停止复制
mysql> stop slave;
# 2. 从库重建表
mysql> alter table xx engine=innodb;
# 3. 执行主库切换操作
# 具体见切库流程
大表清理
为了减小删除大文件引起数据库服务器 IO 抖动,可以对大文件进行shrink,减小删除数据对IO的影响。
# 待删除表:dest_table_del
# 1.创建硬链接
$ln dest_table_del.ibd /home/work/data_bak/dest_table_del.ibd.hdlk
# 2.删除表:
$drop table dest_table_del;
# 3.删除文件
# 从233 开始每次递减2
$for i in `seq 233 -2 2 `; do echo $i; sleep 2; /usr/bin/truncate -s ${i}G /home/work/data_bak/dest_table_del.ibd.hdlk;done
临时文件清理
从临时文件的原理可以看到,一般是由大 SQL
引起,所以直接找到大 SQL
,与业务方沟通完后杀掉即可。
其他解决方式
1. 联系业务删除数据
- 可能是最快的方式。
- 甚至可以让业务写定时删除数据的脚本,但是注意一次不要删除大量的数据,避免引起主从延迟。
- 当业务删除完数据后,去掉从库业务流量,并在从库执行释放空间操作
mysql> stop slave;
mysql> alter table xx engine=innodb;
此处不用
optimize table
的原因,其实optimize table
实际上是 recreate + analyze 的步骤。
2. 大库迁移
当某个库数据量很大,且 QPS 不低,足以作为单独的集群时,可以进行迁移操作。具体的迁移步骤:
- 扩容从库
- 该库读流量打入新的从库,同业务共同观察业务
- 与业务沟通时间并进行写流量迁移
3. 申请大磁盘空间机器替换
具体操作步骤:
- 替换从库机器
- 主库切换
- 下线旧机器
总结
其实数据库的磁盘空间在日常运维工作中就是应该持续关注的事情。可行的策略是:
- 在磁盘占用还不是太高的时候(60%-80%):增加日常巡检处理提醒,此时可以开始关注,如有大表,需联系业务开始处理,不至于在后面的改表或者磁盘空间快满时陷入被动。
- 磁盘已经告警时:参考解决方法。
最重要的还是主动解决,避免被动。
参考
- 大表删除操作:http://blog.itpub.net/22664653/viewspace-750408/