MySQL InnoDB在从表中删除数据行后没有释放磁盘空间

时间:2009-08-13 09:21:01

标签: mysql innodb delete-row

我有一个使用InnoDB存储引擎的MySQL表;它包含大约2M个数据行。当我从表中删除数据行时,它没有释放分配的磁盘空间。运行optimize table命令后,ibdata1文件的大小也没有减少。

有没有办法从MySQL回收磁盘空间?

我情况很糟糕;这个应用程序在大约50个不同的位置运行,现在几乎所有这些都出现了磁盘空间不足的问题。

9 个答案:

答案 0 :(得分:128)

MySQL不会减小ibdata1的大小。永远。即使您使用optimize table释放已删除记录中使用的空间,它也会在以后重用它。

另一种方法是将服务器配置为使用innodb_file_per_table,但这需要备份,删除数据库和还原。积极的一面是,在optimize table之后,表的.ibd文件会减少。

答案 1 :(得分:34)

我自己也有同样的问题。

发生的情况是,即使您删除数据库,innodb仍然不会释放磁盘空间。我不得不导出,停止mysql,手动删除文件,启动mysql,创建数据库和用户,然后导入。感谢上帝我只有200MB的行,但它没有250GB的innodb文件。

设计失败。

答案 2 :(得分:22)

如果您不使用innodb_file_per_table,则可以回收磁盘空间,但相当繁琐,并且需要大量的停机时间。

How To非常深入 - 但我粘贴了下面的相关部分。

请务必在转储中保留架构的副本。

  

目前,您无法从系统表空间中删除数据文件。   要减小系统表空间大小,请使用以下过程:

     

使用mysqldump转储所有InnoDB表。

     

停止服务器。

     

删除所有现有的表空间文件,包括ibdata和   ib_log文件。如果要保留信息的备份副本,   然后在删除之前将所有ib *文件复制到另一个位置   MySQL安装中的文件。

     

删除InnoDB表的所有.frm文件。

     

配置新的表空间。

     

重启服务器。

     

导入转储文件。

答案 3 :(得分:3)

今天(在最初提出这个问题 11 年后)遇到了这个问题,并且能够通过删除表并重新创建它来修复它。我不必重新安装数据库或转储和还原、修改存储、更改表空间等 - 都没有。

我使用的是 InnoDB 而不是 innodb_file_per_table,所以即使我从表中删除了 900K 行,数据库大小也没有改变。所以我删除了表并重新创建了它。

在我的例子中,我的表被清理为零行,所以我很容易删除表,但保留我运行的结构

create table mynewtable as select * from myoldtable where 1=2;

关注

drop table myoldtable;

这使我的数据库大小从 5G 减少到 400MB

答案 4 :(得分:2)

十年后,我遇到了同样的问题。我通过以下方式解决了该问题:

  • 我优化了所有剩余的数据库。
  • 我在服务(Windows + r-> services.msc)上重新启动了计算机和MySQL

仅此而已:)

答案 5 :(得分:1)

解决空间回收问题的其他方法是,在表中创建多个分区 - 基于范围的,基于值的分区,只需删除/截断分区以回收空间,这将释放存储在其中的整个数据所使用的空间特别划分。

当您为表引入分区时,表模式中需要进行一些更改,例如 - 唯一键,包含分区列的索引等。

答案 6 :(得分:0)

回顾过去,我在mysql5.7版本上也遇到了同样的问题,而ibdata1占用了150 Gb。 所以我添加了撤消表空间

进行Mysqldump备份
停止mysql服务
从数据目录中删除所有数据
在当前my.cnf中的undo tablespace参数下面添加

 #undo tablespace
  innodb_undo_directory =  /var/lib/mysql/
  innodb_rollback_segments = 128 
  innodb_undo_tablespaces = 3
  innodb_undo_logs = 128  
  innodb_max_undo_log_size=1G
  innodb_undo_log_truncate = ON

启动mysql服务
存储mysqldump备份

问题解决了!!

答案 7 :(得分:0)

如果 OPTIMIZE 不能解决您的问题,请尝试:

ALTER TABLE tbl_name ENGINE=INNODB, ALGORITHM=INPLACE, LOCK=NONE;

ALTER TABLE tbl_name FORCE, ALGORITHM=INPLACE, LOCK=NONE;

答案 8 :(得分:-1)

从MySQL Inodb引擎的表中删除数据后,有几种方法可以回收磁盘空间

如果你不从头开始使用innodb_file_per_table,那么转储所有数据,删除所有文件,重新创建数据库并再次导入数据只是方法(检查上面FlipMcF的答案)

如果您使用的是innodb_file_per_table,可以尝试

  1. 如果可以删除所有数据truncate命令将删除数据并为您回收磁盘空间。
  2. Alter table命令将删除并重新创建表,以便它可以回收磁盘空间。因此,在删除数据后,运行alter table,不更改任何内容以释放硬盘(即:表TBL_A具有charset uf8,删除数据后运行ALTER TABLE TBL_A charset utf8 - >此命令不会从您的表中更改任何内容但它会使mysql重新创建您的表并且重获磁盘空间
  3. 像TBL_A一样创建TBL_B。将要保留的选择数据从TBL_A插入TBL_B。删除TBL_A,并将TBL_B重命名为TBL_A。如果TBL_A和需要删除的数据很大(MySQL innodb中的删除命令性能非常差),这种方式非常有效。