免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7723 | 回复: 5
打印 上一主题 下一主题

InnoDB undo log解析(一) [复制链接]

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-03-12 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-05-07 10:48 |只看该作者 |倒序浏览
本帖最后由 qlks 于 2013-05-07 10:48 编辑

转自:http://insidemysql.blog.163.com/ ... 422013325115250722/

在InnoDB存储引擎中,undo log用来完成事务的回滚以及MVCC的功能。但是InnoDB本身提供对于undo log的分析或者查询功能非常有限。用户仅能通过SHOW ENGINE INNODB STATUS中的History list length信息的值当前undo log在history列表中的数量。网上已经有些文章分析了undo log的存储结构,但很少对InnoDB的undo log进行解析。本博文将详细介绍InnoDB存储引擎中的undo log格式,使读者能更为深入了解其实现。

在InnoDB存储引擎中,undo log可分为以下两种类型:
  • insert undo log
  • update undo log

insert undo log是指在insert操作中产生的undo log。因为insert操作的记录,只对事务本身可见,对其他事务不可见(这是事务隔离性的要求),故该undo log可以在事务提交后直接删除。不需要进行purge操作。insert undo log的格式如下图所示:


图中*表示对存储的字段进行了压缩。insert undo log开始的前两个字节next记录的是下一个undo log的位置,通过该next的字节可以知道一个undo log所站的空间字节数。类似地,尾部的两个字节记录的是undo log的开始位置。type_cmpl占用一个字节,记录的是undo地类型,对于insert undo log,该值总是为11。undo_no记录事务的ID,table_id记录undo log所对应的表对象。这两个值都是用于进行压缩的。接着的部分记录了所有主键的列和值。在进行rollback操作时,根据这些值可以定位到具体的记录,然后进行删除即可。

update undo log记录的是对delete和update操作产生的undo log。该undo log可能需要提供MVCC机制,因此不能在事务提交时就进行删除。提交时放入undo log链表,等待purge线程进行最后的删除。update undo log的结构如下图所示:


update undo log相对于之前介绍的insert undo log,记录的内容更多,所需占用的空间也更大。next、start、undo_no、table_id与之前介绍的insert undo log部分相同。这里的type_cmpl,由于update undo log本身还有分类,故其可能的值如下:
  • 12 (TRX_UNDO_UPD_EXIST_REC)
  • 13 (TRX_UNDO_UPD_DEL_REC)
  • 14 (TRX_UNDO_DEL_MARK_REC)

undo log可以分为上述3种类型,其分别代表了更新non-delete-mark的记录,将delete的记录标记为not delete,将记录标记为delete。

紧接着的部分记录update_vector信息,update_vector表示update操作导致发生改变的列。每个修改的列信息都要记录的undo log中。对于不同的undo log类型,可能还需要记录对索引列所做的修改。

Oracle和Microsoft SQL Server数据库都由内部的数据字典来观察当前undo的信息,InnoDB存储引擎在这方面做得还是不够,DBA只能通过原理和经验来进行判断。InnoSQL对information_schema进行了扩展,添加了两张数据字典表,这样用户可以非常方便和快捷地查看undo的信息。

首先增加的数据字典表为INNODB_TRX_ROLLBACK_SEGMENT。顾名思义,这个数据字典表用来查看rollback segment(回滚段)。InnoDB 1.1版本开始,其一共有128个rollback segment,每个rollback segment支持1024个undo log段,因此一共支持128*1024个同时并发在线事务。而之前的版本仅有1个回滚段,故最大支持并发事务为1024。

例如,用户可以通过下面的命令来查看rollback segment所在的页(InnoDB 1.2版本之前,rollback segment都放在共享表空间内,故space值都为0。InnoDB 1.2版本开始支持独立的rollback segment表空间):
  1. mysql> SELECT segment_id,space,page_no FROM INNODB_TRX_ROLLBACK_SEGMENT;
  2. +------------+-------+---------+
  3. | segment_id | space | page_no |
  4. +------------+-------+---------+
  5. |          0 |     0 |       6 |
  6. |          1 |     0 |      45 |
  7. |          2 |     0 |      46 |
  8. ......
  9. 128 rows in set (0.00 sec)
复制代码
另一张数据字典表为INNODB_TRX_UNDO,用来记录事务对应的undo log,方便DBA和开发人员详细了解每个事务产生的undo量。下面将演示如和使用INNODB_TRX_UNDO表,首先根据如下代码创建测试表t。
  1. CREATE TABLE t (
  2.      a INT,
  3.      b VARCHAR(32),
  4.      PRIMARY KEY(a),
  5.      KEY(b)
  6. )ENGINE=InnoDB;
复制代码
接着插入一条记录,并尝试通过INNODB_TRX_UNDO观察该事务的undo log的情况:
  1. mysql> BEGIN;
  2. Query OK, 0 rows affected (0.00 sec)

  3. mysql> INSERT INTO t SELECT 1,’1’;
  4. Query OK, 1 row affected (0.00 sec)
  5. Records: 1  Duplicates: 0  Warnings: 0

  6. mysql> SELECT * FROM information_schema.INNODB_TRX_UNDO\G;

  7. *************************** 1. row ***************************
  8.        trx_id: 3001
  9.       rseg_id: 2
  10.   undo_rec_no: 0
  11. undo_rec_type: TRX_UNDO_INSERT_REC
  12.          size: 12
  13.         space: 0
  14.       page_no: 334
  15.        offset: 272
  16. 1 row in set (0.00 sec)
复制代码
通过数据字典表可以看到,事务ID为3001,rollback segment的ID为2,因为是该条事务的第一个操作,故undo_rec_no为0。之后可以看到插入的类型为TRX_UNDO_INSERT_REC,表示是insert undo log。size表示undo log的大小,占用12字节。最后的space、page_no、offset表示undo log开始的位置。打开文件ibdata1,定位到页(334,272),并读取12字节,可得到如下内容:
  1. 01 1c 0b 00 16 04 80 00 00 01 01 10
复制代码
上述就是undo log实际的内容,之前对于insert undo log格式的介绍,可以整理得到:
  1. 01 1c       # 下一个undo log的位置 272+12=0x011c
  2. 0b          # undo log的类型,TRX_UNDO_INSERT_REC为11
  3. 00          # undo log的记录,等同于undo_rec_no
  4. 16          # 表的ID
  5. 04          # 主键的长度
  6. 80 00 00 01 # 主键的内容
  7. 01 10       # undo log开始的偏移量,272=0x0110
复制代码
此外,由于知道该undo log所在的rollback segment的ID为2,用户还可以通过数据字典表INNODB_TRX_ROLLBACK_SEGMENT来查看当前rollback segment的信息,如:
  1. mysql> SELECT segment_id,insert_undo_list,insert_undo_cached
  2.      -> FROM information_schema.INNODB_TRX_ROLLBACK_SEGMENT
  3.      -> WHERE segment_id=2\G;
  4. *************************** 1. row ***************************
  5.         segment_id: 2
  6.   insert_undo_list: 1
  7. insert_undo_cached: 0
  8. 1 row in set (0.00 sec)
复制代码
可以看到insert_undo_list为1。若这时进行事务的COMMIT操作,再查看该数据字典表:
  1. mysql> COMMIT;
  2. Query OK, 0 rows affected (0.00 sec)

  3. mysql> SELECT segment_id,insert_undo_list,insert_undo_cached
  4.      -> FROM information_schema.INNODB_TRX_ROLLBACK_SEGMENT
  5.      -> WHERE segment_id=2\G;
  6. *************************** 1. row ***************************
  7.         segment_id: 2
  8.   insert_undo_list: 0
  9. insert_undo_cached: 1
  10. 1 row in set (0.00 sec)
复制代码
可以发现,insert_undo_list变为0,而insert_undo_cached增加为1。这就是undo页重用,即下次再有事务需要向该rollback segment申请undo页时,可以直接使用该页。

update undo log较之insert undo log要复杂的多,因此将在第二篇中进行分析。so,预知后事如何,待听下回分解吧

PS:InnoSQL 5.5.30下载地址:https://david-mysql-tools.google ... linux-x86_64.tar.gz
      新浪微博:@insidemysql

论坛徽章:
0
2 [报告]
发表于 2013-05-07 12:24 |只看该作者
顶下姜大大

论坛徽章:
8
CU大牛徽章
日期:2013-09-18 15:20:48CU大牛徽章
日期:2013-09-18 15:20:58CU大牛徽章
日期:2013-09-18 15:21:06CU大牛徽章
日期:2013-09-18 15:21:12CU大牛徽章
日期:2013-09-18 15:21:17天秤座
日期:2013-10-30 14:01:03摩羯座
日期:2013-11-29 18:02:31luobin
日期:2016-06-17 17:46:36
3 [报告]
发表于 2013-05-07 14:43 |只看该作者
@qlks 高手重出江湖了。

论坛徽章:
93
2015年辞旧岁徽章
日期:2019-10-10 10:51:15CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2020-10-15 16:55:55CU大牛徽章
日期:2014-02-21 14:22:07羊年新春福章
日期:2019-10-10 10:51:39CU大牛徽章
日期:2019-10-10 10:55:38季节之章:春
日期:2020-10-15 16:57:40ChinaUnix元老
日期:2019-10-10 10:54:42季节之章:冬
日期:2019-10-10 10:57:17CU大牛徽章
日期:2014-02-21 14:22:52CU大牛徽章
日期:2014-03-13 10:40:30CU大牛徽章
日期:2014-02-21 14:23:15
4 [报告]
发表于 2013-05-08 11:18 |只看该作者
难得见到的版主,这么大的见面礼,拜读拜读。

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-03-12 06:20:00
5 [报告]
发表于 2013-05-08 11:51 |只看该作者

论坛徽章:
0
6 [报告]
发表于 2013-05-15 11:17 |只看该作者
hi:wink::wink::wink::wink::wink:
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP