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

如何在MySQL中收缩/清除ibdata1文件,mysql,database,innodb,Mysql,Database,Innodb,我在localhost中使用MySQL作为“查询工具”在R中执行统计,也就是说,每次我运行R脚本时,我都会创建一个新数据库(a),创建一个新表(B),将数据导入B,提交一个查询以获得所需的数据,然后删除B和a 它对我来说工作得很好,但是我意识到ibdata文件的大小正在快速增长,我在MySQL中没有存储任何内容,但是ibdata1文件已经超过了100mb 我在设置中或多或少使用了默认的MySQL设置,有没有办法在一段固定的时间后自动收缩/清除IBMata1文件?当您删除innodb表时,MySQ

我在localhost中使用MySQL作为“查询工具”在R中执行统计,也就是说,每次我运行R脚本时,我都会创建一个新数据库(a),创建一个新表(B),将数据导入B,提交一个查询以获得所需的数据,然后删除B和a

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


我在设置中或多或少使用了默认的MySQL设置,有没有办法在一段固定的时间后自动收缩/清除IBMata1文件?

当您删除innodb表时,MySQL不会释放IBMata文件中的空间,这就是它不断增长的原因。这些文件几乎从不缩小

如何收缩现有ibdata文件:

du -b ibdata1

您可以编写脚本,并将脚本安排在固定的时间段后运行,但是对于上面描述的设置,多个表空间似乎是一个更容易的解决方案

如果使用配置选项
innodb\u file\u per\u table
,则会创建多个表空间。也就是说,MySQL为每个表创建单独的文件,而不是一个共享文件。这些单独的文件存储在数据库的目录中,删除此数据库时将删除它们。这样就不需要在您的情况下收缩/清除ibdata文件

有关多个表空间的详细信息:


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

但是您可以配置MySQL,以便将每个表(包括其索引)存储为单独的文件。这样,
ibdata1
就不会增长得那么大。根据这一点,MySQL的5.6.6版默认启用该选项

那是很久以前的事了。但是,要将服务器设置为对每个表使用单独的文件,您需要更改
my.cnf
,以启用此功能:

[mysqld]
innodb_file_per_table=1

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

  • 对所有数据库、过程、触发器等执行
    mysqldump
    ,除了
    mysql
    performance\u schema
    数据库
  • 删除除上述两个数据库以外的所有数据库
  • 停止mysql
  • 删除
    ibdata1
    ibu日志
    文件
  • 启动mysql
  • 从转储还原
  • 在步骤5中启动MySQL时,将重新创建
    ibdata1
    ibu log
    文件

    现在你可以走了。创建新数据库进行分析时,表将位于单独的
    ibd*
    文件中,而不是
    ibdata1
    中。由于您通常很快就会删除数据库,
    ibd*
    文件将被删除

    您可能已经看到了这一点:

    通过使用命令
    altertableengine=innodb
    optimizetable
    可以从ibdata1中提取数据和索引页面以分离文件。但是,除非执行上述步骤,否则ibdata1不会收缩


    关于
    信息\u模式
    ,不需要也不可能删除。实际上,它只是一堆只读视图,而不是表。并且并没有和它们相关联的文件,甚至并没有数据库目录。
    informations_schema
    正在使用内存数据库引擎,在mysqld停止/重新启动时删除并重新生成。请参阅。

    如前所述,您不能收缩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
    
    资料来源:

    如果对(某些)MySQL表使用InnoDB存储引擎,您可能已经遇到了默认配置的问题。正如您可能已经注意到的,在MySQL的数据目录(Debian/Ubuntu–/var/lib/MySQL)中有一个名为“ibdata1”的文件。它保存了MySQL实例的几乎所有InnoDB数据(不是事务日志),可能会变得相当大。默认情况下,此文件的初始大小为10Mb,并自动扩展。不幸的是,按设计,InnoDB数据文件无法收缩。这就是为什么删除、截断、删除等不会回收文件使用的空间

    我想你可以在那里找到很好的解释和解决方案:

    添加到

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

  • mysqldump-u[username]-p[root\u password][database\u name]>dumpfilename.sql
  • mysqladmin-u[username]-p[root\u password]drop[database\u name]
  • sudo/etc/init.d/mysqld-stop
  • sudorm/var/lib/mysql/ibdata1

    sudorm/var/lib/mysql/ib_日志文件*
  • sudo/etc/init.d/mysqld start
  • mysqladmin-u[username]-p[root\u password]创建[database\u name]
  • mysql-u[username]-p[root\u password][database\u name]
  • 警告:这些说明将
    #!/usr/bin/env bash
    DATABASES="$(mysql -e 'show databases \G' | grep "^Database" | grep -v '^Database: mysql$\|^Database: binlog$\|^Database: performance_schema\|^Database: information_schema' | sed 's/^Database: //g')"
    mysqldump --databases $DATABASES -r alldatabases.sql && echo "$DATABASES" | while read -r DB; do
        mysql -e "drop database \`$DB\`"
    done && \
        /etc/init.d/mysql stop && \
        find /var/lib/mysql -maxdepth 1 -type f \( -name 'ibdata1' -or -name 'ib_logfile*' \) -delete && \
        /etc/init.d/mysql start && \
        mysql < alldatabases.sql && \
        rm -f alldatabases.sql
    
    PURGE BINARY LOGS BEFORE CURRENT_TIMESTAMP;