MySQL-更改实时数据库的innodb_file_per_table


18

我有一个大型的MySql数据库(150GB),只是现在我才注意到,将innodb_file_per_table设置为off会导致整个数据库托管在一个文件中(ibdata1)。我想激活innodb_file_per_table它并追溯地将数据库分成几个文件,执行此操作的最佳方法是什么?

Answers:


32

确实只有一种方法可以实现这一目标。您将必须使用mysqldumps导出数据,删除所有数据库,关闭mysqld,删除ib_logfile0,删除ib_logfile1,删除ibdata1,innodb_file_per_table[mysqld]标题下添加,启动mysql。

我在2010年10月将这个答案发布在StackOverflow中

以下是垂直列出的步骤:

步骤01)MySQL将所有数据库转储到SQL文本文件中(称为SQLData.sql)

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

步骤03)关闭mysql

CAVEAT:要从InnoDB文件中完全清除未提交的事务,请运行此命令

mysql -uroot -p... -Ae"SET GLOBAL innodb_fast_shutdown = 0;"
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

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

步骤05)删除ibdata1,ib_logfile0和ib_logfile1

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

步骤06)重新启动mysql

这将重新创建10MB的ibdata1,每个1G的ib_logfile0和ib_logfile1

步骤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实际上会缩小。

作为MySQL DBA,我在职业生涯中做了很多次

实际上,我第一次这样做是将50GB的ibdata1文件压缩为500MB。

试试看。如果您对此还有其他疑问,请给我发送电子邮件。相信我。这将在短期和长期内起作用。!!!

有一种替代方法将提取InnoDB表而不缩小ibdata1。

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

[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G

步骤02) service mysql restart

步骤03)要提取一个名为mydb.mytable的InnoDB表,请执行以下操作:

ALTER TABLE mydb.mytable ENGINE=InnoDB;

这将创建一个文件,请保留原始结构文件

  • /var/lib/mysql/mydb/mytable.frm
  • /var/lib/mysql/mydb/mytable.ibd

您可以为每个InnoDB表执行此操作。不幸的是,ibdata1将保留150GB。


从.sql文件运行重新加载时,出现以下错误ERROR 1071 (42000) at line 25: Specified key was too long; max key length is 1000 bytes任何提示?
2012年

@Ran,请将其作为一个单独的问题发布。
RolandoMySQLDBA 2012年


如果先设置innodb_file_per_table然后ALTER TABLE在每个表上进行操作,是否可以删除ibdata1文件来回收空间而不必还原?
SystemParadox

1
@SystemParadox绝对不是!!!!!!!! 您将丢失数据字典。
RolandoMySQLDBA 2015年

5

正如Rolando指出的那样,如果要回收ibdata的空间,则转储/恢复是您的唯一选择。这样做可能也是提高性能的最佳选择。

但是,如果您只是想减少损失并在硬盘驱动器上“丢失”这150GB,则只需innodb_file_per_table在my.cnf中启用并重新启动服务器即可。

然后为每个表发出:

ALTER TABLE x DISABLE KEYS;
ALTER TABLE x ENGINE=InnoDB;
ALTER TABLE x ENABLE KEYS; 

这里的问题是大型表空间将需要一段时间。

我的建议是设置活动数据库的从属服务器,在从属服务器上运行转换,然后关闭主服务器/从属服务器并将新的数据空间复制到主服务器,或者在追赶到该从属服务器时将其升级为主服务器。

您将很难在没有停机的情况下进行此更改。


+1表示很诚实,并说“减少了损失”。您可能也说过“咬住子弹”。
RolandoMySQLDBA 2012年

您可以使用pt-online-schema-change来避免在运行alter table时停机。
Cornernote '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.