MySQL数据库InnoDB存储引擎源代码调试跟踪分析

导读目录:

1       早期结论… 3
2       测试一:死锁检测… 4
3       测试二:cursor测试… 6
4       测试三:external_lock测试… 6
5       测试四:杂项测试… 6
6       测试五:autocommit测试… 7

7       测试六:unlock tables测试… 9
8       测试七:锁等待超时测试… 9
9       测试八:store_lock函数… 10
10         测试九:InnoDB两阶段提交… 12
10.1      autocommit = ON.. 12
10.2      autocommit = off. 14
10.3      flush_at_trx_commit参数处理… 15
11         测试十:InnoDB crash recovery. 15
11.1      recovery的三种模式… 16

12         测试十一:index coverage scan?… 18
13         测试十二:mini transaction.. 18
14         测试十三:事务开始… 19
14.1      autocommit=ON.. 19
14.2      autocommit=OFF. 19
14.3      Innodb内部事务… 20

15         测试十四:insert ignore测试… 20
16         测试十五:auto_increment. 21
17         测试十六:数据格式转换… 23
18         测试十七:innodb加载表数据字典… 23
19         测试十八:scan测试… 24
20         测试十九:加锁等待… 26
21         测试二十:mysql定位table. 27
22         测试二十一:如何做join.. 28
23         测试二十二:latch & lock holding latch.. 28
24         测试二十三:MySQL上层加锁逻辑… 29

25         测试二十四:get_share & free_share. 30
26         测试二十五:Insert on duplicate update. 31
27         测试二十六:purge测试… 32
28         测试二十六(cont.): purge测试续… 32
29         测试二十七:blob & blob purge. 34
30         测试二十八:HA_READ_KEY_EXACT. 35
31         测试二十九:offline_ddl/fast_idx_create. 37
32         测试三十:partition & innoplugin.. 39
33         测试三十一:vs 2008 + mysql5.5. 41
34         测试三十二:ntse online add index. 42
35         测试三十三:group log write & flush.. 43
36         测试三十三(cont.): mutex & event. 44
37         测试三十四:innodb readview测试… 48
38         测试建表三十五: utf8 21845 vs 21846. 49
39         测试三十六:innodb表元数据并发控制… 50
40         测试三十七:ntse引擎Table模块… 53
41         测试三十八:truncate vs drop. 56
42         测试三十九:加锁逻辑 innodb vs ntse. 56
43         测试四十:mysql+ntse实现update. 57
44         测试四十一:Halloween,RBR. 58
45         测试四十二:innodb无主键表… 61

 

本文档主要内容:用于分析InnoDB源代码

目的:
设计TNT事务型引擎,作为参考

实验:
create table tlock (id int primary key, comment varchar(200));
insert into tlock values(1, ‘aaaaaaaaaaaaaaaaa’);
insert into tlock values(2, ‘bbbbbbbbbbbbbbb’);
insert into tlock values(100, ‘zzzzzzzzzzzzzzzzzz’);
insert into tlock values(1000,’AAAAAAAAAAAA’);

版本:
select version();                 5.1.49-debug-log
存储引擎:InnoDB

早期收获:
一、基本了解innodb锁表模块功能,与mysql交互,表锁,行锁,加锁,放锁,死锁检测,函数调用逻辑,TNT锁表模块可以参考。
二、基本了解innodb事务模块功能,与上层交互接口,调用方式,事务提交选择,TNT事务模块原型已经有底。
三、基本了解innodb XA事务,crash recovery流程,与上层接口交互,恢复逻辑,TNT支持binlog的二阶段提交,恢复功能可以做出。
四、了解部分函数功能,测试版本innodb的不足之处,可以在实现TNT引擎过程中,加以避免。
五、其他…

1.早期结论
测试结果比较乱,看起来会比较累,但是基本上说明了innodb的事务/加锁/二阶段提交/crash recovery流程。对设计TNT引擎,十分有帮助。

  1. 时间点选择

a)  表锁,在statement第一次取记录前加(LOCK_IS, LOCK_IX);external_lock函数,仅仅维护表计数(上层mysql对表加锁的计数),而不是真正加锁。

b)  行锁,根据模式,对记录加锁(LOCK_S, LOCK_X)
c)  在加行锁之前,必须保证表级意向锁已经加上
d)  autocommit = ON,Innodb Lock tables不做任何操作,不对表加锁;但是mysql上层会对表加锁。
e)  autocommit=OFF,Innodb Lock tables对表加锁(LOCK_S, LOCK_X);同时mysql上层也会对表加锁。
f)  mysql上层会加表锁,而且保证加锁不会产生死锁;innodb执行statement过程中,只会加LOCK_IS,LOCK_IX表锁锁,不会加LOCK_S,LOCK_X表锁;LOCK_S,LOCK_X表锁,只会在autocommit=OFF时,发出LOCK TABLES指令是才加。innodb没有锁升级。
g)  表意向锁(LOCK_IS,LOCK_IX)的加锁,延迟到statement取第一条记录之前。

2. external_lock函数功能
a)         external_lock函数,顾名思义,外部的锁。对于innodb来说,外部的锁就是上层mysql的锁。statement开始时,mysql上层会对statement涉及到的表加锁,同时调用external_lock函数通知innodb(每个表都调用一次),external_lock函数记录下上层加表锁的数量;statement结束时,mysql上层释放statement涉及到的表锁,同时调用external_lock函数通知innodb,每调用一次,计数减减,当计数到0时,根据当前autocommit设置,判断是否需要自动提交事务(因为mysql上层并不会自动调用commit函数,触发事务提交)。

3.功能测试
a)         加锁流程,每个测试都有加锁流程
b)         commit,放锁流程,详见测试4测试6
c)         事务开始时与mysql的交互,详见测试13
d)         死锁检测流程,详见测试1
e)         Lock节点组织、定位,详见测试4
f)          autocommit参数的影响,详见测试4测试5
g)         lock tables & unlock tables,详见测试6
h)         加锁等待超时 vs 不超时,详见测试7
i)           store_lock函数功能,见测试8,不详尽
j)           innodb二阶段提交支持,见测试9
k)         innodb的crash recovery,见测试10
l)           innodb如何实现auto increment,见测试15

m)       mini transaction的功能,见测试12

  1. InnoDB不足之处

a)         在我测试的版本中,一个kernel mutex,保护server,trx,query threads,lock table,保护的资源太多,会是瓶颈之一。
b)         Innodb二阶段提交,开启binlog,group commit就被自动禁用。极大的增加了fsync调用,降低了并发系统性能,prepare_commit_mutex
c)         死锁检测做的不是很高效。(当然这也与多版本并发控制有关,加锁概率小,锁不会太多)
d)         放锁时,唤醒操作也不是很高效。(挨个遍历需要唤醒的Lock,每个lock又需要与链表前面的lock比较是否冲突)
e)         在发出lock tables命令之后,select … lock in share mode仍旧需要对行记录加锁
f)          锁等待超时innodb_lock_wait_timeout就报错返回,有时会对用户造成困扰 (当然,mysql的应用环境下,都是短小事务,遇见此报错的概率很小)

MySQL数据库InnoDB存储引擎源码解读系列技术文章的作者:何登成

原创文章,转载请注明: 文章地址MySQL数据库InnoDB存储引擎源代码调试跟踪分析


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值