我有一个使用InnoDB存储引擎的MySQL表;它包含大约2M个数据行。当我从表中删除数据行时,它没有释放分配的磁盘空间。运行optimize table
命令后,ibdata1文件的大小也没有减少。
有没有办法从MySQL回收磁盘空间?
我情况很糟糕;这个应用程序在大约50个不同的位置运行,现在几乎所有这些都出现了磁盘空间不足的问题。
答案 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)
十年后,我遇到了同样的问题。我通过以下方式解决了该问题:
仅此而已:)
答案 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,可以尝试