禁用 innodb_file_per_table 时优化 innodb 表

Posted

技术标签:

【中文标题】禁用 innodb_file_per_table 时优化 innodb 表【英文标题】:Optimize innodb table when innodb_file_per_table disable 【发布时间】:2015-11-25 21:54:40 【问题描述】:

我正在使用 innodb。我的应用程序性能有问题。当我运行mysqlturner.pl 时,我得到:

[--] InnoDB 表中的数据:8G(表:1890) [!!] 碎片表总数:1890

好的,我已经运行了 mysqlcheck -p --optimize db。 我已经禁用了 innodb_file_per_table 。过去 2 年没有重新索引数据库。我该怎么做?

    制作mysqldump? 停止mysql服务? 将启用 innodb_file_per_table 插入到 my.cnf 中? 启动mysql服务? 从 mysqldump 导入? 运行 mysqlcheck -p --optimize db?

一切都会好吗?

【问题讨论】:

很确定您需要在转储之后但在恢复之前删除表;并且很确定共享的 ibdata 不会缩小。 如何确定共享的 ibdata 不会缩小? 我已经有几年没有深入研究细节了,但最后我记得缩小主要ibdata1 文件的唯一受支持的方法是备份您的数据,卸载并重新安装 MySQL 服务器,然后恢复。 【参考方案1】:

表格碎片化

假的。

所有 InnoDB 表总是(根据该工具)碎片化。

实际上,1000 个表中只有 1 个需要进行碎片整理。

OPTIMIZE TABLE foo; 将对单个表进行碎片整理。但是,我再说一遍,“不要打扰”。

ibdata1 臃肿

另一方面...如果您担心 ibdata1 的大小 并且 Data_free (SHOW TABLE STATUS) 表明 ibdata1 的大块是“免费的”,那么唯一的解决方法是痛苦的:如前所述:转储、停止、删除 ibdata1、重新启动、重新加载。

但是...如果您没有足够的磁盘空间来转储所有内容,那么您将陷入困境。

您有 8GB 的​​表? (对所有 InnoDB 表求和 Data_length 和 Index_length。)如果 ibdata1 是 10GB,请不要打扰。如果它是 100GB,那么你有很多浪费的空间。但是,如果您没有用完磁盘空间,我再说一遍“不要打扰”。

如果您的磁盘空间不足并且 ibdata1 似乎有很多“空闲”,然后进行转储等。但另外:如果您有 1890 个表,可能大多数都是“小” .也许有几个有点大?也许某些表的大小波动很大(例如,添加一百万行,然后删除其中大部分)?我建议在创建大表或波动表时将 innodb_file_per_table 设为 ON;小表关闭。

小表在 ibdata1 中占用的空间更少;如果需要,可以通过OPTIMIZE if 清理大/波动表。

【讨论】:

【参考方案2】:

是的,可以。在开始之前进行备份,并首先在主机副本上测试整个过程,尤其是。确切的 mysqldump 命令,您不希望转储中出现像“information_schema”这样的数据库。

同时确保其他服务在您开始导出后无法连接到您的数据库 - 它们更改的任何数据都将在导入期间丢失。

上一题有详细说明: Howto: Clean a mysql InnoDB storage engine?

【讨论】:

碎片表是唯一的方法(innodb enable per table)吗?

以上是关于禁用 innodb_file_per_table 时优化 innodb 表的主要内容,如果未能解决你的问题,请参考以下文章

MySQL单独存放表空间Innodb_file_per_table

innodb_file_per_table 理解

如何将现有数据库的“innodb_file_per_table”参数从“OFF”更改为“1”?

InnoDB 引擎独立表空间 innodb_file_per_table

innodb_file_per_table - 转换为InnoDB

使用参数innodb_file_per_table支持MySQL InnoDB表数据共享空间自动收缩