我在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文件?
当前回答
如前所述,您不能收缩ibdata1(为此需要转储和重新构建),但通常也没有真正的必要。
使用autoextend(可能是最常见的大小设置),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
快速脚本接受的答案的过程在bash:
#!/usr/bin/env bash
dbs=$(mysql -BNe 'show databases' | grep -vE '^mysql$|^(performance|information)_schema$')
mysqldump --events --triggers --databases $dbs > alldatabases.sql && \
echo "$dbs" | while read -r db; do
mysqladmin drop "$db"
done && \
mysql -e 'SET GLOBAL innodb_fast_shutdown = 0' && \
/etc/init.d/mysql stop && \
rm -f /var/lib/mysql/ib{data1,_logfile*} && \
/etc/init.d/mysql start && \
mysql < alldatabases.sql
保存为purge_binlogs.sh并以root用户运行。
不包括mysql, information_schema, performance_schema(和binlog目录)。
假设您在/root/.my.cnf中有管理员凭证,并且您的数据库位于默认的/var/lib/mysql目录中。
您也可以在运行此脚本后清除二进制日志,以重新获得更多的磁盘空间:
PURGE BINARY LOGS BEFORE CURRENT_TIMESTAMP;
如前所述,您不能收缩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以覆盖您希望保留的所有数据库。
似乎没有人提到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。