MySQL碎片整理小节--实例演示
MYSQL之磁盘碎片整理
清澈,细流涓涓的爱
数据库引擎以InnoDB为主
1.磁盘碎片是什么
InnoDB表的数据存储在页中,每个页可以存放多条记录,这些记录以树形结构组织,这棵树称为B+树。
聚簇索引的叶子结点包含行中所有字段的值,辅助索引的叶子结点包含索引列和主键列。
在InnoDB中,删除一些行,这些行只是被标记已删除,而不会立即删除,个人认为和电脑的清除磁盘相同,之后可以通过覆盖旧数据实现删除,InnDB的Purge线程会异步的清理这些没用的索引键和行。但是依然不会把这些释放出来的空间还给操作系统重新使用,因此会导致页面中存在很多空洞,如果表结构中包含动态长度字段,这些空间甚至无法被InnoDB重新用来存储新的行。
另外严重的问题是删除数据会导致页page中出现空白空间,大量随机的Delete操作必然会在数据文件中造成不连续的空白空间,当插入数据时,这些空白空间则会被利用起来,造成了数据的物理存储顺序和逻辑的排序顺序不同,这就是数据碎片。
-- 查看全局变量Purge
show variables like 'innodb_purge_threads';
InnoDB后台线程:https://www.cnblogs.com/abclife/p/5062008.html
解释磁盘碎片的英文博客:https://lefred.be/content/overview-of-fragmented-mysql-innodb-tables/
上面这是个大能的博客,写的pretty good!
2.实验
我们首先创建一个具有一百条数据的表来进行实验:
delimiter //
create procedure insertt()
begin
declare i int DEFAULT 0;
while i<1000000 do
insert into temp values(null,'a',1);
set i:=i+1;
end while;
end;
//
delimiter ;
drop PROCEDURE insertt;
-- 尝试插入一百万条数据
call insertt()
-- mysql版本5.7.36
> OK
> 时间: 838.706s
创建后的磁盘存储大小:

DB:information_scheme中存放我们表的信息,通过下列命令来查看我们的磁盘碎片最大的前五名
-- 别人的博客中copy的,我的猪脑写不出来
SELECT CONCAT(table_schema, '.', table_name) as 'TABLE',
ENGINE, CONCAT(ROUND(table_rows / 1000000, 2), 'M') ROWS,
CONCAT(ROUND(data_length / ( 1024 * 1024 * 1024 ), 2), 'G') DATA,
CONCAT(ROUND(index_length / ( 1024 * 1024 * 1024 ), 2), 'G') IDX,
CONCAT(ROUND(( data_length + index_length ) / ( 1024 * 1024 * 1024 ), 2), 'G') 'TOTAL SIZE',
ROUND(index_length / data_length, 2) IDXFRAC, CONCAT(ROUND(( data_free / 1024 / 1024),2), 'MB') AS data_free
FROM information_schema.TABLES
ORDER BY data_length + index_length desc LIMIT 5;
result:

我们可以看到data_free,我们最高的free空间只有6MB
innodb_ruby工具可以直接在linux系统下运行查看.Ibd文件的结构,将B+tree以及磁盘使用暴露出来,但是我不会用,这里带上他的github链接:https://github.com/akopytov/sysbench
下面我们执行删除操作:
-- 删除前五十万条数据
delete from temp order by id LIMIT 500000
文件大小:

删除后,磁盘文件的大小并没有变化,因为删除产生了磁盘碎片,空白page残留在文件中,被删除的数据记录仍然被保持在MySQL的链接清单中,因此数据存储文件的大小并不会随着数据的删除而减小,我们再次使用上述操作查看data_free。

可以看到temp表的data_free增长了。
3.对于碎片回收操作
对MySQL进行碎片整理有两种方法:
OPTIMIZE TABLE
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE table_name1 [, table_name2] ...
ALTER
ALTER TABLE table_name ENGINE = Innodb
OPTIMIZE可以同时对多个表格进行碎片整理,OPTIMIZE语句有两个可选的关键字:LOCAL和NO_WRITE_TO_BINLOG,默认是每次碎片整理都会被记录到BINlog二进制日志中去,如果带了关键字,就不会被记录到日志中去。
ALTER看起来是执行了一次空操作,重新设置了一遍数据库引擎,同时会进行碎片整理。
两种操作在一定程度是等价的。
使用optimize结果

磁盘文件小了一半左右

alter不再演示
4.后记
1.MySQL官方建议不要经常(每小时或每天)进行碎片整理,一般根据实际情况,只需要每周或者每月整理一次即可。
2.OPTIMIZE TABLE只对MyISAM,BDB和InnoDB表起作用,尤其是MyISAM表的作用最为明显。此外,并不是所有表都需要进行碎片整理,一般只需要对包含上述可变长度的文本数据类型的表进行整理即可。
3.在OPTIMIZE TABLE运行过程中,MySQL会锁定表。
4.默认情况下,直接对InnoDB引擎的数据表使用OPTIMIZE TABLE,可能会显示「 Table does not support optimize, doing recreate + analyze instead」的提示信息。这个时候,我们可以用mysqld --skip-new或者mysqld --safe-mode命令来重启MySQL,以便于让其他引擎支持OPTIMIZE TABLE。
参考博客:https://www.cnblogs.com/kerrycode/p/10943122.html --写的很好,就是排版不舒服
MySQL碎片整理小节--实例演示的更多相关文章
- MysqL碎片整理优化
先来说一下什么是碎片,怎么知道碎片有多大! 简单的说,删除数据必然会在数据文件中造成不连续的空白空间,而当插入数据时,这些空白空间则会被利用起来.于是造成了数据的存储位置不连续,以及物理存储顺序与理论 ...
- Mysql 碎片整理与统计信息收集
======重新收集统计信息======= 1.分析和存储表的关键字分布 analyze table table_name; analyze 用于收集优化器的统计信息.和tuning相关:对 myis ...
- MySQL基准测试(三)--开源工具与实例演示
MySQL基准测试(三)--开源工具与实例演示 针对web应用 ab ab是一个Apache HTTP服务的基准测试工具. http_load http_load是一个针对Web服务器测试工具. JM ...
- Mysql Innodb 表碎片整理
一.为什么会产生碎片 简单的说,删除数据必然会在数据文件中造成不连续的空白空间,而当插入数据时,这些空白空间则会被利用起来.于是造成了数据的存储位置不连续,以及物理存储顺序与理论上的排序顺序不同,这种 ...
- MYSQL优化之碎片整理
MYSQL优化之碎片整理 在MySQL中,我们经常会使用VARCHAR.TEXT.BLOB等可变长度的文本数据类型.不过,当我们使用这些数据类型之后,我们就不得不做一些额外的工作--MySQL数据 ...
- MySQL表碎片整理
MySQL表碎片整理 1. 计算碎片大小 2. 整理碎片 2.1 使用alter table table_name engine = innodb命令进行整理. 2.2 使用pt-online-sch ...
- astgo经常死机变慢?试试mysql数据碎片整理吧
使用SSH之类的工具或navicat链接数据库后(注意:是链接数据库后哦,不是直接SSH后就弄,这样提示命令错误的) 执行下面命令(目的是对ASTGO的数据库内除话单之外的所有表进行数据碎片整理,特别 ...
- Mysql基本操作整理
1.登录数据库 格式: mysql -h主机地址 -u用户名 -p用户密码 –P端口 –D数据库 –e “SQL 内容”>mysql -uroot -p 数据库名称~~~~~~~~~~~~~~~ ...
- Mysql索引整理总结
一.索引概述 1. 简介 索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息. 举例说明索引:如果把数据库中的某一张看成一本书,那么索引就像是书的目录,可以通过 ...
随机推荐
- c# $ @特殊字符
c# @ 停止字符串中的转义字符,让字符串内的转义字符当正常字符输入. 因此,如果你需要类似"所见所得"效果的赋值,逐字字符串赋值方式会是你的首选!此外,需要注意的是,当使用符号 ...
- c语言结构体中的一个char数组怎么赋值?
目录 前景提示 这里的结构体处理的步骤 一.char数组类型的处理 二.char数组指针类型的处理 三.全部代码 1. char数组 2. char数组指针 结语 前景提示 定义一个结构体,结构体中有 ...
- NPOI导出大量数据的避免OOM解决方案【SXSSFWorkbook】
一.NPOI的基本知识 碰到了导出大量数据的需求场景:从数据读取数据大约50W,然后再前端导出给用户,整个过程希望能较快的完成.如果不能较快完成,可以给与友好的提示. 大量数据的导出耗时的主要地方: ...
- MySQL查看数据库中所有表占用的空间大小
select TABLE_NAME, concat(truncate(data_length/1024/1024,2),'MB') as data_size, concat(truncate(inde ...
- OA办公软件篇(一)—组织架构
OA办公软件篇(一)-组织架构 背景 作用 迭代历程 具体实现 写在最后 背景 在说组织架构之前,我们先来说说OA本身. 百度百科解释OA为:办公自动化(Office Automation,简称O ...
- linux echo用法和实例
echo命令用于在shell中打印shell变量的值,或者直接输出指定的字符串.linux的echo命令,在shell编程中极为常用, 在终端下打印变量value的时候也是常常用到的,因此有必要了解下 ...
- linux 内核以及mod
linux设计为单内核,但是使用了 微内核的设计思想 内核相关的两个文件夹 /proc /sys 设定内核运行参数方法 echo VALUE > /proc/sys/To/SOMEFILE sy ...
- Java &、&&、|、||、^、<<、>>、~、>>>等运算符
&(按位与) 运算规则:两个为真才为真 (1&1=1 , 1&0=0 , 0&1=0 , 0&0=0) 例:3&5=1 3的二进制位是0000 0011 ...
- jdk配置完成tomcat无法启动问题解决
今天在进行struts2练习之前,准备为电脑配置tomcat容器,发现jdk的java指令可以正确运行,而tomcat启动时控制台弹出后立即消失.查资料显示jdk为正确配置,但是自己的java指令都能 ...
- Linux移植到自己的开发板(三)根文件系统
@ 目录 1 Linux内核配置 2 ramdisk制作 3 busybox配置 4 genext2fs生成镜像 为了快速调试,采用ramdisk进行根文件系统测试.要使内核能挂载ramdisk根文件 ...