【问题标题】:With InnoDB, how can I claim back index space?使用 InnoDB,我怎样才能收回索引空间?
【发布时间】:2012-07-29 21:49:07
【问题描述】:
我有一些大型 InnoDB 数据库,接近 1TB。
为了在使用备用存储时释放一些空间,我删除了一些未使用的 InnoDB 索引,希望它可以释放一些空间。
它什么也没释放。
由于它是 InnoDB,引擎会使用分配的空空间进行进一步的插入和索引吗?
【问题讨论】:
标签:
mysql
indexing
innodb
diskspace
【解决方案1】:
InnoDB 将数据存储在表空间中。默认情况下,只有一个表空间,所有数据库的数据都存储在一个文件中。该文件中包含数据字典、表和索引。有一个全局参数innodb_data_file_path 定义了这个表空间文件。它的语法类似于ibdata1:256M:autoextend,这意味着在开始时将创建一个大小为 256 MB 的文件,然后每当数据大小超过此大小时,该文件将自动扩展。 innodb_autoextend_increment 变量在 MB 中定义了每个增量应该是多少。
如何获得索引空间?
您应该首先备份所有 InnoDB 表并将 my.ini/my.cnf 中的设置更改为 innodb_file_per_table 并重新启动 MySQL 服务器。
现在导入这些表,现在每个表都有自己的表空间,可以在删除表时缩小大小。
这些是可能的解决方法:
- 每个表单独文件:InnoDB 提供此选项,其中每个表的数据(数据 + 索引)可以通过全局变量 innodb_file_per_table 存储在单独的文件中。
- 固定表空间大小:解决表空间文件大小问题的一种方法是将表空间大小(删除自动扩展)固定为外推值。所以,当你达到极限时,你就知道是时候清理了。
- 移至 MyISAM:对于所有表(甚至数据库),如果您认为数据对于事务等不是那么重要,请将它们移至 MyISAM。
【解决方案2】:
您应该重新组织 InnoDB 基础架构。为什么?因为 ibdata1 从不缩小。在禁用innodb_file_per_table 的情况下,它会迅速膨胀 ibdata1 吗?除了数据和索引,ibdata1 中还有什么?
- 数据字典
- 双写入缓冲区(处理后台页面写入)
- 插入缓冲区(对二级索引进行更改)
- 回滚段
- 撤消表空间
话虽如此,您需要将数据迁移出去,删除所有 InnoDB 中继文件,然后重新加载两件事:
- innodb_file_per_table 已启用
- 更大的事务日志
我在 2010 年 10 月 29 日写了如何做到这一点:Howto: Clean a mysql InnoDB storage engine?
展望未来,您可以缩小单个 InnoDB 表。例如,缩小 mydb.mytable:
ALTER TABLE mydb.mytable ENGINE=InnoDB;
【解决方案3】:
如果您不使用 innodb_file_per_table,则可以回收磁盘空间,但非常乏味,并且需要大量停机时间。
“操作方法”可以在这里找到:http://dev.mysql.com/doc/refman/5.6/en/innodb-data-log-reconfiguration.html
请务必在转储中保留架构的副本。
目前,您无法从系统表空间中删除数据文件。
要减小系统表空间大小,请使用以下过程:
使用 mysqldump 转储所有 InnoDB 表。
停止服务器。
删除所有现有的表空间文件,包括 ibdata 和
ib_log 文件。如果您想保留信息的备份副本,
然后在删除之前将所有 ib* 文件复制到另一个位置
MySQL 安装中的文件。
删除 InnoDB 表的所有 .frm 文件。
配置一个新的表空间。
重启服务器。
导入转储文件。