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

早期收穫:
1、基本瞭解innodb鎖表模塊功能,與mysql交互,表鎖,行鎖,加鎖,放鎖,死鎖檢測,函數調用邏輯,TNT鎖表模塊能夠參考。
2、基本瞭解innodb事務模塊功能,與上層交互接口,調用方式,事務提交選擇,TNT事務模塊原型已經有底。
3、基本瞭解innodb XA事務,crash recovery流程,與上層接口交互,恢復邏輯,TNT支持binlog的二階段提交,恢復功能能夠作出。
4、瞭解部分函數功能,測試版本innodb的不足之處,能夠在實現TNT引擎過程當中,加以免。
5、其餘…

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存儲引擎源碼解讀系列技術文章的做者:何登成

相關文章
相關標籤/搜索