mysql清除磁盘碎片

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

任务背景

接到金山云报警短信,说某数据库的容量已经达到了90%的水位线,于是登陆控制台查看详细情况。

在控制台首先发现,每一天的磁盘容量的确有所波动,那么就证明开发人员写的“资源回收”模块是在正常运行的,如图:
mysql清除磁盘碎片

那么就说明没有什么数据是可以删的,既然删不掉多余的数据又不想多掏钱扩磁盘容量,只能从“磁盘碎片”下手了。而InnoDB引擎清理磁盘碎片的命令就是OPTIMIZE

具体操作

首先我先查询一下所有的“磁盘碎片情况”,使用语句如下:

    select CONCAT(TABLE_SCHEMA,'.',TABLE_NAME) as 数据表名,concat(truncate(sum(DATA_LENGTH+DATA_FREE+INDEX_LENGTH)/1024/1024,2),' MB') as total_size, concat(truncate(sum(DATA_LENGTH)/1024/1024,2),' MB') as data_size,concat(truncate(sum(DATA_FREE)/1024/1024,2),' MB') as data_free, concat(truncate(sum(INDEX_LENGTH)/1024/1024,2),'MB') as index_size from information_schema.tables group by TABLE_NAME order by data_length desc; 

或者使用select table_schema, table_name, data_free, engine from information_schema.tables where table_schema not in ('information_schema', 'mysql') and data_free > 0;也可以,这个是查询data_free大于0的所有表。

然后看到我这个叫history_device_flow_day的表里情况如下:
mysql清除磁盘碎片

表里的data_free就是磁盘碎片的量,比如我现在要干掉history_device_flow_day里所有的磁盘碎片,是975MB,于是先查询一下这个history_device_flow_day的存储引擎,使用语句如下:

    show table status from jsonlinefssrds where name='history_device_flow_day';

上面语句里的jsonlinefssrds是对应的数据库,看到的效果如下:
mysql清除磁盘碎片

存储引擎是InnoDB,那么就可以启动清除碎片的语句了:OPTIMIZE TABLE 数据表表名;,因为OPTIMIZE TABLE只对MyISAMBDBInnoDB表起作用。

再执行了OPTIMIZE TABLE history_device_flow_day;之后,大约9分钟,就会看到“OK”的字样:
mysql清除磁盘碎片

估计有的朋友会问,那上面不是明明写了“Table does not support optimize, doing recreate + analyze instead”吗?这个其实无妨,实际上磁盘碎片已经被清除掉了。我们可以再用一次查询磁盘碎片的命令看一下,如图:
mysql清除磁盘碎片

的确释放了900多M。

或者使用ALTER TABLE 表名 ENGINE = Innodb;(只是InnoDB的表可以这么做)来达到清理磁盘碎片的目的,这个命令表面上看什么也不做,实际上是重新整理碎片了。当执行优化操作时,实际执行的是一个空的ALTER命令,但是这个命令也会起到优化的作用,它会重建整个表,删掉未使用的空白空间。

补充

为什么会产生磁盘碎片?那是因为某一个表如果经常插入数据和删除数据,必然会产生很多未使用的空白空间,这些空白空间就是不连续的碎片,这样久而久之,这个表就会占用很大空间,但实际上表里面的记录数却很少,这样不但会浪费空间,并且查询速度也更慢。

注意!OPTIMIZE操作会暂时锁住表,而且数据量越大,耗费的时间也越长,它毕竟不是简单查询操作。所以把OPTIMIZE命令放在程序中是不妥当的,不管设置的命中率多低,当访问量增大的时候,整体命中率也会上升,这样肯定会对程序的运行效率造成很大影响。比较好的方式就是做个shell,定期检查mysql中 information_schema.TABLES字段,查看DATA_FREE字段,大于0的话,就表示有碎片,然后启动脚本。

参考资料

http://pengbotao.cn/mysql-suipian-youhua.html
http://irfen.me/mysql-data-fragmentation-appear-and-optimization/

最后的最后,如果您觉得本文对您升职加薪有帮助,那么请不吝赞助之手,刷一下下面的二维码,赞助本人继续写更多的博文!
mysql清除磁盘碎片



 本文转自 苏幕遮618 51CTO博客,原文链接:http://blog.51cto.com/chenx1242/2064189

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
8月前
|
缓存 固态存储 关系型数据库
MySQL性能优化指南:深入分析重做日志刷新到磁盘的机制
MySQL性能优化指南:深入分析重做日志刷新到磁盘的机制
440 0
|
8月前
|
缓存 关系型数据库 MySQL
MySQL Binlog--事务日志和BINLOG落盘参数对磁盘IO的影响
MySQL Binlog--事务日志和BINLOG落盘参数对磁盘IO的影响
163 0
|
6月前
|
存储 关系型数据库 MySQL
MySQL数据库碎片化:隐患与解决策略
UUID作为主键可能导致MySQL存储碎片,影响性能。频繁的DML操作、字段长度变化和非顺序插入(如UUID)都会造成碎片。碎片增加磁盘I/O,降低查询效率,浪费空间,影响备份速度。建议使用自增ID,固定长度字段,并适时运行OPTIMIZE TABLE来减少碎片。
|
3月前
|
SQL 存储 关系型数据库
MySQL 回收表碎片实践教程
在 MySQL 数据库中,随着数据的增删改操作,表空间可能会出现碎片化,这不仅会占用额外的存储空间,还可能降低表的扫描效率,特别是一些大表,在进行数据清理后会产生大量的碎片。本篇文章我们一起来学习下如何进行碎片回收以及相关注意点。
98 1
MySQL 回收表碎片实践教程
|
5月前
|
缓存 关系型数据库 MySQL
MySQL——大量的deleted进程导致磁盘100%
MySQL——大量的deleted进程导致磁盘100%
38 0
|
7月前
|
存储 SQL 关系型数据库
如果mysql磁盘满了,会发生什么?还真被我遇到了!
如果mysql磁盘满了,会发生什么?还真被我遇到了!
89 0
|
存储 Prometheus 监控
记一次MySQL DB实例磁盘告警的处理过程
记一次MySQL DB实例磁盘告警的处理过程
219 0
记一次MySQL DB实例磁盘告警的处理过程
|
存储 SQL 缓存
细说MySQL中磁盘与CPU的交互——神秘的Buffer Pool
MySQL是如何读取记录的?Buffer Pool缓存功不可没!什么是Buffer Pool?它的结构是什么样的?当数据不断的读取,缓存的数据如何更新?本文将带你详细了解这些!
157 0
细说MySQL中磁盘与CPU的交互——神秘的Buffer Pool
|
SQL 关系型数据库 MySQL
Mysql碎片整理:一些注意事项整理
整理Mysql的一些注意事项整理,不断汇总,可以通过二级标题去筛选,每个二级标题都是独立的。可以在评论区评论留下注意事项,我汇总,积少成多。
186 0
|
存储 SQL 关系型数据库
Mysql碎片整理:存储程序
定义变量;语句结束分隔符;存储函数;存储过程;游标在存储过程和存储函数中的使用;触发器的定义;事件的创建。
109 0