实验:
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’);
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的应用环境下,都是短小事务,遇见此报错的概率很小)