最近听说一个事情,就是MYSQL 在删除大部分数据后,数据表的表空间会进行收缩,将系统的表空间释放给操作系统。根据对多种数据库的了解,自动释放这个事情我是存疑的,所以做了如下的测试,来进行相关的证明。
我们的表如下,
此表为顺序型的表,整体数据只有插入,里面没有任何的UPDATE 或DELETE的痕迹,是一个新表,删除的时候,我们从前面删除,一次,在从后面删除一次。
delete from app_user where id < 10999999;
delete from app_user where id > 10000000;
最后我们将表整体的记录都删除,在看看是否空间收缩
为什么这样删除,主要的原因是,这样删除后证明两点,在大量删除表中的数据,前删,或后删,后的表是否会收缩
在删除前我们针对这个表的大小进行记录
我们对于数据库服务器,进行了SNAPSHOT ,每次删除后,我们在看结果后,会再次还原数据库,在做相关的测试。
在删除后,我们根据结果,数据空间丝毫没有变化。
在此从尾部删除数据后,空间依然没有释放给磁盘空间
最后我们将数据都删光,看看是否会能释放空间。
结果还是没有变化。
所以无论你删除多少数据,数据表都不会收缩空间。但是为什么会产生这个传说,主要还是下面的这篇文字,关于MYSQL 的page merge 的问题,这点的确可以好好得看看。
InnoDB Page Merging and Page Splitting (percona.com)
https://www.percona.com/blog/innodb-page-merging-and-page-splitting/
extent只能存在于段内,其固定尺寸为1MB(默认页面大小为此情况下)。页面是extent的子元素,其默认大小为16KB。
因此,一个extent最多可以包含64个页面。一个页面可以包含2到N个行。页面可以容纳的行数与行的大小有关,其由您的表结构定义。InnoDB中有一个规则,它规定至少要容纳两行到页面中。因此,我们有一个行大小限制为8000字节。
这里在MYSQL 中会牵扯删除数据的后的PAGE MERGE 部分,其中当你删除一条记录时,它并不会被物理删除。相反,它被标记为已删除,它所占用的空间变得可回收。
当一页接收到足够的删除操作以匹配 MERGE_THRESHOLD(默认为页面大小的50%)时,InnoDB开始查找最近的页面(下一个和前一个)以查看是否有机会通过合并这两个页面来优化空间利用率。当页面的删除的空间达到50%以上,则可以针对两个类似连贯的页面进行合并。当一个记录被更新且它的大小使得页面的利用率低于阈值时,同样的过程也会发生。规则是:当涉及相邻链接的页面的删除和更新操作时,合并操作将发生。如果合并成功,INFORMATION_SCHEMA.INNODB_METRICS中的index_page_merge_successful度量值将增加。
也就是index_page_merge_successful 的数值增加不光有DELETE的情况下,在数据UPDATE 将数据值长度改小后,也可能发生页合并。
并且在发生页合并的情况下,还需要关注主键,如果主键不是自增的情况下,发生页合并的可能性要比自增为主机的发生业合并的可能性要大。
写到最后,实际上发生页合并对于mysql来说利弊 50/50, 发生页合并要牺牲数据库在合并时的性能,但对于空间再次利用来说,对于数据库是一件好事,因为可以有更多的空余的页面可以被使用。
本文分享自 AustinDatabases 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!