MySQL 5.6 如何给ibdata1瘦身

article/2025/10/8 4:44:56

bcd91d07a0f4e35b0273efed

前不久刚给ibdata1瘦身,发篇文章总结下。

ibdata1是MySQL使用InnoDB引擎时所产生的文件,其一般存储数据、索引、结构、缓冲数据、共享数据和重做日志等。因为ibdata1只增不减,长期操作数据库,可能会使其越来越大,而浪费空间。

加上使用InnoDB引擎时,没有添加innodb_file_per_table参数也是导致ibdata1过大的原因。

但InnoDB只增不减,也导致给ibdata1瘦身是件比较麻烦的事。

最大的我见过的是40多G的ibdata1文件,实际数据库差不多是20多G,在做了优化后,ibdata1缩小至20多G,所以说减肥还是有必要的。

首先,先略微说下innodb_file_per_table参数,使用该参数可使得InnoDB引擎转变为独立表空间模式(默认为共享表空间),也就是每个数据库的每个表都会生成一个数据空间,就像MyISAM引擎一样。

独立表空间优点就是每个表有独立空间,数据和索引都会存在自已的表空间中,可以实现单表在不同的数据库中移动。重要的是空间可以回收,而且不管日常怎么操作,表空间的碎片不会太严重的影响性能,优化表的速度也快,表文件出现问题不会大动干戈,只要修复对应表即可。缺点是单表占用的空间比共享表空间方式稍大,共享表空间在Insert操作上有一些优势。

所以没增加innodb_file_per_table参数的同学,建议还是加上吧。因为增加innodb_file_per_table参数,与我们后续给ibdata1瘦身并无冲突,而且对以后也只有好处。

说了这么多废话,言归正传。谈谈怎么给ibdata1瘦身,唯一的方法是就是备份整个数据库,然后删掉ibdata1和ib_logfile*,再恢复数据库,以此达到瘦身目的。当然了,操作数据库肯定是有风险的,而且也需要生产环境允许MySQL暂停写或访问。

简单的总结就是以下这几点:

1.在/etc/my.cnf中添加“innodb_force_recovery=4”使InnoDB成为只读表,这其实应该说是第一个坑。另外确定“innodb_data_file_path”参数限定的初始ibdata1大小在合理范围,一般稍大于现有数据大小。
2.启动MySQL,使用我给的工具备份除了mysql、information_schema和performance_schema的整个数据库。为以后顺利恢复数据做准备。
3.删除除了mysql、information_schema和performance_schema的整个数据库,这3个排除在外的其实也删不掉。
4.停止MySQL,删除ibdata1和ib_logfile*文件。
5.删除数据库目录中的mysql目录的innodb_index_stats.*、innodb_table_stats.*、slave_master_info.*、slave_relay_log_info.*、slave_worker_info.*文件,这5个是InnoDB的基础表(状态表),这是MySQL 5.6的坑,删除ibdata1后不会自动重建这5个表,而且如果不删除这些旧文件,还不可创建或重建新的。
6.在/etc/my.cnf把“innodb_force_recovery=4”去除。
7.启动MySQL,将第2步备份的数据库还原,然后用从MySQL 5.6导出来的InnoDB基础表备份还原回去重建(第5步删掉的)。
8.搞定,重启下MySQL,确保没有错误,没有异常。

必要的工具,在文末的Github地址下载。

下面详细说说每个步骤,首先是设置InnoDB为只读表,这还是比较必要的。可确保你的数据完整性、安全性。为何是坑呢,因为我遇到过没这样设置,导致后续恢复备份时,数据有异常。

具体操作,在/etc/my.cnf中添加“innodb_force_recovery=4”

...
[mysqld]
...
innodb_force_recovery = 4
...

如此便可,innodb_file_per_table也是在[mysqld]下添加。

innodb_force_recovery的值可以设置为1-6,大的数字包含其前面所有数字的影响。

1. (SRV_FORCE_IGNORE_CORRUPT):忽略检查到的corrupt页。
2. (SRV_FORCE_NO_BACKGROUND):阻止主线程的运行,如主线程需要执行full purge操作,会导致crash。
3. (SRV_FORCE_NO_TRX_UNDO):不执行事务回滚操作。
4. (SRV_FORCE_NO_IBUF_MERGE):不执行插入缓冲的合并操作。
5. (SRV_FORCE_NO_UNDO_LOG_SCAN):不查看重做日志,InnoDB存储引擎会将未提交的事务视为已提交。
6. (SRV_FORCE_NO_LOG_REDO):不执行前滚的操作。

接着呢,启动MySQL,备份整个数据库,一般我们会用

mysqldump --lock-all-tables --all-databases > all-dbs.sql

来完整备份数据库。但这样的话,就包含了mysql、information_schema和performance_schema这3个数据库,而在后续还原数据库,带着这3个数据库可能会出错(我有几次遇到过)。

所以我提供了shell脚本工具mysql_dump_all_db.sh,因为怕大家不像我是免密码操作MySQL的,在使用工具前,请先修改脚本中的MySQL帐号和密码,然后再通过

sh mysql_dump_all_db.sh

执行备份操作,备份好的文件,会存放在脚本运行所在目录。

这个工具默认排除mysql、information_schema和performance_schema这3个数据库,如果你有其他想排除的,可以直接修改脚本,增加其他想要排除的数据库。

完了之后呢,删除所有数据库,可以通过phpMyadmin或直接在shell操作MySQL删除,在shell下删除,可以在/tmp/DatabasesToDump.txt查看到所有数据库,由“mysql_dump_all_db.sh”生成。我一般在phpMyadmin删除,简单,不怕错。如你所见,mysql、information_schema和performance_schema这3个数据库是删不掉的,所以要排除,免得麻烦。

搞定后,就可以停止MySQL了。删除数据库目录的ibdata1和ib_logfile*文件,一般是在/usr/local/mysql/data,看你怎么配置的了。

接着,在该目录下的mysql目录(/usr/local/mysql/data/mysql)中,把innodb_index_stats.*、innodb_table_stats.*、slave_master_info.*、slave_relay_log_info.*、slave_worker_info.*共计10个文件删除,这些文件已经无用了,而且占着茅坑不拉屎。MySQL 5.6很煞笔的不会重建这5个表,如果你不删除他们,待会将无法重建或恢复这5个表,接着log一直在报错,死循环。所以要把这5个表的10个文件干掉。所以这个是个坑。

在/etc/my.cnf把“innodb_force_recovery=4”去除后,就可以启动MySQL了,这时候ibdata1和ib_logfile*文件会重建。噢,上帝,胜利在望,不要激动,让我们继续吧。

把刚才备份的所有数据库还原,用从MySQL 5.6导出来的InnoDB基础表备份还原回去重建。

我在后面的Github地址有提供,从全新 MySQL 5.6导出的,名字为“mysql_innodb_basic_tables.sql”的备份文件,通过它可以重建刚才删掉的5个InnoDB基础表。

还原数据库文件非常简单,不过我还是略微写下,照顾下小白,在shell下:

mysql < all-dbs.sql
mysql < mysql_innodb_basic_tables.sql

这样就OK了,如没有免密码操作权限,请自行添加-u和-p参数。

好的,做完这些,重启下MySQL,确保没有错误即可。这样就完成了对ibdata1的瘦身。

以上操作环境为:CentOS 6.6 x64、MySQL 5.6.25。

工具存放在Github中(原谅我的渣英文),见: https://github.com/kn007/Reduce-Shrink-Purge-the-ibdata1-file-in-MySQL

写这篇文章就是为了大家少走一点弯路,也把自己遇到的坑说一下。算是个总结,也是给后人的一些经验。原则上不提供技术支持,有问题请自行解决。另外毕竟是数据库,瘦身有风险,操作需谨慎。


http://chatgpt.dhexx.cn/article/uCeQvHQT.shtml

相关文章

误删mysql8下ibdata1文件恢复数据

一位小伙伴不小心误删了生产环境上mysql数据下/data/mysql/ibdata1和ib_logfile0、ib_logfile1文件&#xff0c;并且mysql服务停止了&#xff0c;造成mysql重启不了&#xff0c;吓得小伙伴以为要“被删库跑路”了&#xff0c;于是赶紧帮忙”救火”。像这种误删数据或者删库的情…

MySQL ibdata1 文件“减肥”记

夏天来了&#xff0c;没想到连 ibdata1 文件也要开始“减肥”了~ 作者&#xff1a;杨彩琳 爱可生华东交付部 DBA&#xff0c;主要负责 MySQL 日常问题处理及 DMP 产品支持。爱好跳舞&#xff0c;追剧。 本文来源&#xff1a;原创投稿 有句话是这么说的&#xff1a;“在 InnoDB…

【无标题】1.[ERROR] InnoDB: The innodb_system data file ‘ibdata1‘ must be writable

问题原因: 文件的权限导致运行MySQL服务的用户无法对这些文件进行写入导致的报错. 解决方案: 方案一: 初始化MySQL服务时记得使用"–user"指定运行mysql服务的用户. 方案二: 直接进入到数据目录使用"chown"命令修改权限即可.

【MySQL】MySQL发生系统错误、The innodb_system data file ‘ibdata1‘ must be writable问题的解决

1. 启动mysql服务时&#xff1a;发生系统错误5 使用命令行 net start MySql 后报错&#xff1a;发生系统错误 5。 说明权限不够 &#xff0c;需要使用管理员身份运行cmd。 但是每次都需要搜索后然后右键选择以管理员身份运行很麻烦&#xff0c;这里介绍一个一劳永逸的办法&am…

MySQL的ibdata1文件占用过大瘦身

处理MySQL的ibdata1文件过大问题 本人在对数据库进行大量的数据插入和删除的时候&#xff0c;发现ibdata1的占了将近一个T ibdata1文件是什么&#xff1f; ibdata1是一个用来构建innodb系统表空间的文件&#xff0c;这个文件包含了innodb表的元数据、撤销记录、修改buffer和双…

【数据库篇】MySQL InnoDB ibd 文件格式解析

mysql innodb的表由.frm .ibd 组成&#xff0c;frm&#xff1a;存了每个表的元数据&#xff0c;包括表结构的定义等&#xff1b;ibd&#xff1a;存了每个表的元数据&#xff0c;包括表结构的定义等&#xff1b; 1.0 ibd文件基本结构 ibd文件由Tablespaces,Segments,Extents,P…

mysql 里的 ibdata1 文件

为什么 mysql 里的 ibdata1 文件不断的增长&#xff1f; 转自&#xff1a;http://linux.cn/article-5829-rss.html ibdata1 file 我们在 Percona 支持栏目经常收到关于 MySQL 的 ibdata1 文件的这个问题。 当监控服务器发送一个关于 MySQL 服务器存储的报警时&#xff0c;恐慌…

mysql ibdata1

ibdata1是什么&#xff1f; Mysql ibdata1即Innodb data1缩写&#xff0c;是innodb引擎的表空间&#xff0c;用于存放 数据字典Data dictionary&#xff1a; 只读的表&#xff0c;存储对象的相关信息&#xff0c;如占用空间&#xff0c;列的缺省值&#xff0c;约束信息&…

MySQL 中的 ibdata1

系统表空间是InnoDB数据字典、双写缓冲区、更改缓冲区和撤消日志的存储区域 。如果表是在系统表空间中创建的&#xff0c;而不是在每个表文件或通用表空间中创建&#xff0c;则它还可能包含表和索引数据。 系统表空间可以有一个或多个数据文件。默认情况下&#xff0c;ibdata1…

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

同事的一个问题&#xff1a; MySQL的ibdata1文件越来越大&#xff0c;这是为啥、 看着别扭&#xff0c;怎么搞小它&#xff1f; ibdata1文件是什么&#xff1f; ibdata1是一个用来构建innodb系统表空间的文件&#xff0c;这个文件包含了innodb表的元数据、undo日志、修改buffe…

js类型转换题

考察隐式类型转换&#xff1a; 1.号一侧出现了字符串&#xff0c;就用String()将不是字符串的变成字符串&#xff0c;最后拼接在一起 2.-号则会调用显示类型转换Number()&#xff0c;将非数字转换成数字&#xff0c;进行计算 true 0 和 true false 都是隐式调用Number()变成…

JS中的强制类型转换

概念 这里我们首先需要知道什么是值类型转换 值类型转换&#xff1a;将值从一种类型转换为另一种类型&#xff0c;就是类型转换&#xff0c;分显示转换和隐式转换 js类型转换出的值都是基本类型&#xff08;number、boolean、string、null、undefined、string&#xff09;&a…

JavaScript——数据类型的转换

目录 一、其他类型转化成字符串类型 1. 把数字型转换为字符串型 变量.toString() 2. 利用 String(变量) 3. 利用 拼接字符串的方法实现转换效果 隐式转换 二、其他类型转化成数字类型&#xff08;重点&#xff09; 1. parseInt(变量) 可以把 字符型的转换为数字型…

JavaScript类型转换规则

类型转换 先梳理一下es6之前有五种基本数据类型:Null、Undefined、String、Number 、Boolean 布尔类型转换规则 直观上为空的值(0、空字符串、null、undefined、和NaN)将变为false 注意 :包含"0" 为true console.log(Boolean("")); //falseconsole.log(…

JavaScript类型转换

javascript是一种弱类型的语言&#xff0c;变量和类型无关&#xff0c;所以有时需要我们进行类型转换 一、数字型转换&#xff08;number&#xff09; 两种方法&#xff1a; 1、number&#xff1a;类型转化走的是v8引擎最底层机制的转化规则&#xff1a; 先将引用类型转化为…

js类型转换

NaNi??? 一、显性类型转换 强制类型转换主要是指通过String、Number和Boolean等构造方法手动转换成对应的字符串、数字和布尔值。 1.1 转为字符串 1.1.1 原始类型转字符串 原始类型字符串string &#xff1a;‘str’“str”number : 123“123”Boolean“true”/“fals…

Axure 9.0.0.3701 授权码

产品经理主力工具 Axure 在2020年5月26日更新了最新的 3701 版本&#xff0c;具体更新如下&#xff1a; 很多小伙伴在更新后会出现之前的授权无法使用的情况&#xff0c;如果出现这种情况大家可以通过在产品栈查找相对应的版本进行获取最新的授权码。 获取地址&#xff1a;http…

Axure 8.0/9.0 注册码 激活码 授权码 License

先查版本号&#xff0c;根据版本号在下面的网址查找对应的授权密钥&#xff08;没有的话&#xff0c;可以试试相近版本&#xff09; https://7rp.cn/34

Axure 9.0.0.3704 授权码

产品经理常用工具软件 Axure 又更新啦&#xff0c;本次更新版本为 Axure RP 9.0.0.3704&#xff0c;具体更新如下&#xff1a; 如何查看版本号&#xff1a; 更新后效果&#xff1a; 很多小伙伴在更新到最新版本后之前的授权出现了失效的情况&#xff0c;下边栈长为大家准备了最…

全网超详细的【Axure】Axure RP 9的下载、安装、中文字体、授权

文章目录 1. 文章引言2. 下载Axure93. 安装Axure94. Axure9中文5. Axure9授权 1. 文章引言 最近在学习原型图&#xff0c;针对画原型图的工具&#xff0c;反复对比墨刀、Axure、xiaopiu后&#xff0c;最终选择了Axure。 接下来&#xff0c;我便从Axure RP 9的下载、安装、中文…