本文介绍了为什么在删除部分表数据后表文件的大小保持不变,以及如何回收表空间。
[En]
This article describes why the size of the table file remains the same after a part of the table data is deleted, and how to reclaim the tablespaces.
为什么删除表数据后,表文件大小不变
MySQL 采用的是标记删除,需要等待后台 purge 线程删除数据。但是,purge 线程删除数据后,表空间依然不会回收。
对于数据页,删除了几行数据,因为有其他数据,数据页不被回收,空闲的位置被重复使用。即使数据页被清空,数据页也不会被回收,而是被用于重复使用,当需要创建新的数据页时,直接使用可重用的数据页。
[En]
For a data page, several rows of data are deleted because there is other data, the data page is not recycled, and the vacant locations are reused. Even if a data page is emptied, the data page is not recycled, but is also used for reuse, and the reusable data page is used directly when a new data page needs to be created.
我应该如何循环表空间?答案是重建表格。
[En]
How should I recycle the tablespace? The answer is to rebuild the table.
表空间回收方式
重建表推荐使用 ALTER TABLE t ENGINE = InnoDB;
。在不同的 MySQL 版本中,这条语句的执行方式不同。
注意,在重建表的时候,InnoDB 不会把整张表占满,每个页留了 1/16 给后续的更新用。
Copy Table
MySQL5.5 之前采用 Copy Table 方式重建表,Alter 期间,只支持 DML 查询操作,不支持 DML 更新操作,语句为 alter table t engine=innodb, ALGORITHM=copy;
。
1、server 层创建与原表结构相同的临时表
2、根据主键递增顺序,将一行一行的数据读出并写入到临时表,直至全部写入完成
3、互换原表和临时表表名
4、删除临时表
Online DDL
MySQL5.6 开始采用 Inplace 方式重建表,Alter 期间,支持 DML 查询和更新操作,语句为 alter table t engine=innodb, ALGORITHM=inplace;
。之所以支持 DML 更新操作,是因为数据拷贝期间会将 DML 更新操作记录到 Row log 中。
重建过程中最耗时的就是拷贝数据的过程,这个过程中支持 DML 查询和更新操作,对于整个 DDL 来说,锁时间很短,就可以近似认为是 Online DDL。
1、获取 MDL(Meta Data Lock)写锁,innodb 内部创建与原表结构相同的临时文件
2、拷贝数据之前,MDL 写锁退化成 MDL 读锁,支持 DML 更新操作
3、根据主键递增顺序,将一行一行的数据读出并写入到临时文件,直至全部写入完成。并且,会将拷贝期间的 DML 更新操作记录到 Row log 中
4、上锁,再将 Row log 中的数据应用到临时文件
5、互换原表和临时表表名
6、删除临时表
请注意,这两种复制方法都需要额外的存储空间副本,因此当存储空间不足时,重建表会失败。
[En]
Note that both copy methods require an additional copy of storage space, so rebuilding the table fails when there is insufficient storage space.
对于大表的重建,十分消耗 IO 和 CPU 资源。如果是线上服务,为了安全性考虑,建议使用 GitHub 开源的 gh-ost
来做。
Online和Inplace
Inplace 替换,表示在 InnoDB 内部完成了重建过程,不是在 server 层。
Online 采用的就是 Inplace 的重建方式。但是,Inplace 方式并不一定是 Online,比如添加全文索引时 alter table t add FULLTEXT(field_name); 就不是 Online 的,因为它会阻塞 DML 更新操作;而 Online DDL 一定是 Inlpace 方式的。
alter table、analyze table和optimize table解释
alter table t engine = innode;(也就是 recreate)就是 Online DDL 重建表过程;
analyze table t; 不是重建表过程,它只是对索引信息重新统计,会上 MDL 读锁;
optimize table t;是 recreate + analyze 过程。
Original: https://www.cnblogs.com/flowers-bloom/p/mysql45-recycle-table-space.html
Author: flowers-bloom
Title: MySQL45讲之表空间回收
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/508144/
转载文章受原作者版权保护。转载请注明原作者出处!