《MYSQL实战45讲》表数据删一半,为什么表文件大小不变?

参数innodb_file_per_table

这个参数设置为ON,表示每个表数据单独存在一个文件中,这时如果执行drop命令,系统会直接删除表文件。

这个参数设置为off时,所有表的数据和索引都存在共享的.ibdata文件,即使表删掉了,磁盘空间也不会回收,而是将表数据标记为可复用。

系统表空间

所有表的数据和索引都存储在共享的.ibdata文件

数据删除其实是标记为可复用

每个b+数的叶子节点是一个数据页,一个数据页包含很多条记录,一条记录被删除时,仅仅是这个记录的位置被标记为可复用,不管是主键索引还是二级索引,数据都是按照索引的顺序排好的,当一条记录被标记为可复用时,当有一条记录可以插在这个被复用的位置上时,就直接复用了这个位置,但是如果这条记录不能插在这个位置上就不能复用,比如一个主键索引树上,一个数据页有R1(100,数据),R2(200,数据),R3(300,数据),当R2被删除标记为可复用时,有个记录为100~300之间的都能复用这个位置,但是超过这个范围的就不行了。

当一个数据页都被标记为可复用时,就没有范围了,当需要新开辟一个数据页时,直接复用这个数据页。

所以,即使我们使用delete删除一个表的所有记录,磁盘文件也是不会减小的,而是都标记成可复用。

而这些可以复用但是没被复用的空间就是空洞。

删除数据会产生空洞,插入数据也会

在数据页内的数据很紧凑的情况下(不是100,200,300而是1,2,3,4,5这种)

假如一个数据页A已经满了,这时再插入一个比较靠后的位置,就会把这个新数据和数据页A后面的记录放在另一个新申请的数据页中。这就导致了A后面的记录变成空洞。

更新索引上 的值是先删除一个旧的值,再插入一个新的值

这也会产生空洞

通过重建表来收缩表空间,填补空洞

使用alter table A engine=InnoDB命令来重建表

(MYSQL5.5之前,默认的隐含意思是alter table t engine=innodb,ALGORITHM=copy)

MYSQL5.5之前,这条语句的执行逻辑是这样的:

首先创建一个临时表B,再将A中的数据一条一条按照顺序读写到表B中

这时B中数据是按照顺序插入的,没有空洞。

最后将A和B互换(重命名),删除表B。完成表A的重建

Online DDL

在上面这个流程中,最耗时的就是拷贝数据这个部分了,这个过程中如果写数据到A中,就会造成数据丢失。

Online DDL: 在对表结构进行更改时(执行DDL语句),同时支持对表数据进行增删改查。

此时重建表的逻辑就变成了

(MYSQL5.5之后,默认的隐含意思是alter table t engine=innodb,ALGORITHM=inplace)

首先创建临时文件B,在拷贝数据到临时文件B期间,将对表A的数据增删改查记录到一个日志文件row log中。

在拷贝完成后,将日志文件对表A数据的更改应用到临时文件B中,这样临时文件B中的数据旧和是一样的了

最后用临时文件B替换表A的数据文件

注意到这里和MYsql5.5之前有个不同的点是,之前的B是创建的表,是在server创建的,而这里是创建的临时文件,是在innodb内部创建的。对于server来说没有将表A的数据迁移到其他表,因为inno代办对其数据文件进行了更换。是在 原表上直接进行DDL操作,所以这种方式叫做inplace

DML写锁退化成读锁

这个流程中,在Alter 语句启动时会获取DML元数据写锁,防止其他线程来对这个进行结构的更改,同时DML写锁会阻塞数据的增删改查操作,但是读锁不会。所以在进行拷贝数据时,DML写锁会退化成DML读锁,DML读锁只会阻塞DML写锁,但是不会阻塞增删改查。

Online和inplace

DDL过程如果是Online的,就一定是inplace的

原因

因为Online DDl依赖于inplace算法,在重建表时,如果是使用的COPY模式,那就会创建新的表来作为临时中间表,这会阻塞增删改查,而inplace可以不创建新的表,仅仅是创建临时文件。

并且inplace在对DML写锁的持有上进行了优化,在进行拷贝数据到临时文件时就退化成读锁了。

但是一个DDL是inplace的,就不一定是Online的

原因

Online DDL指的是在进行DDL时不阻塞DML(数据的增删改查)。

即使是inplace地添加全文索引和添加空间索引时(在原表上创建索引而不创建临时表),仍然不能进行DML操作。

相关推荐
恒拓高科WorkPlus18 分钟前
企业统一门户-BeeWorks安全的企业数字化办公门户
1024程序员节
阿波罗尼亚26 分钟前
REST 表征状态转移
1024程序员节
wangchenggong19881 小时前
solidity中的函数总结
区块链·1024程序员节
冻咸鱼1 小时前
MySQL基础知识大全
数据库·mysql·oracle
“抚琴”的人3 小时前
C# 取消机制(CancellationTokenSource/CancellationToken)
开发语言·c#·wpf·1024程序员节·取消机制
介一安全3 小时前
【Frida Android】基础篇12:Native层hook基础——调用原生函数
android·网络安全·逆向·安全性测试·frida·1024程序员节
Cathyqiii4 小时前
Diffusion-TS:一种基于季节性-趋势分解与重构引导的可解释时间序列扩散模型
人工智能·神经网络·1024程序员节
存储国产化前线4 小时前
从浪涌防护到系统可控,天硕工业级SSD重构工业存储安全体系
ssd·固态硬盘·1024程序员节·工业级固态硬盘
瑞禧生物ruixibio4 小时前
4-ARM-PEG-Alkene(2)/Biotin(2),四臂聚乙二醇-烯烃/生物素多功能支链分子
1024程序员节
焦点链创研究所4 小时前
BUYCOIN:以社区共治重构加密交易版图,定义交易所3.0时代
1024程序员节