我在localhost中使用MySQL作为在R中执行统计的“查询工具”,也就是说,每次我运行R脚本时,我都会创建一个新的数据库(a),创建一个新的表(B),将数据导入到B中,提交一个查询以获得我需要的数据,然后我删除B和删除a。
这对我来说很好,但我意识到ibdata文件的大小正在迅速增加,我在MySQL中没有存储任何东西,但ibdata1文件已经超过100 MB。
我正在使用或多或少的默认MySQL设置进行设置,是否有一种方法可以让我在一段固定的时间后自动收缩/清除ibdata1文件?
我在localhost中使用MySQL作为在R中执行统计的“查询工具”,也就是说,每次我运行R脚本时,我都会创建一个新的数据库(a),创建一个新的表(B),将数据导入到B中,提交一个查询以获得我需要的数据,然后我删除B和删除a。
这对我来说很好,但我意识到ibdata文件的大小正在迅速增加,我在MySQL中没有存储任何东西,但ibdata1文件已经超过100 MB。
我正在使用或多或少的默认MySQL设置进行设置,是否有一种方法可以让我在一段固定的时间后自动收缩/清除ibdata1文件?
当前回答
似乎没有人提到innodb_undo_log_truncate设置可能产生的影响。
在阅读了Percona关于这个主题的博客文章后,我在MariaDB 10.6中启用了截断UNDO LOG条目的功能,它填充了ibdata1的95%,在完全删除和恢复之后,从那时起,ibdata1就不再增长了。
在默认innodb_undo_log_truncate = 0的情况下,我的ibdata1很容易就达到了数据库空间占用的10%,也就是几十gb。
innodb_undo_log_truncate = 1时,ibdata1的大小为76 Mb。
其他回答
当你删除innodb表时,MySQL不会释放ibdata文件中的空间,这就是为什么它一直在增长。这些文件几乎从不缩小。
如何缩小现有的ibdata文件:
https://dev.mysql.com/doc/refman/5.6/en/innodb-system-tablespace.html#innodb-resize-system-tablespace
您可以编写脚本,并安排脚本在固定的时间后运行,但对于上面描述的设置,多个表空间似乎是更简单的解决方案。
如果使用配置选项innodb_file_per_table,则会创建多个表空间。也就是说,MySQL为每个表创建单独的文件,而不是一个共享文件。这些单独的文件存储在数据库的目录中,当您删除该数据库时,它们将被删除。在您的情况下,这样就不需要收缩/清除ibdata文件了。
关于多个表空间的更多信息:
https://dev.mysql.com/doc/refman/5.6/en/innodb-file-per-table-tablespaces.html
似乎没有人提到innodb_undo_log_truncate设置可能产生的影响。
在阅读了Percona关于这个主题的博客文章后,我在MariaDB 10.6中启用了截断UNDO LOG条目的功能,它填充了ibdata1的95%,在完全删除和恢复之后,从那时起,ibdata1就不再增长了。
在默认innodb_undo_log_truncate = 0的情况下,我的ibdata1很容易就达到了数据库空间占用的10%,也就是几十gb。
innodb_undo_log_truncate = 1时,ibdata1的大小为76 Mb。
ibdata1不收缩是MySQL的一个特别烦人的特性。ibdata1文件实际上无法收缩,除非删除所有数据库、删除文件并重新加载转储。
但是您可以配置MySQL,使每个表(包括其索引)存储为一个单独的文件。这样ibdata1就不会变大。根据Bill Karwin的评论,MySQL 5.6.6版本默认启用了这个功能。
这是一段时间前的事了。然而,要设置你的服务器为每个表使用单独的文件,你需要改变my.cnf来启用这个功能:
[mysqld]
innodb_file_per_table=1
https://dev.mysql.com/doc/refman/5.6/en/innodb-file-per-table-tablespaces.html
当你想要从ibdata1中回收空间时,你实际上必须删除文件:
做一个mysqldump的所有数据库,过程,触发器等除了mysql和performance_schema数据库 删除除上述2个数据库以外的所有数据库 停止mysql 删除ibdata1和ib_log文件 启动mysql 从转储恢复
在第5步启动MySQL时,将重新创建ibdata1和ib_log文件。
现在你可以走了。在创建用于分析的新数据库时,表将位于单独的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=innodb或OPTIMIZE TABLE <tablename>,可以从ibdata1中提取数据和索引页,以分离文件。但是,除非执行上述步骤,否则ibdata1不会收缩。
对于information_schema,没有必要也不可能删除。它实际上只是一堆只读视图,而不是表。并且没有与它们相关的文件,甚至没有数据库目录。informations_schema使用内存db-engine,在停止/重新启动mysqld时删除并重新生成。见https://dev.mysql.com/doc/refman/5.7/en/information-schema.html。
如前所述,您不能收缩ibdata1(为此需要转储和重新构建),但通常也没有真正的必要。
使用autoextend(可能是最常见的大小设置),ibdata1预分配存储空间,在存储空间接近满时增长。这使得写入速度更快,因为已经分配了空间。
当你删除数据时,它不会缩小,但文件内部的空间被标记为未使用。现在,当您插入新数据时,它将在进一步增长文件之前重用文件中的空白空间。
所以只有当你真的需要这些数据时,它才会继续增长。除非您确实需要为另一个应用程序使用空间,否则可能没有理由缩小它。
再加上约翰P的回答,
对于linux系统,步骤1-6可以用这些命令完成:
Mysqldump -u [username] -p[root_password] [database_name] > dumpfilename.sql Mysqladmin -u [username] -p[root_password] drop [database_name] sudo /etc/init.d / mysqld停止 Sudo rm /var/lib/mysql/ibdata1 执行rm /var/lib/mysql/ib_logfile* sudo /etc/init.d / mysqld开始 Mysqladmin -u [username] -p[root_password] create [database_name] Mysql -u [username] -p[root_password] [database_name] < dumpfilename.sql . zip
警告:如果你在这个mysql实例上有其他数据库,这些指令将导致你丢失其他数据库。确保修改步骤1、2和6、7以覆盖您希望保留的所有数据库。