前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL之重建表

MySQL之重建表

作者头像
AsiaYe
发布2020-07-01 15:01:16
4.1K0
发布2020-07-01 15:01:16
举报
文章被收录于专栏:DBA随笔DBA随笔

MySQL之重建表

在MySQL中,如果我们对大表频繁进行insert和delete操作,那么时间一长,这个表中会出现很多"空洞",也就是表碎片。

碎片产生的原因是insert随机值作为主键id,会产生很多数据页分裂操作;而delete掉一些排列有序的主键值,这些被delete的空间不会直接释放,而是仅仅进行delete的标记,这些空间如果不能被利用,那就会变成"空洞"。

在这种情况下,往往需要对表进行重建,从而释放这些空余的空间,让数据变得"紧凑些",如下:

这个重建表的过程,在MySQL5.5之前,它的执行逻辑是下面这样的:

1、假设原表是A,新建一个表table B,和表A的表结构保持一致

2、按照主键顺序,将表A的数据一行一行的读出来,插入到表B里面

3、交换表A和表B的名称

当我们执行alter table A engine=Innodb的时候,就会执行我们上述描述的三个动作。

在MySQL5.6及以后的版本里面,引入了Online DDL的方法,Online DDL的引入,使得上面的过程有了一点点不同,当执行alter table A engine=Innodb的时候,MySQL的内部动作如下:

1、建立临时文件file A,扫描表A主键的所有数据页,注意,这里不是临时表,而是临时文件;

2、用数据页中表A的记录生成B+树,然后存储到临时文件中去

3、在生成临时文件的过程中,使用另一个log文件,将对表A的所有DML操作,记录到log文件中,改文件大小由参数控制:

代码语言:javascript
复制
mysql> show variables like "%online%";
+----------------------------------+-----------+
| Variable_name                    | Value     |
+----------------------------------+-----------+
| innodb_online_alter_log_max_size | 134217728 |
+----------------------------------+-----------+
1 row in set, 1 warning (0.01 sec)

4、临时文件file A生成之后,将log中对表A的操作应用到临时文件中,

5、用临时文件替换表A的数据文件

这个重建的过程中,允许对表A做增删改查的操作,所以称之为Online DDL。

这里需要注意一点,因为Online DDL需要在DDL的过程中支持表的增删改查操作,所以Online DDL一开始会获取MDL写锁,但是在数据文件开始拷贝之前,就退化成MDL读锁了。

现在我们来说下第一点里面强调的临时文件file A.

在MySQL5.5之前,我们使用临时表作为重建的中间介质,在MySQL5.6之后,我们使用临时文件作为重建的中间介质,这里说说这个临时表和临时文件的区别。

临时表是创建在server层面的,临时文件是创建在innodb层面的,所以Online DDL的整个过程都是在Innodb内部完成的,这种方法也称之为"inplace",相对应的,需要借助server层面临时表的过程,称之为"Copy"。

我们在阅读Online DDL一节的官方文档的时候,看到的copy和inplace也就是这个意思。详情可参见官方文档:

https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl.html

几个小问题:

1、假设我们有一个1TB的表,磁盘只有1.2TB,那么还可以做inplace的DDL呢?

答案:不可以,因为inplace方案中的临时文件也要占用一定的空间。

2、inplace方案进行的表重建操作,都是Online DDL么?

答案:不是,有些操作是inplace的,也就是在innodb层面进行的,但是却不是online的,例如增加全文索引的操作,这个操作是inplace的,但是会阻塞增删改查操作,因此不是Online DDL,只能说:Online DDL一定是inplace的,但是inplace方案进行的操作,不一定是Online的。

3、加入某个表的大小是1TB,进行alter table A engine=Innodb之后,表的空间没有缩小,反而增大了一点,这是为什么?

答案:可能是因为表之前刚刚进行过一次alter table的操作,而且表上面的并发增删改比较多,在进行alter table的过程中,这些操作都写进了log中,从而导致表的实际大小增加。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DBA随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MySQL之重建表
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档