为啥mysql不回收ibd文件中的可用空间?

Posted

技术标签:

【中文标题】为啥mysql不回收ibd文件中的可用空间?【英文标题】:why mysql does not reclaim free space in ibd file?为什么mysql不回收ibd文件中的可用空间? 【发布时间】:2020-08-22 07:32:20 【问题描述】:

我正在使用 mysql5,我想缩小 ibd 文件中的一些“已删除”空格。我已经搜索了“优化表”选项,但我现在不能使用它,因为它是一个非常关键的表。它在 Mysql 中使用 19G,但在 OS 中使用 33G。我只是发现33G正在增加。

听说它在 33G 空间中重复使用,比如黑色区域。但是为什么每天都在增加呢?

MySQL 不重用这些空闲空间?我的意思是,大约 24G 永远不会被重复使用?

感谢您的阅读,希望我的英语水平不会让您在阅读时感到困惑。

【问题讨论】:

哪个mysql版本?你有 innnodb_file_per_table 设置吗?它每天增加多少(空间和行)?重用应该发生。 33G只是关键表的ibd文件大小吗? 这不是真正的问题。首先,您应该在问题中指出这是按表设置还是共享表空间。如果不使用 Innodb_file_per_table 你就不走运了。默认值通常是共享的,所以所有的 innodb 表都在一个 IBD 中。如果你使用 Innodb_file_per_table 那么你就有机会恢复空间。您还应该研究 Percona 的 pt-online-schema 作为优化写入锁定的可能解决方法。 感谢您的回复。很抱歉我没有写下具体的版本和设置。 innnodb_file_per_table 为 ON。和 pt-online-schema 是不错的选择,但我的老板不能信任这个工具..因为这不是正式的.. :( 我的版本是 Distrib 5.0.95 Percona 工具包在开源世界中与它一样正式。就仍在运行 MySQL 5.0 而言,您遇到的问题要大得多,这已被弃用,并且多年来没有任何错误和安全修复。 【参考方案1】:

表格的有效部分分散在.ibd 中。文件。操作系统没有办法重用表格中间释放的部分。

因此,InnoDB 永远不会缩小表空间,只会扩大它。

同时,新的INSERTs 将填充一些释放的空间。

是什么导致了这种情况?你DELETE 很多行吗?如果您希望再做一个大的DELETE,下次请参阅以下建议:http://mysql.rjweb.org/doc.php/deletebig

同时,如果该表是使用innodb_file_per_table = 1 创建的,那么OPTIMIZE TABLE 将复制该表并将旧副本释放到操作系统。但是...您需要额外的磁盘空间来完成这项任务。它会阻止对表的一些操作。 (具体取决于您使用的 MySQL/MariaDB 版本。)

为什么需要收回空间?如果您没有磁盘空间不足,那么这真的很重要吗?

空间不足?

告诉我们SHOW CREATE TABLE。可能有一些使桌子变小的技巧。 (这并不能解决问题,但会延迟将来的问题。)例如,如果可以将 INT(4 个字节)更改为 SMALLINT(2 个字节),这可能有助于缩小表。或者INDEX 可能是多余的; DROPping 会有帮助的。

ALTER 更改此类内容可能会同时执行OPTIMIZE。 (在 MySQL 5.0 中,几乎所有的ALTERs 都是通过复制表来执行的。)

磁盘空间非常紧张时的另一个提示...(假设 innodb_file_per_table 一直打开):OPTIMIZE 较小的表;其中一些可能会缩小一点,从而为您提供一些额外的磁盘空间。

另一个提示:

    确定哪些表位于它们自己的表空间中。 找出ibdata1 中有多少可用空间。 SET innodb_file_per_table=OFF; ALTER TABLE t ENGINE=InnoDB; 对于一些小表是第 1 步。但在 ibdata1 的 Data_free 降得太小之前停止。

该提示将为那些可以移动而不会导致 ibdata1 增长的表释放空间。

【讨论】:

感谢您的回复。磁盘快满了。 DB根空间占总空间的93%。所以我需要将ibd文件33G缩小到19G。我需要多少空间进行优化?只是复制19G进行优化吗?我们删除了一堆 19G 的行。但是os容量还是占了33G。每天大约有 100,000 行插入。它从 24m 增加到 40m。我不确定我们之前删除了多少行。 您将需要额外的 19GB 空间来执行 OPTIMIZE。 (这个数字是近似值。) @HyeongwooPark - 我添加了一些提示。如需更多讨论,请提供SHOW TABLE STATUS; 名称:tableSample /Engine: InnoDB /Version: 10 /Rows: 54252075 /Avg_row_length: 215 /Data_length: 11683250176 /Index_length: 8881471488 /Data_free: 6291456 这是我要修复的。 @HyeongwooPark - 你有多少可用磁盘空间?即使小于 19GB,OPTIMIZE 也可能成功。如果它失败了,(或挂起,然后你杀死它),不应该造成任何伤害。【参考方案2】:

您正在寻找的选项是innodb_use_trim=1,结合innodb_file_per_table=1,如果您使用的MySQL 版本足够新,可以拥有它。这将通过在表空间文件中打孔来释放空页。

【讨论】:

忘记“修剪”:引入:MariaDB 10.1.0、MariaDB 10.0.15 Fusion-io 已弃用:MariaDB 10.2.4 已删除:MariaDB 10.3.0。反正它只适用于COMPRESS OP 说他们使用的是 MySQL 5。innodb_use_trim 在 MariaDB 10.3+ 中始终处于开启状态。

以上是关于为啥mysql不回收ibd文件中的可用空间?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL借助ibd文件恢复数据技巧?

为啥回收站自动清空?

mysql ibd是啥文件

MYSQL .ibd文件数据恢复

MySQL 8.0 恢复孤立文件每表ibd文件

mysql数据库被破坏,只剩下ibd文件时如何恢复