MySQL不建议delete删除数据的原因是什么?(三)

开课吧开课吧锤锤2021-03-08 09:54

    Java编程语言是一种简单、面向对象、分布式、解释型、健壮安全、与系统无关、可移植、高性能、多线程和动态的语言。如今Java已经广泛应用于各个领域的编程开发。

java

    Innodb中的碎片

    碎片的产生

    我们知道数据存储在文件系统上的,总是不能100%利用分配给它的物理空间,删除数据会在页面上留下一些”空洞”,或者随机写入(聚集索引非线性增加)会导致页分裂,页分裂导致页面的利用空间少于50%,另外对表进行增删改会引起对应的二级索引值的随机的增删改,也会导致索引结构中的数据页面上留下一些"空洞",虽然这些空洞有可能会被重复利用,但终究会导致部分物理空间未被使用,也就是碎片。

    同时,即便是设置了填充因子为100%,Innodb也会主动留下page页面1/16的空间作为预留使用(Aninnodb_fill_factorsettingof100leaves1/16ofthespaceinclusteredindexpagesfreeforfutureindexgrowth)防止update带来的行溢出。

    mysql>selecttable_schema,

    ->table_name,ENGINE,

    ->round(DATA_LENGTH/1024/1024+INDEX_LENGTH/1024/1024)total_mb,TABLE_ROWS,

    ->round(DATA_LENGTH/1024/1024)data_mb,round(INDEX_LENGTH/1024/1024)index_mb, round(DATA_FREE/1024/1024)free_mb,round(DATA_FREE/DATA_LENGTH*100,2)free_ratio

    ->frominformation_schema.TABLESwhereTABLE_SCHEMA='test'

    ->andTABLE_NAME='user';

    +--------------+------------+--------+----------+------------+---------+----------+---------+------------+

    |table_schema|table_name|ENGINE|total_mb|TABLE_ROWS|data_mb|index_mb|free_mb|free_ratio|

    +--------------+------------+--------+----------+------------+---------+----------+---------+------------+

    |test|user|InnoDB|4|50000|4|0|6|149.42|

    +--------------+------------+--------+----------+------------+---------+----------+---------+------------+

    1rowinset(0.00sec)

    其中data_free是分配了未使用的字节数,并不能说明完全是碎片空间。

    碎片的回收

    对于InnoDB的表,可以通过以下命令来回收碎片,释放空间,这个是随机读IO操作,会比较耗时,也会阻塞表上正常的DML运行,同时需要占用额外更多的磁盘空间,对于RDS来说,可能会导致磁盘空间瞬间爆满,实例瞬间被锁定,应用无法做DML操作,所以禁止在线上环境去执行。

    #执行InnoDB的碎片回收

    mysql>altertableuserengine=InnoDB;

    QueryOK,0rowsaffected(9.00sec)

    Records:0Duplicates:0Warnings:0

    ##执行完之后,数据文件大小从14MB降低到10M。

    #ls-lh/data2/mysql/test/user1.ibd

    -rw-r-----1mysqlmysql10MNov616:18/data2/mysql/test/user.ibd

    mysql>selecttable_schema,table_name,ENGINE,round(DATA_LENGTH/1024/1024+INDEX_ LENGTH/1024/1024)total_mb,TABLE_ROWS,round(DATA_LENGTH/1024/1024)data_mb,round (INDEX_LENGTH/1024/1024)index_mb,round(DATA_FREE/1024/1024)free_mb,round (DATA_FREE/DATA_LENGTH*100,2)free_ratiofrominformation_schema. TABLESwhereTABLE_SCHEMA='test'andTABLE_NAME='user';

    +--------------+------------+--------+----------+------------+---------+----------+---------+------------+

    |table_schema|table_name|ENGINE|total_mb|TABLE_ROWS|data_mb|index_mb|free_mb|free_ratio|

    +--------------+------------+--------+----------+------------+---------+----------+---------+------------+

    |test|user|InnoDB|5|50000|5|0|2|44.29|

    +--------------+------------+--------+----------+------------+---------+----------+---------+------------+

    1rowinset(0.00sec)

    以上内容由开课吧老师敖丙提供,更多Java教程尽在开课吧广场Java教程频道。

有用
分享
全部评论快来秀出你的观点
登录 后可发表观点…
发表
暂无评论,快来抢沙发!
高并发编程训练营