分享篇 | MySQL的ibdata1是个啥,为啥越来越大,怎么缩小?

同事的一个问题:
MySQL的ibdata1文件越来越大,这是为啥、
看着别扭,怎么搞小它?

ibdata1文件是什么?
ibdata1是一个用来构建innodb系统表空间的文件,这个文件包含了innodb表的元数据、undo日志、修改buffer和双写buffer。随着数据库的使用,ibdata1文件会越来越大,innodb_autoextend_increment选项则指定了该文件每次自动增长的步进,默认是8M.
熟悉Oracle的亲,可以把ibdata理解成redo日志。

当在MySQL中对InnoDB表进行更改时,这些更改首先存储在InnoDB日志缓冲区的内存中,然后写入通常称为重做日志(redo logs)的InnoDB日志文件中。

介绍MySQL InnoDB 日志缓冲区(Log Buffer)的文章链接如下:
传送门:
知识分享 | MySQL InnoDB 日志缓冲区(Log Buffer)讲解

这里放张图
image.png

my.cnf中的参数设置形式:
innodb_data_file_path = ibdata1:256M;ibdata2:128M:autoextend

什么原因导致ibdata1越来越大?
上文也说了,ibdata1存放innodb表的元数据、undo日志、修改buffer和双写buffer,是MYSQL的最主要的数据,随着数据库越来越大,表也会越来越大。
尤其是innodb_file_per_table参数未开启的话,新创建表的数据和索引会存在系统表空间中,增加更加更快。

该如何处理呢?
业务数据使用独享表空间,将不用的业务表空间分别单独存放。MySQL开启独享表空间的参数是Innodb_file_per_table,会为每个Innodb表创建一个.ibd的文件。

没开启,怎么减小ibdata的大小?
两个操作步骤:
1.初始参数中修改innodb_data_file_path=1,保证业务数据被单独存放。
举例:innodb_data_file_path = ibdata1:32M;ibdata2:16M:autoextend
2.使用mysqldump做下数据的导出和导入

步骤2实操如下:

  1. 导出数据库中所有数据
    # mysqldump -uroot -p --socket=/tmp/mysql.sock --single-transaction --master-data=2 --all-databases -E -R --triggers --set-gtid-purged=off > /tmp/all-database.dump
  2. 删除数据库中数据
    mysql> drop database dbname;
  3. 停止MySQL
    # /etc/init.d/mysqld stop

    #mysqladmin -uroot -p shutdown
  4. 删除ibdata1文件(移动到/tmp下)
    # mv /var/lib/mysql/ibdata1 /tmp
    # mv /var/lib/mysql/ib_logfile0 /tmp
    # mv /var/lib/mysql/ib_logfile1 /tmp
  5. my.cnf设定
    # vi /etc/my.cnf
    开启独享表空间,并指定ibdata1大小为256M,ibdata2大小128M,自动扩张。
    innodb_file_per_table = 1

    innodb_data_home_dir = /mysqldata/data
    innodb_data_file_path = ibdata1:256M;ibdata2:128M:autoextend
  6. 启动MySQL
    # /etc/init.d/mysqld start
    或者
    #mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &
  7. 导入数据
    # mysql -u root -p < /tmp/all-database.dump
  8. 搞定

发问:使用mysqldump缩小ibdata时,mysqldump导出导入太慢,如何减少业务中断时间?

回答:充分利用主从架构来做,怎么做?

步骤如下:
1.主库mysqldump出导出文件,并scp到从库;
2.从库做逻辑恢复,并使用gtid追平主库数据(注意此刻的从库已经修改了innodb_file_per_table = 1和innodb_data_file_path = ibdata1:256M;ibdata2:128M:autoextend)
3.为保险起见,可找个业务空闲窗口,切换下高可用至从库(此刻的从库变为新主),并对外恢复业务数据访问
4.原主做mysqldump恢复,并追平新主数据,此刻原主为新从
5.搞定。

具体实操,不再赘述。

文章结束。

以下是个人微信公众号,欢迎关注:
image.png

  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MySQL 中,ibdata1 是 InnoDB 存储引擎的系统表空间,它存储了表、索引和事务等的元数据信息。因为 ibdata1 文件的大小是动态增长的,所以如果不进行定期清理,它可能会占据大量的磁盘空间。下面是一些清理 ibdata1 的方法: 1. 清理未使用的 InnoDB 表 使用以下命令可以查找未使用的 InnoDB 表: ``` SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema') AND ENGINE = 'InnoDB' AND TABLE_NAME NOT IN ( SELECT DISTINCT TABLE_NAME FROM information_schema.statistics WHERE TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema') ); ``` 如果查询结果为空,则表示所有 InnoDB 表都在使用中,否则需要进一步分析并删除未使用的表。 2. 清理 InnoDB 日志文件 在 MySQL 中,InnoDB 存储引擎会生成两个日志文件:ib_logfile0 和 ib_logfile1。这些日志文件记录了 InnoDB 存储引擎的所有操作,包括事务的提交和回滚。如果这些日志文件过大,可以通过以下命令清理: ``` SET GLOBAL innodb_fast_shutdown = 0; ``` 然后重启 MySQL 服务器,这样会清理掉不必要的日志文件。 3. 重建 InnoDB 表 如果 InnoDB 表中存在大量已删除的数据,可以通过以下方法进行重建: ``` ALTER TABLE table_name ENGINE=InnoDB; ``` 这样可以重建表并清理掉已删除的数据。 4. 导出并重新导入数据库 如果以上方法无法清理 ibdata1 文件,可以考虑将数据库导出为 SQL 文件,删除原数据库并重新创建一个空的数据库,然后再将 SQL 文件重新导入。这样可以清理掉所有不必要的数据和元数据信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值