如何收缩/清除MySQL中的ibdata1文件

我在本地主机上使用MySQL作为“查询工具”来执行R中的统计信息,也就是每次运行一个R脚本时,我创build一个新的数据库(A),创build一个新的表(B),将数据导入B ,提交一个查询来获得我所需要的,然后我放下B并放下A.

它对我来说工作得很好,但是我意识到ibdata文件的大小正在迅速增加,我没有在MySQL中存储任何内容,但ibdata1文件已经超过了100 MB。

我正在使用或多或less默认的MySQL设置的设置,是否有一种方法可以自动缩小/清除ibdata1文件一段固定的时间后?

ibdata1不缩小是MySQL特别恼人的特性。 除非删除所有数据库,删除文件并重新加载转储,否则ibdata1文件实际上无法收缩。

但是您可以configurationMySQL,以便每个表(包括其索引)都存储为一个单独的文件。 这样ibdata1将不会增长。 根据Bill Karwin的评论 ,MySQL 5.6.6版本默认启用。

我刚才做了这个。 但是,要设置服务器为每个表使用不同的文件,您需要更改my.cnf以启用此function:

 [mysqld] innodb_file_per_table=1 

http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html

如果您想要从ibdata1回收空间,您实际上必须删除该文件:

  1. mysqlperformance_schema数据库以外的所有数据库,过程,触发器等进行mysqldump
  2. 删除上述2个数据库以外的所有数据库
  3. 停止mysql
  4. 删除ibdata1ib_log文件
  5. 启动mysql
  6. 从转储还原

在步骤5中启动MySQL时,将重新创buildibdata1ib_log文件。

现在你可以走了。 当您创build新的数据库进行分析时,这些表将位于单独的ibd*文件中,而不是位于ibdata1 。 正如您通常在数据库后不久, ibd*文件将被删除。

http://dev.mysql.com/doc/refman/5.1/en/drop-database.html

你可能已经看到这个:
http://bugs.mysql.com/bug.php?id=1341

通过使用ALTER TABLE <tablename> ENGINE=innodbOPTIMIZE TABLE <tablename>可以从ibdata1中提取数据和索引页来分隔文件。 但是,除非您执行上述步骤,否则ibdata1将不会收缩。

关于information_schema ,这是不必要的,也可能下降。 它实际上只是一堆只读视图,而不是表格。 没有文件与它们关联,甚至没有数据库目录。 informations_schema正在使用内存数据库引擎,并在mysqld停止/重新启动时被删除并重新生成。 请参阅https://dev.mysql.com/doc/refman/5.7/en/information-schema.html

当你删除innodb表时,MySQL不会释放ibdata文件内的空间,这就是为什么它不断增长的原因。 这些文件几乎不会缩小。

如何缩小现有的ibdata文件:

http://dev.mysql.com/doc/refman/5.5/en/innodb-resize-system-tablespace.html

您可以编写脚本并安排脚本在一段固定时间后运行,但是对于上述设置,似乎多个表空间是一个更简单的解决scheme。

如果使用configuration选项innodb_file_per_table ,则可以创build多个表空间。 也就是说,MySQL为每个表格创build单独的文件,而不是一个共享文件。 这些单独的文件存储在数据库的目录中,并在删除此数据库时被删除。 这应该删除在您的情况下收缩/清除ibdata文件的需要。

有关多个表空间的更多信息:

http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html

加上John P的回答 ,

对于linux系统,可以使用以下命令完成步骤1-6:

  1. mysqldump -u [username] -p[root_password] [database_name] > dumpfilename.sql
  2. DROP DATABASE database_name
  3. sudo /etc/init.d/mysqld stop
  4. sudo rm /var/lib/mysql/ibdata1
    sudo rm /var/lib/mysql/ib_logfile (以及删除可能被命名为ib_logfile0ib_logfile1等的其他ib_logfile)
  5. sudo /etc/init.d/mysqld start
  6. create database [database_name]
  7. mysql -u [username]-p[root_password] [database_name] < dumpfilename.sql

警告:如果您在此mysql实例上有其他数据库,这些说明将会导致您丢失其他数据库。 确保步骤1,2和6,7被修改为覆盖您希望保留的所有数据库。

如果你使用InnoDB存储引擎来处理(某些)你的MySQL表,你可能已经遇到了一个默认configuration的问题。 正如你可能已经注意到你的MySQL的数据目录(在Debian / Ubuntu – / var / lib / mysql中)是一个名为“ibdata1”的文件。 它包含几乎所有的MySQL实例的InnoDB数据(这不是一个事务日志),可能会变得相当大。 默认情况下,这个文件的初始大小为10Mb,并自动扩展。 不幸的是,通过deviseInnoDB数据文件不能被缩小。 这就是为什么DELETE,TRUNCATE,DROP等不能回收文件使用的空间的原因。

我想你可以在那里find很好的解释和解决办法:

http://vdachev.net/2007/02/22/mysql-reducing-ibdata1/

如果您的目标是监视MySQL可用空间,并且您不能停止MySQL来收缩您的ibdata文件,那么通过表状态命令来获取它。 例:

MySQL> 5.1.24:

 mysqlshow --status myInnodbDatabase myTable | awk '{print $20}' 

MySQL <5.1.24:

 mysqlshow --status myInnodbDatabase myTable | awk '{print $35}' 

然后将这个值与你的ibdata文件进行比较:

 du -b ibdata1 

资料来源: http : //dev.mysql.com/doc/refman/5.1/en/show-table-status.html

在新版本的mysql-server食谱上面会粉碎“mysql”数据库。 在旧版本中,它的作品。 在新的一些表切换到表typesINNODB,这样做,你会损害他们。 最简单的方法是转储你所有的数据库,卸载mysql-server,join剩下的my.cnf:

 [mysqld] innodb_file_per_table=1 erase all in /var/lib/mysql install mysql-server restore users and databases 

正如已经指出的,你不能缩小ibdata1(这样做你需要转储和重build),但是也经常没有真正的需要。

使用自动扩展(可能是最常见的大小设置)ibdata1预先分配存储,每当它几乎满时增长。 这使得写入空间已经分配得更快。

当您删除数据时,它不会缩小,但文件内部的空间被标记为未使用。 现在当你插入新的数据时,它将在文件增长之前重新使用文件中的空白空间。

所以只有在真正需要这些数据的时候才会继续增长。 除非你真的需要另一个应用程序的空间,否则可能没有理由缩小它。