【问题标题】:Free space in MySQL after deleting tables & columns?删除表和列后 MySQL 中的可用空间?
【发布时间】:2011-05-19 07:51:37
【问题描述】:

我有一个大约 20GB 的数据库。我需要删除 5 个表并在其他 3 个表中删除一些列。

删除 5 个可用大约 3 GB 的表并删除其他表中的列应该再释放 8 GB。

如何从 MySQL 中回收这个空间。

我已阅读转储数据库并将其恢复为解决方案之一,但我不确定它是如何工作的,我什至不确定这是否仅适用于删除整个数据库或仅删除部分数据库?

请建议如何解决这个问题。谢谢。

【问题讨论】:

  • @Gaurav - 一旦表被删除,mysql 也会删除物理文件,从逻辑上讲,磁盘空间是可用的。你的问题/意图是什么?
  • 我不认为是这样,因为我丢弃了一个 1 GB 的表并且我很确定我没有磁盘空间回来?即使我这样做了,你会如何解决这个问题?
  • @Gaurav - 你之前和之后都做了du -shc YOUR_DATABASE_DIRECTORY 吗?您可以使用optimize table 删除列,尽管 mysql 会再次自动处理为表模式更新清理空间
  • @ajreal:也许 Gaurav 没有使用 MyISAM 表? InnoDB 表都在单个文件/块设备上
  • 既然你用的是InnoDB,那么你用的是innodb_file_per_table吗?如果没有,您将无法取回空间,因为它位于共享表空间中。 InnoDB 最终会重用它,但你不会马上取回它。

标签: sql mysql mysqldump


【解决方案1】:

从 cmets 看来,您使用的 InnoDB 似乎没有按表设置文件选项。

在这种模式下,从 innodb 表空间回收空间通常是不可能的。您唯一的做法是转储整个数据库,打开 file-per-table 模式,然后重新加载它(使用完全干净的 mysql 实例)。对于大型数据库,这将需要很长时间; mk-parallel-dump 和恢复工具可能会快一点,但仍需要一段时间。请务必先在非生产服务器上测试此过程。

【讨论】:

  • 一旦打开该选项,任何新表都会得到一个文件。这意味着您可以打开它并一次缓慢地将一个表移动到它自己的文件中(尽管转储/重新加载表),直到完成。如有必要,这将使您可以将停机时间分成许多较小的时间段,而不是一个较大的时间段。
【解决方案2】:

编辑:没有 file_per_table 不适用,Mark 就在那里。

实际情况是,一旦 MySQL 占用了空间,它就不会归还它。这样一来,如果您删除 500 行然后立即插入 500 行,它就不必将该空间还给文件系统然后再请求它。这是一种避免文件系统开销的优化,并且在您删除少量位时效果很好。

如果您删除了大量内容,则需要很长时间才能再次使用所有这些空间,这可能很烦人。这可以通过两种方式解决:删除表格并重新加载内容,或优化表格(我相信这基本上是在内部重新加载表格)。

从表中取回空间所需要做的就是:

OPTIMIZE TABLE my_big_table;

请注意,这可能需要一段时间,而不是近乎即时的操作。基本上,计划一些停机时间。如果你的桌子只是几场演出,它不应该太长(可能几分钟)。这还会重建索引并进行其他一些内务处理。

您可以查看有关优化on the MySQL site 的更多信息。这是它的建议:

如果您删除了表的大部分内容或对具有可变长度行的表(具有 VARCHAR、VARBINARY、BLOB 或 TEXT 列的表)进行了许多更改,则应使用 OPTIMIZE TABLE。删除的行保存在一个链表中,随后的 INSERT 操作重用旧的行位置。您可以使用 OPTIMIZE TABLE 来回收未使用的空间并对数据文件进行碎片整理。

【讨论】:

  • “如果你的桌子只是几场演出,”如果演出你的意思是“Gigas”,你的短语似乎并不准确。我花了 52 分钟来优化 4Go 数据库的每个表 :) 只是对更多访问者说。
  • Mysql 在内部进行了完全重写。另请注意,运行OPTIMIZE TABLE [table]时需要有表的“真实大小”的磁盘空间@
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-15
  • 1970-01-01
  • 1970-01-01
  • 2019-05-13
  • 1970-01-01
相关资源
最近更新 更多