我找到的最短路径是:
ALTER TABLE YOURTABLE ENGINE=InnoDB
在截断或删除不需要的记录后,我运行了这个并且表空间缩小了。
Here is a nice article by Shlomi Noach, where I found (this and more information about) this.
感谢 Shlomi Noach。希望能帮助到你。以防万一我也将其粘贴在这里:
使用 InnoDB 时,您有两种管理表空间存储的方法:
将所有内容放入一个大文件中(可选择拆分)。
每张桌子有一个文件。
我将讨论这两个选项的优缺点,并努力说服 innodb_file_per_table 更可取。
单个表空间
将所有内容都放在一个大文件中意味着所有方案中的所有表和索引都在该文件中“混合”在一起。
这允许以下很好的属性:可用空间可以在不同的表和不同的方案之间共享。因此,如果我从日志表中清除许多行,那么现在未使用的空间可能会被任何其他表的新行占用。
同样好的属性也转化为一个不太好的属性:数据可能在表空间中非常分散。
InnoDB 表空间的一个恼人属性是它们从不收缩。所以在从日志表中清除这些行之后,表空间文件(通常是 ibdata1)仍然保持相同的存储。它不会向文件系统释放存储空间。
我不止一次地看到某些表是如何无人看管的,直到磁盘空间达到 90% 并且 SMS 通知开始四处响起。
在这种情况下几乎没有什么可做的。好吧,人们总是可以清除行。当然,这个空间会被 InnoDB 重用。但是拥有一个占用大约 80-90% 磁盘空间的文件是性能灾难。这意味着圆盘针需要移动很远的距离。整体磁盘性能非常低。
解决此问题的最佳方法是设置一个新的从属设备(在清除行之后),并将数据转储到该从属设备中。
InnoDB 热备份
有趣的是,ibbackup 实用程序会照原样复制表空间文件。如果是 120GB,其中仅使用了 30GB,您仍然会得到 120GB 的备份和恢复。
mysqldump,mk-parallel-dump
如果您只有原始机器可以使用,mysqldump 将是您的最佳选择。假设您只使用 InnoDB,使用 --single-transaction 的转储将完成这项工作。或者您可以使用 mk-parallel-dump 来加快速度(取决于您的转储方法和可访问性需求,注意锁定)。
innodb_file_per_table
使用此参数集,将为每个表创建一个 .ibd 文件。我们得到的是这样的:
表空间在不同的表之间不共享,当然也不在不同的方案之间。
每个文件都被视为自己的一个表空间。
同样,表空间的大小永远不会减少。
可以重新获得每个表空间的空间。
等待。最后两个似乎矛盾,不是吗?让我们解释一下。
在我们的日志表示例中,我们清除了许多行(最多删除了 90GB 的数据)。 .ibd 文件不会缩小。但我们可以这样做:
ALTER TABLE 日志引擎=InnoDB
将发生的情况是创建一个新的临时文件,并在其中重建表。只有现有数据会添加到新表中。完成后,原表被删除,新表重命名为原表。
当然,这需要很长时间,在此期间表被完全锁定:不允许写入和读取。但仍然 - 它允许我们重新获得磁盘空间。
使用新的 InnoDB 插件,在执行 TRUNCATE TABLE 日志语句时也会重新获得磁盘空间。
碎片并不像在单个表空间中那样糟糕:数据被限制在较小文件的边界内。
监控
关于 innodb_file_per_table 的另一个好处是可以在文件系统级别监控表大小。您不需要访问 MySQL、使用 SHOW TABLE STATUS 或查询 INFORMATION_SCHEMA。您可以在 MySQL 数据目录(和子目录)下查找前 10 个最大的文件,并监控它们的大小。您可以查看哪个表增长最快。
备份
最后,目前还不能通过复制 .ibd 文件来备份单个 InnoDB 表。但希望能朝着这个方向努力。