面试官问:数据库 delete 表数据,磁盘空间还是被一直占用,为什么?
点击关注公众号,Java干货及时送达
牛逼!又发现了一款面试题库,太全了!!
(点击查看)
来源:toutiao.com/i6935264754059477542
明明已经执行了delete,可表文件的大小却没减小,令人费解 Mysql数据结构 表文件大小未更改和mysql设计有关 那怎么才能让表大小变小 Online DDL 总结
为了节约成本,定期进行数据备份,并通过delete删除表记录。
明明已经执行了delete,可表文件的大小却没减小,令人费解
Mysql数据结构
凡是使用过mysql,对B+树肯定是有所耳闻的,MySQL InnoDB 中采用了 B+ 树作为存储数据的结构,也就是常说的索引组织表,并且数据时按照页来存储的。因此在删除数据时,会有两种情况:
表文件大小未更改和mysql设计有关
比如想要删除 R4 这条记录:
InnoDB 直接将 R4 这条记录标记为删除,称为可复用的位置。如果之后要插入 ID 在 300 到 700 间的记录时,就会复用该位置。由此可见,磁盘文件的大小并不会减少。
因此,无论是数据行的删除还是数据页的删除,都是将其标记为删除的状态,用于复用,所以文件并不会减小。
那怎么才能让表大小变小
DELETE只是将数据标识位删除,并没有整理数据文件,当插入新数据后,会再次使用这些被置为删除标识的记录空间,可以使用OPTIMIZE TABLE来回收未使用的空间,并整理数据文件的碎片。
在公众号互联网架构师台回复“2T”,获取一份惊喜礼包。
OPTIMIZE TABLE 表名;
另外,也可以执行通过ALTER TABLE重建表
ALTER TABLE 表名 ENGINE=INNODB
alter table t engine = InnoDB(也就是recreate),而optimize table t 等于recreate+analyze
Online DDL
最后,再说一下Online DDL,dba的日常工作肯定有一项是ddl变更,ddl变更会锁表,这个可以说是dba心中永远的痛,特别是执行ddl变更,导致库上大量线程处于“Waiting for meta data lock”状态的时候。因此在 5.6 版本后引入了 Online DDL。
执行online DDL语句的时候,使用ALGORITHM和LOCK关键字,这两个关键字在我们的DDL语句的最后面,用逗号隔开即可。示例如下:
ALTER TABLE tbl_name ADD COLUMN col_name col_type, ALGORITHM=INPLACE, LOCK=NONE;
INPLACE:替换:直接在原表上面执行DDL的操作。 COPY:复制:使用一种临时表的方式,克隆出一个临时表,在临时表上执行DDL,然后再把数据导入到临时表中,在重命名等。这期间需要多出一倍的磁盘空间来支撑这样的 操作。执行期间,表不允许DML的操作。 DEFAULT:默认方式,有MySQL自己选择,优先使用INPLACE的方式。
SHARE:共享锁,执行DDL的表可以读,但是不可以写。 NONE:没有任何限制,执行DDL的表可读可写。 EXCLUSIVE:排它锁,执行DDL的表不可以读,也不可以写。 DEFAULT:默认值,也就是在DDL语句中不指定LOCK子句的时候使用的默认值。如果指定LOCK的值为DEFAULT,那就是交给MySQL子句去觉得锁还是不锁表。不建议使用,如果你确定你的DDL语句不会锁表,你可以不指定lock或者指定它的值为default,否则建议指定它的锁类型。
OPTIMIZE TABLE 和 ALTER TABLE 表名 ENGINE=INNODB都支持Oline DDL,但依旧建议在业务访问量低的时候使用
总结
如有文章对你有帮助,
欢迎关注❤️、点赞👍、转发📣!
推荐, Java面试题库,详情点击: 牛逼!又发现了一款牛逼的Java面试题库,史上最强! 点击文末“阅读原文”可直达