您的位置:首页 > 数据库 > MySQL

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

2011-12-06 09:35 561 查看
导读目录:

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引擎,十分有帮助。

时间点选择

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

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存储引擎源代码调试跟踪分析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: