这是关于 InnoDB 的更完整的答案。这是一个漫长的过程,但值得付出努力。
请记住,/var/lib/mysql/ibdata1 是 InnoDB 基础架构中最繁忙的文件。它通常包含六种类型的信息:
InnoDB 架构
许多人创建多个 ibdata 文件希望获得更好的磁盘空间管理和性能,但这种想法是错误的。
不幸的是,对存储在共享表空间文件 ibdata1 中的 InnoDB 表运行 OPTIMIZE TABLE 会做两件事:
- 使表的数据和索引在
ibdata1 内连续
- 使
ibdata1 增长,因为连续的数据和索引页面被附加到ibdata1
但是,您可以将表数据和表索引从 ibdata1 中分离出来并独立管理它们。
假设您要将innodb_file_per_table 添加到/etc/my.cnf (my.ini)。然后你可以在所有 InnoDB 表上运行OPTIMIZE TABLE 吗?
好消息:当您在启用innodb_file_per_table 的情况下运行OPTIMIZE TABLE 时,将为该表生成一个.ibd 文件。例如,如果您的表 mydb.mytable 的数据目录为 /var/lib/mysql,它将生成以下内容:
/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
.ibd 将包含该表的数据页和索引页。太好了。
坏消息:您所做的只是从ibdata 中提取mydb.mytable 的数据页和索引页。每个表的数据字典条目,包括mydb.mytable,仍保留在数据字典中(请参阅Pictorial Representation of ibdata1)。 此时您不能简单地删除 ibdata1 !!! 请注意,ibdata1 根本没有缩小。
InnoDB 基础架构清理
要一劳永逸地缩小ibdata1,您必须执行以下操作:
将所有数据库转储(例如,使用mysqldump)到.sql 文本文件(下面使用SQLData.sql)
-
删除所有数据库(mysql 和 information_schema 除外)CAVEAT:作为预防措施,请运行此脚本以确保您已获得所有用户授权:
mkdir /var/lib/mysql_grants
cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/.
chown -R mysql:mysql /var/lib/mysql_grants
登录 mysql 并运行 SET GLOBAL innodb_fast_shutdown = 0;(这将完全清除来自 ib_logfile0 和 ib_logfile1 的所有剩余事务更改)
关闭 MySQL
-
将以下行添加到 /etc/my.cnf(或 Windows 上的 my.ini)
[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
(旁注:无论您为innodb_buffer_pool_size 设置什么,确保innodb_log_file_size 是innodb_buffer_pool_size 的25%。
另外:innodb_flush_method=O_DIRECT 在 Windows 上不可用)
删除ibdata*和ib_logfile*,您可以选择删除/var/lib/mysql中的所有文件夹,/var/lib/mysql/mysql除外。
启动 MySQL(这将重新创建 ibdata1 [默认为 10MB] 和 ib_logfile0 和 ib_logfile1,每个 1G)。
导入SQLData.sql
现在,ibdata1 仍将增长,但仅包含表元数据,因为每个 InnoDB 表都将存在于 ibdata1 之外。 ibdata1 将不再包含其他表的 InnoDB 数据和索引。
例如,假设您有一个名为 mydb.mytable 的 InnoDB 表。如果您查看/var/lib/mysql/mydb,您将看到代表该表的两个文件:
-
mytable.frm(存储引擎标头)
-
mytable.ibd(表数据和索引)
使用/etc/my.cnf 中的innodb_file_per_table 选项,您可以运行OPTIMIZE TABLE mydb.mytable,文件/var/lib/mysql/mydb/mytable.ibd 将实际缩小。
在我作为 MySQL DBA 的职业生涯中,我已经多次这样做了。事实上,我第一次这样做时,我将 50GB ibdata1 文件缩小到只有 500MB!
试一试。如果您对此还有其他问题,请提出。相信我;这将在短期和长期有效。
警告
在第 6 步,如果由于 mysql 架构开始删除而导致 mysql 无法重新启动,请回顾第 2 步。您制作了 mysql 架构的物理副本。您可以按如下方式恢复它:
mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql
返回第 6 步并继续
更新 2013-06-04 11:13 EDT
关于在第 5 步中将 innodb_log_file_size 设置为 innodb_buffer_pool_size 的 25%,这是一个相当老套的规则。
回到July 03, 2006,Percona 有一篇很好的文章why to choose a proper innodb_log_file_size。后来,在Nov 21, 2008,Percona 又在how to calculate the proper size based on peak workload keeping one hour's worth of changes 上跟进了另一篇文章。
我已经在 DBA StackExchange 上写过关于计算日志大小以及我在哪里引用了那两篇 Percona 文章的帖子。
就个人而言,我仍然会使用 25% 的规则进行初始设置。然后,随着生产时间的推移,可以更准确地确定工作负载,you could resize the logs 在维护周期内只需几分钟。