MySql - 清理 ibdata1

Ran*_*Ran 4 mysql innodb ibdata

我有一个数据库,其整个大小约为 44GB,其中 ibdata1 约为 35GB。这没有意义,因为数据的大小不应超过 10GB。

我使用以下查询来估计数据大小:

    SELECT CONCAT(table_schema, '.', table_name),
       CONCAT(ROUND(table_rows / 1000000, 2), 'M')                                    rows,
       CONCAT(ROUND(data_length / ( 1024 * 1024 * 1024 ), 2), 'G')                    DATA,
       CONCAT(ROUND(index_length / ( 1024 * 1024 * 1024 ), 2), 'G')                   idx,
       CONCAT(ROUND(( data_length + index_length ) / ( 1024 * 1024 * 1024 ), 2), 'G') total_size,
       ROUND(index_length / data_length, 2)                                           idxfrac
FROM   information_schema.TABLES
ORDER  BY data_length + index_length DESC
LIMIT  30;
Run Code Online (Sandbox Code Playgroud)

任何想法如何清理 ibdata1 以及它为什么增长这么多?

顺便说一句,我使用 innodb_file_per_table

Rol*_*DBA 13

安德烈亚斯首先在做什么方面得到了这个答案。为安德烈亚斯 +1 !!!

我想澄清为什么这个答案是唯一的方法以及如何去做。

默认情况下 ibdata1 通常包含四种类型的信息

  • 表格数据
  • 表索引
  • MVCC(多版本并发控制)数据
  • 表元数据

对存储 ibdata1 的 InnoDB 表运行 OPTIMIZE TABLE 会使事情变得更糟,因为它的作用如下:

  • 使表的数据和索引在 ibdata1 中连续
  • 它使 ibdata1 增长,因为连续数据附加到 ibdata1

您可以从 ibdata1 中分离表数据和表索引,并使用innodb_file_per_table独立管理它们。这样,只有 MVCC 和 Table MetaData 会驻留在 ibdata1 中。

如果你已经在使用它,那么你必须有一个存储大量MVCC的高写环境来支持事务隔离。一旦持有 MVCC 的交易完成,空间就会被简单地放弃以供重用。

要一劳永逸地缩小 ibdata1,您必须执行以下操作:

STEP 01) MySQLDump 所有数据库到一个 SQL 文本文件中(称之为 SQLData.sql)

STEP 02) 删除所有数据库(mysql 模式除外)

步骤 03) service mysql stop

步骤 04) 将以下行添加到 /etc/my.cnf

[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
Run Code Online (Sandbox Code Playgroud)

旁注:无论您为 innodb_buffer_pool_size 设置什么,请确保 innodb_log_file_size 是 innodb_buffer_pool_size 的 25%。

步骤 05) rm -f /var/lib/mysql/ibdata1 /var/lib/mysql/ib_logfile

此时,/var/lib/mysql中应该只有mysql模式

步骤 06) service mysql start

这将分别以 10MB、ib_logfile0 和 ib_logfile1 分别以 1G 的速度重新创建 ibdata1

步骤 07) 将 SQLData.sql 重新加载到 mysql

ibdata1 会增长但只包含表元数据

每个 InnoDB 表都将存在于 ibdata1 之外

假设您有一个名为 mydb.mytable 的 InnoDB 表。如果你进入/var/lib/mysql/mydb,你会看到两个代表表的文件

  • mytable.frm(存储引擎标题)
  • mytable.ibd(mydb.mytable 的表数据和表索引的主页)

ibdata1 将不再包含 InnoDB 数据和索引。

使用 /etc/my.cnf 中的 innodb_file_per_table 选项,您可以运行OPTIMIZE TABLE mydb.mytable;并且文件 /var/lib/mysql/mydb/mytable.ibd 实际上会缩小。

我想建议一个公式,供您查询 InnoDB 缓冲池大小的问题,请参阅在 InnoDB 和 MyISAM 之间的主要区别是什么?