我们在 Percona 支持栏目经常收到关于 MySQL 的 ibdata1 文件的这个问题。当监控服务器发送一个关于 MySQL 服务器存储的报警时,恐慌就开始了 —— 就是说磁盘快要满了。一番调查后你意识到大多数地盘空间被 InnoDB 的共享表空间 ibdata1 使用。而你已经启用了 innodb_file_per_table,所以问题是:

ibdata1存了什么?

当你启用了 innodb_file_per_table,表被存储在他们自己的表空间里,但是共享表空间仍然在存储其它的 InnoDB 内部数据:

  • 数据字典,也就是 InnoDB 表的元数据
  • 变更缓冲区
  • 双写缓冲区
  • 撤销日志

其中的一些在 Percona 服务器上可以被配置来避免增长过大的。例如你可以通过 innodb_ibuf_max_size 设置最大变更缓冲区,或设置 innodb_doublewrite_file 来将双写缓冲区存储到一个分离的文件。

MySQL 5.6 版中你也可以创建外部的撤销表空间,所以它们可以放到自己的文件来替代存储到 ibdata1。可以看看这个文档

什么引起 ibdata1 增长迅速?

当 MySQL 出现问题通常我们需要执行的第一个命令是:

 
1
SHOW ENGINE INNODB STATUS/G

这将展示给我们一些很有价值的信息。我们从** TRANSACTION(事务)**部分开始检查,然后我们会发现这个

 
1
2
3
4
---TRANSACTION 36E, ACTIVE 1256288 sec
MySQL thread id 42, OS thread handle 0x7f8baaccc700, query id 7900290 localhost root
show engine innodb status
Trx read view will not see trx with id >= 36F, sees < 36F

这是一个最常见的原因,一个14天前创建的相当老的事务。这个状态是活动的,这意味着 InnoDB 已经创建了一个数据的快照,所以需要在撤销日志中维护旧页面,以保障数据库的一致性视图,直到事务开始。如果你的数据库有大量的写入任务,那就意味着存储了大量的撤销页。

如果你找不到任何长时间运行的事务,你也可以监控INNODB STATUS 中的其他的变量,“History list length(历史记录列表长度)”展示了一些等待清除操作。这种情况下问题经常发生,因为清除线程(或者老版本的主线程)不能像这些记录进来的速度一样快地处理撤销。

我怎么检查什么被存储到了 ibdata1 里了?

很不幸,MySQL 不提供查看什么被存储到 ibdata1 共享表空间的信息,但是有两个工具将会很有帮助。第一个是马克·卡拉汉制作的一个修改版 innochecksum ,它发布在这个漏洞报告里。

它相当易于使用:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# ./innochecksum /var/lib/mysql/ibdata1
0 bad checksum
    13 FIL_PAGE_INDEX
    19272 FIL_PAGE_UNDO_LOG
    230 FIL_PAGE_INODE
    1 FIL_PAGE_IBUF_FREE_LIST
    892 FIL_PAGE_TYPE_ALLOCATED
    2 FIL_PAGE_IBUF_BITMAP
    195 FIL_PAGE_TYPE_SYS
    1 FIL_PAGE_TYPE_TRX_SYS
    1 FIL_PAGE_TYPE_FSP_HDR
    1 FIL_PAGE_TYPE_XDES
    0 FIL_PAGE_TYPE_BLOB
    0 FIL_PAGE_TYPE_ZBLOB
    0 other
    3 max index_id

全部的 20608 中有 19272 个撤销日志页。这占用了表空间的 93%

第二个检查表空间内容的方式是杰里米·科尔制作的 InnoDB Ruby 工具。它是个检查 InnoDB 的内部结构的更先进的工具。例如我们可以使用 space-summary 参数来得到每个页面及其数据类型的列表。我们可以使用标准的 Unix 工具来统计撤销日志页的数量:

 
1
2
# innodb_space -f /var/lib/mysql/ibdata1 space-summary | grep UNDO_LOG | wc -l
19272

尽管这种特殊的情况下,innochedcksum 更快更容易使用,但是我推荐你使用杰里米的工具去了解更多的 InnoDB 内部的数据分布及其内部结构。

好,现在我们知道问题所在了。下一个问题:

我该怎么解决问题?

这个问题的答案很简单。如果你还能提交语句,就做吧。如果不能的话,你必须要杀掉线程开始回滚过程。那将停止 ibdata1 的增长,但是很显然,你的软件会出现漏洞,有些人会遇到错误。现在你知道如何去鉴定问题所在,你需要使用你自己的调试工具或普通的查询日志来找出谁或者什 么引起的问题。

如果问题发生在清除线程,解决方法通常是升级到新版本,新版中使用一个独立的清除线程替代主线程。更多信息查看该文档

有什么方法回收已使用的空间么?

没有,目前还没有一个容易并且快速的方法。InnoDB 表空间从不收缩...参见10 年之久的漏洞报告,最新更新自詹姆斯·戴(谢谢):

当你删除一些行,这个页被标为已删除稍后重用,但是这个空间从不会被回收。唯一的方法是使用新的 ibdata1 启动数据库。要做这个你应该需要使用 mysqldump 做一个逻辑全备份,然后停止 MySQL 并删除所有数据库、ib_logfile*、ibdata1* 文件。当你再启动 MySQL 的时候将会创建一个新的共享表空间。然后恢复逻辑备份。

总结

当 ibdata1 文件增长太快,通常是 MySQL 里长时间运行的被遗忘的事务引起的。尝试去解决问题越快越好(提交或者杀死事务),因为不经过痛苦缓慢的 mysqldump 过程,你就不能回收浪费的磁盘空间。

也是非常推荐监控数据库以避免这些问题。我们的 MySQL 监控插件包括一个 Nagios 脚本,如果发现了一个太老的运行事务它可以提醒你。

mysql 里的 ibdata1 文件不断的增长的更多相关文章

  1. mysql 里的 ibdata1 文件不断的增长?

    我们在 Percona 支持栏目经常收到关于 MySQL 的 ibdata1 文件的这个问题.当监控服务器发送一个关于 MySQL 服务器存储的报警时,恐慌就开始了 —— 就是说磁盘快要满了.一番调查 ...

  2. mysql里的ibdata1文件

    mysql大多数磁盘空间被 InnoDB 的共享表空间 ibdata1 使用.而你已经启用了 innodb_file_per_table,所以问题是: ibdata1存了什么? 当你启用了innodb ...

  3. ibdata1文件--缩小mysql数据库的ibdata1文件

    摘要 在MySQL数据库中,如果不指定innodb_file_per_table参数,单独存在每个表的数据,MySQL的数据都会存放在ibdata1文件. mysql ibdata1存放数据,索引等, ...

  4. 原想着mysql里放些文件什么的,查完资料还是算了

    三种东西永远不要放到数据库里 1.图片,文件,二进制数据,文件还是放入文件服务器吧或者分布式文件系统 2.短生命期数据 3.日志文件 mysql中一张表的数据是全部在一个数据文件中的.如果大字段的数据 ...

  5. 如何收缩Mysql的ibdata1文件

    ibdata1是MySQL数据库中一个数据文件了,你会发现它来越大了,下面我来介绍收缩Mysql的ibdata1文件大小方法. 如果你有使用InnoDB来存储你的Mysql表,使用默认设置应该会碰到个 ...

  6. mysql frm的恢复,data里只有frm文件的恢复

    mysql frm的恢复,data里只有frm文件的恢复 mysql frm的恢复,data里只有frm文件的恢复,换了系统,装了windows2003,重装最新5.4版的mysql,把原来的一个数据 ...

  7. MySQL的ibdata1文件占用过大

    处理MySQL的ibdata1文件过大问题 本人遇到一次在安装zabbix监控的时候,yum安装的MySQL数据库,后面用了一段时间发现data目录下的ibdata1的空间特别大,反而我的zabbix ...

  8. 详解MySQL表空间以及ibdata1文件过大问题

    ibdata1文件过大 原因分析 ibdata1是一个用来构建innodb系统表空间的文件,关于系统表空间详细介绍参考MySQL官网文档 上面是一个数据库的ibdata1文件,达到了780多G,而且还 ...

  9. 处理MySQL的ibdata1文件过大问题

    ibdata1文件是什么? ibdata1是一个用来构建innodb系统表空间的文件,这个文件包含了innodb表的元数据.撤销记录.修改buffer和双写buffer.如果file-per-tabl ...

随机推荐

  1. 自己总结 C++ 代码规范

    .编写原则,代码尽量简单,简洁,高效,自己写的代码让自己和别人容易看懂 .命名: a. 类的成员变量加前缀 m_(表示 member). 常量全用大写的字母,用下划线分割单词(;) 循环变量和简单变量 ...

  2. VSS虚拟交换系统

    下面介绍一下如何在CISCO交换机上配置VSS,具体配置如下: //在CISCO1 上配置vss域,两台设备都要在同一个域中 Cisco-(confgi)#switch virtual domain ...

  3. I.MX6 I2C DS1337 disable square-wave output

    linux I2C DS1337 disable square-wave output \\\\\\\\\\\-*- 目录 -*-////////// | 一.DS1337访问寄存器说明: | 二.c ...

  4. Git钩子:自定义你的工作流

    Git钩子是在Git仓库中特定事件发生时自动运行的脚本.它可以让你自定义Git内部的行为,在开发周期中的关键点触发自定义的行为. Git钩子最常见的使用场景包括推行提交规范,根据仓库状态改变项目环境, ...

  5. SPOJ104 Highways 【矩阵树定理】

    SPOJ104 Highways Description In some countries building highways takes a lot of time- Maybe that's b ...

  6. Unicode字符转换成字符串

    /*** * Unicode字符转换成字符串 * @param str * Unicode字符 * @return * String * * @author WXW */ public static ...

  7. Object-C 中的Selector 概念

    selector可以叫做选择器,其实指的就是对象的方法,也可以理解为C语言里面的函数指针,在面向对象里面的对应概念. @selector(xxxx)的作用是找到名字为xxxx的方法.一般用于[a pe ...

  8. WampServer的配置

    转自:http://www.cnblogs.com/azumia/archive/2012/06/06/2538872.html 第一,打开局域网访问 配置文件:点击右下角的WAMP 服务器小托盘,选 ...

  9. hessian协议原理

    Hessian 原理分析 一.      远程通讯协议的基本原理 网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络 IO 来实现,其中传输协议比较出名的有 http . t ...

  10. LG2590 [ZJOI2008]树的统计

    题意 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: ...