Mysql磁盘碎片整理

这篇博客探讨了MySQL数据库在频繁删除操作后产生的磁盘碎片问题,总结了通过删除表分区进行碎片整理的高效方法,指出这种方式可以提升IO性能和SQL执行效率。文章还提到了检查磁盘碎片的SQL语句,并建议定期清理碎片以维持数据库性能。此外,作者提及在紧急情况下可考虑调整刷盘参数,但会带来数据丢失风险,并分享了数据库核心参数的相关链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

        经常进行 delete 操作,产生空白空间,如果进行新的插入操作,MySQL将尝试利用这些留空的区域,但仍然无法将其彻底占用,于是造成了数据的存储位置不连续,以及物理存储顺序与理论上的排序顺序不同,久而久之就产生了碎片。

根据线上处理经验总结比对3种处理磁盘碎片优缺点:

治理方案

优势

缺点

备注

将数据量巨大的表设计成分区表,按时间分区

通过结转分区数据,删除分区释放磁盘碎片,磁盘IO抖动秒级别,对线上业务影响小

估算数据量,每个分区不超过3亿数据350G为佳;流水,日志表这些表应该在创建时就应该设计成分区表,避免以后磁盘碎片痛点

重建表存储引擎,重新组织数据(ALTER TABLE tablename ENGINE=InnoDB;)

整理过程加锁,周期长,且对线上业务影响较大:10亿数据量,1000G,tp99会持续超过60s

谨慎操作

主从切换(DBA可使用一个磁盘更大的干净的库,进行主从切换)

涉及面广,牵扯范围较大,处理时长在分钟级

谨慎操作

总结

        使用删除表分区的方式性价比更高:数据库:    Sql语句:alter table xxxx drop partition p19;

        只要使用mysql,必然会遇到Mysql碎片问题痛点,数据量大的业务表应该设计成分区表方便磁盘碎片整理,降低维护成本和业务影响。碎片清理前后,IO性能会上升,SQL执行效率更快。所以,在日常运维工作中,应对碎片进行定期清理,保证数据库有稳定的性能和充足的空间。

        扩展:提到提高IO性能,在紧急情况下还可以考虑开启刷盘(设置 sync_binlog=0;innodb_flush_log_at_trx_commit=0),但开启刷盘会有数据丢失风险(集团数据库模板配置参数默认sync_binlog=1;innodb_flush_log_at_trx_commit=1)。

        mysql数据库核心参数介绍:https://www.cnblogs.com/klvchen/p/10861850.html

查看磁盘碎片的SQL

SELECT table_schema AS '数据库',
       TABLE_NAME AS '表名',
                     table_rows AS '记录数',
                     truncate(data_length/1024/1024/1024, 2) AS '数据容量(MB)',
                     truncate(data_free/1024/1024/1024, 2) AS '数据空洞(MB)',
                     truncate(index_length/1024/1024/1024, 2) AS '索引容量(MB)'
FROM information_schema.tables
ORDER BY data_length DESC,
         index_length DESC;

题外话

        治理磁盘碎片最好的方法就是删除表,不同业务对数据的要求不同。如果有可能的话新建一个临时表。

-- 原始表
origin_test
-- 临时表
origin_test_temp
-- 以上两张表结构一样,不同的是临时表带分区


ALTER TABLE origin_test RENAME TO origin_test1; 
ALTER TABLE origin_test_temp RENAME TO origin_test; 


以上,通过修改表明的方式,进行磁盘碎片整理。但是数据库表会有短暂的停写。再过一段时间后,origin_test表的数据积累到一定程度,就可以将origin_test_temp删除了。

### 如何清理 MySQL 索引碎片的最佳实践 #### 了解索引碎片及其影响 索引碎片是指由于频繁的插入、更新和删除操作,导致数据库中的数据页不再连续存储的现象。这会降低查询性能并增加磁盘I/O开销。avg_fragmentation_in_percent列展示了堆或索引的碎片水平[^2]。 #### 清理索引碎片的方法 ##### 对于 InnoDB 表 对于 InnoDB 存储引擎来说,可以通过OPTIMIZE TABLE命令来重组表结构从而减少碎片化: ```sql OPTIMIZE TABLE table_name; ``` 该命令实际上执行了如下三个动作: - 创建一个新的临时表并将原表的数据复制过去; - 构建新的索引; - 删除旧表并重命名新表为原来的名称; 这种方法可以有效地消除物理上的碎片,并重建所有的辅助索引以提高访问效率。不过需要注意的是,在高并发环境下运行此命令可能会引起短暂的服务中断,因此建议在低峰期进行维护工作。 另外一种方式是在 ALTER TABLE 的基础上加上 ALGORITHM=COPY 参数来进行在线DDL变更: ```sql ALTER TABLE table_name ENGINE=InnoDB, ALGORITHM=COPY; ``` 这种方式同样能够达到整理空间的效果而且支持更多的选项控制。 ##### 对于 MyISAM 表 MyISAM 类型则可以直接利用 OPTIMIZE TABLE 或者 REPAIR TABLE 来修复损坏及优化表结构: ```sql REPAIR TABLE table_name QUICK; -- 只针对非致命错误做快速修复 OPTIMIZE TABLE table_name; ``` 以上两种方法都可以很好地解决MyISAM表中存在的碎片问题。 #### 定期监控与预防措施 为了防止过多的碎片积累,应该定期检查数据库健康状况并通过上述手段及时处理潜在隐患。同时合理规划业务逻辑尽量避免不必要的DML(DatA Manipulation Language)操作也是很重要的方面之一。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值