【MySQL】ibdata文件增大的原因

背景
  早上和一个同事讨论技术问题,谈到ibdata文件会随着数据的使用而增大,而且在事务隔离级别RR 隔离级别下要比RC 隔离级别的大。本文尝试分析两个问题之一
 a ibdata 文件随着数据库的使用而增大。
 b RR 隔离级别下比RC 隔离级别下增长的快大。
ibdata1 存放哪些数据?
表数据/索引 (innodb_file_per_table=0 时)
data dictionary aka metadata of InnoDB tables
undo 表空间 回滚段相关记录
doublewrite buffer
change buffer
什么原因导致ibdata 迅速增大呢?
从ibdata1文件存放的内容来分析
我们都知道innodb的表有两种存放方式:
当innodb_file_per_table=0时也即共享表空间方式,所有表的索引/数据统一存放在一个共享表空间中ibdata1文件,随着数据量的增大,共享表空间的文件大小也迅速增长,同时空间回收困难;
当innodb_file_per_table=1时也即独占表空间方式,也就是一张表一个表空间(ibd文件),表中的索引和数据存放在独立的表空间中,执行drop/truncate 操作可以快速的回收独立表空间。
对于buffer 可以分别使用参数 innodb_doublewrite_file ,innodb_ibuf_max_size控制大小,他们带来的空间增长可以忽略不计,最终 ibdata最终的大小取决于事务的大小/长短。
a 数据库系统中存在长时间未提交的事务,或者在同一个事务中更新/插入很多数据,导致innodb需要维护很大的undo segments来保障一致性读。
通过执行命令
SHOW ENGINE INNODB STATUSG
---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
例子中显示有一个长达 1256288秒(14年)的事务未提交。active 意味着innodb在undo segment里面创建数据的快照以便提供一致性读。如果数据库存在大量的长事务,就要耗费大量的undo segment。
b 5.5版本之前 purge undo thread是和master thread 共用的。存在大量长事务的时候导致purge undo的速度小于undo segment产生的速度。通过 innodb 参数 History list length

  1. ------------
  2. TRANSACTIONS
    ------------
    Trx id counter 43831607347
    Purge done for trx's n:o < 43831607342 undo n:o < 0 state: running but idle
    History list length 2308
    LIST OF TRANSACTIONS FOR EACH SESSION:

History list length  2308 表示有 2308个事务没有清理,过大的值意味着purge thread 速度达到了瓶颈。5.5 版本开始MySQL 将purge thread 和master thread 分开,我们可以通过调整参数来加快purge undo的速度。
# yzsql 3311 param purge

  1. Variable_name                Value
  2. innodb_max_purge_lag          0
  3. innodb_max_purge_lag_delay    0
  4. innodb_purge_batch_size       300
  5. innodb_purge_threads          12

如何查看ibdata文件中的内容呢?
MySQL 官方并没有提供工具查ibata存储了什么内容,不过我们可以通过如下两种工具
innochecksum,(感谢  Mark Callaghan)。
 ./innochecksum /var/lib/mysql/ibdata1

  1. 0     bad checksum
  2. 13    FIL_PAGE_INDEX
  3. 19272 FIL_PAGE_UNDO_LOG --占用了总ibdata1 的93%
  4. 230   FIL_PAGE_INODE
  5. 1     FIL_PAGE_IBUF_FREE_LIST
  6. 892   FIL_PAGE_TYPE_ALLOCATED
  7. 2     FIL_PAGE_IBUF_BITMAP
  8. 195   FIL_PAGE_TYPE_SYS
  9. 1     FIL_PAGE_TYPE_TRX_SYS
  10. 1     FIL_PAGE_TYPE_FSP_HDR
  11. 1     FIL_PAGE_TYPE_XDES
  12. 0     FIL_PAGE_TYPE_BLOB
  13. 0     FIL_PAGE_TYPE_ZBLOB
  14. 0     other
  15. 3     max index_id

从上面的分析来看 undo log占用了总ibdata1 的93%。
第二个工具:innodb_space (  made by Jeremy Col)可以清晰地分析出ibdata1的组成(该工具需要bindata环境)

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

如何解决 ibdata1 不停的增大呢? 
坦白的说我们没有方法阻止其不停的增大,但是我们可以使用
1 规范开发同学的数据库使用习惯,使用短小的事务替代大事务,并确保每个事务都有commit机制。
2 增加purge thread 数量,加快purge undo的速度尽快释放undo空间。
3 升级到5.6 版本 独立出undo 表空间来保持ibdata文件在一个合理的大小。
当然我们也没有优雅的办法上增大的ibdata文件缩小,这个文件只增加不减小。

时间: 2024-09-14 05:56:49

【MySQL】ibdata文件增大的原因的相关文章

Flash文件增大原因与解决方法

Flash的有个优点就是容量小,便于互联网传播,如何控制它的大小非常重要,下面作者就给大家介绍flash制作过程中,控制文件大小的一些方法,经验之谈,希望您能喜欢! Flash一般做出来都是要拿到网络上去传播的,所以控制他的大小非常重要,试想如果你一个文件做出来几M甚至几十M,那会有几个人有耐心去等他下载完,下面我来说一些造成文件增大原因与解决的方法,因为我们做网络广告的时候,一般一个广告不让超过20K,所以对于控制文件大小比较有经验. 1.图片处理不当,把很大的图片拿到FLASH里面去缩小到自

MYSQL数据表损坏的原因分析和修复方法

1.       表损坏的原因分析 以下原因是导致mysql 表毁坏的常见原因: 1. 服务器突然断电导致数据文件损坏. 2. 强制关机,没有先关闭mysql 服务. 3. mysqld 进程在写表时被杀掉. 4. 使用myisamchk 的同时,mysqld 也在操作表. 5. 磁盘故障. 6. 服务器死机. 7. mysql 本身的bug .   2.       表损坏的症状 一个损坏的表的典型症状如下: 1 .当在从表中选择数据之时,你得到如下错误: Incorrect key file

php上传大文件失败的原因及应对策略_php技巧

为什么上传大文件总是失败,但是上传小文件就没有问题.小编也不得其解,网上搜其原因,整理了一篇关于php上传大文件失败的原因和解决办法的文章,分享给大家. 下面分别是各种原因以及解决办法:第1种情况:文件上传时存放文件的临时目录必须是开启的并且是 PHP 进程所有者用户可写的目录.如果未指定则 PHP 使用系统默认值. php.ini文件中upload_tmp_dir用来说明PHP上传的文件放置的临时目录,要想上传文件,得保证服务器没有关闭临时文件并对该文件夹有写入的权限. 第2种情况:max_e

MYSQL数据表损坏的原因分析和修复方法小结(推荐)_Mysql

1.表损坏的原因分析 以下原因是导致mysql 表毁坏的常见原因: 1. 服务器突然断电导致数据文件损坏. 2. 强制关机,没有先关闭mysql 服务. 3. mysqld 进程在写表时被杀掉. 4. 使用myisamchk 的同时,mysqld 也在操作表. 5. 磁盘故障. 6. 服务器死机. 7. mysql 本身的bug . 2.表损坏的症状 一个损坏的表的典型症状如下: 1 .当在从表中选择数据之时,你得到如下错误: Incorrect key file for table: '...

如何修改MySQL日志文件位置?

MySQL日志文件相信大家都有很多的了解,MySQL日志文件一般在:/var/log/mysqld.log,下面就教您修改MySQL日志文件位置的方法,供您参考. 今天需要改MySQL日志文件的位置,发现在/etc/my.cnf中怎么也改不了. 后来发现MySQL日志位是指定的: [root@localhost etc]# ps auxgrep mysqld   root     11830 0.5 0.0   4524 1204 pts/0    S    03:03   0:00 /bin/

Mysql对文件操作的封装

mysql|封装 Mysql对文件操作的封装 在查看Mysql对文件的操作中发现,它在不同的操作系统上对文件的操作,除了使用标准C运行库函数,包括open.close.seek等,在Win32下的文件和目录操作函数使用了CreatFile.CloseHandl.SetFilePointer等,不明白为什么对文件的操作要封装出两套函数. 查看了相关资料,其实使用API和标准库函数都可以生成文本文件和二进制文件,在这点上没有区别.同read()对应的是ReadFile,同write()对应的是Wri

MySQL日志文件详解

  这篇文章主要介绍了MySQL日志文件详解,本文分别讲解了错误日志.二进制日志.通用查询日志.慢查询日志.Innodb的在线redo日志.更新日志等日志类型和作用介绍,需要的朋友可以参考下 概述 日志文件是MySQL数据库的重要组成部分.MySQL有几种不同的日志文件,通常包括错误日志文件,二进制日志,通用日志,慢查询日志,等等.这些日志可以帮助我们定位mysqld内部发生的事件,数据库性能故障,记录数据的变更历史,用户恢复数据库等等.本文主要描述MySQL的各种日志文件. MySQL日志文件

Win7系统运行cmd命令提示“Windows找不到文件”的故障原因及解决方法

  故障原因分析: 一般发生这样的情况,是系统内的文件被删除所导致的. 解决方法: 1.先准备一个U盘,将U盘插入相同版本系统可正常运行cmd命令的计算机中; 2.在该计算机中打开"计算机",依次打开"C:WindowsSystem32",在该文件夹中找到"cmd.exe",并将其复制起来,通过U盘粘贴到无法运行cmd系统中"C:WindowsSystem32"目录下即可. 3.复制好之后,再次运行CMD命令即可正常打开. 以

MySQL 物理文件体系结构的简单整理说明

原文:MySQL 物理文件体系结构的简单整理说明   本文出处:http://www.cnblogs.com/wy123/p/7102128.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误进行修正或补充,无他)   本文的数据库版本是MySQL5.7.18,简单介绍一下MySQL数据文件目录的物理结构和作用,从中可以窥见MySQL的整体上的物理文件结构以及逻辑功能.可以从整体结构上了解到MySQL的物理体系架构(本人学习的思路往