MySQL 系统表空间ibdata:我也不想当一个死肥宅

InnoDB的系统表空间,由一个或多个ibdata文件构成,存放InnoDB表的元数据,数据字典等等。

说到数据字典,在MySQL8.0里忽然又想起另一个文件mysql.ibd,这个也是存放数据字典的地方,这两者是不是重复了呢?只能说有可能有重叠的数据,有可能一部分类型的数据字典信息放在ibdata,另一部分类型的数据字典信息放在mysql.idb。而两者可以明确区别的是,ibdata对应的是系统表空间(system tablespace),mysql.ibd对应的数据字典表表空间(data dictionary tablespace),即对应的是mysql这一个schema。在MySQL8.0以前,mysql schema下的表是存放在名为mysql的文件目录下的,在8.0以后,集中存放在了mysql.ibd这一文件中。

说回ibdata。据说有那么一个独特的人群,就算不吃饭,喝水都会胖,称其为易胖体质。在我的印象中,ibdata这家伙就是名副其实的易胖体质。几十上百G的ibdata也见过了,但从my.cnf来看,它的初始体重不过是2个G,这都胖成什么样了。

ibdata文件对应的是系统表空间,这个胖子肚子里包含了数据字典,双写缓存(doublewrite buffer),变更缓存(change buffer),还有回滚日志(undo logs)。既然肚子里大概就这些东西,到底是哪个导致ibdata的肥胖呢?

数据字典即是对象的元数据,这个就算是有所增长也是数量有限的,谁会吃饱了撑的天天做DDL。剩下的doublewrite buffer和change buffer,都已经是个固定值了,也不可能有大幅度的增长。那么就剩下undo logs了。DML没提交前,就需要维护回滚段,保证其在事务期间不会被重用或回收。那么如果存在大量长事务,就会导致活动的undo segment越来越多,不够用的时候也就只能在空间上往上扩展,那么基本可以断定,根本原因即是undo logs。还说只喝水,明明就是在偷偷胡吃海喝嘛!

ibdata这个胖子还特别懒,不会自己积极做运动减肥,胖了就瘦不了。真是个死肥宅!

既然它自暴自弃,那就让它自生自灭呗。不行啊,这胖子占了100G空间,还在不停地增长,磁盘空间都要爆了!面对这三百斤的胖宅,我默默地拿起了菜刀。

杀了它!不行,没了它,MySQL活不了。把my.cnf里的innodb_data_file_path改小?不行,MySQL起不来。怎么办?别怕,我拿菜刀是有原因的。我要拿菜刀把它的肉割下来!

怎么割?割起来动作就有点大了。首先要把整个MySQL用mysqldump导出来,只能是逻辑备份。然后将原来的数据库删掉,重新导入。这样,ibdata就瘦下来了。整个过程想想都刺激。所以保险起见,最好搭建从库,利用主从切换的方式来给ibdata瘦身。

ibdata表示很无辜,它也不想变胖,是undo logs自己跑进它的肚子的。想想也有道理。那么是否可以管教一下调皮的undo logs呢?答案是可以的。

undo log默认是放在系统表空间中,可以通过innodb_undo_directory和innodb_undo_tablespaces来将undo表空间独立出来,这样就可以把undo log和ibdata分开了。

那么问题又来了,undo log独立出来以后,分开是分开了,但是如果还是存在大量长事务,undo log还是会不断地增大,目录还是会被慢慢占满。

别慌,如果将undo表空间独立出来,那么问题就好办了。可以通过innodb_max_undo_log_size和SET GLOBAL innodb_undo_log_truncate=ON来设置undo段自动回收。具体的实现过程如下:
当undo表空间文件大小超过了innodb_max_undo_log_size,就会被标记为回收状态,并且释放不再需要保留的回滚段,回收空间。当然,尚在活动的事务,对应的回滚段是继续保留的。这样就实现了undo表空间文件的空间回收。

ibdata弱弱地说:如果一不小心变成了一个肥宅,我也不是故意的…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值