數(shù)據(jù)庫鎖機(jī)制簡單來說剂买,就是數(shù)據(jù)庫為了保證數(shù)據(jù)的一致性气笙,使各種共享資源
在被并發(fā)訪問時(shí)變得有序而設(shè)計(jì)的一種規(guī)則得哆。
mysql的鎖機(jī)制比較簡單,最顯著的特點(diǎn)是不同的存儲(chǔ)引擎支持不同的鎖機(jī)制圾浅。
我們所知道掠手,innoDB 支持行鎖,有時(shí)也會(huì)升級(jí)為表所狸捕,myisam 只支持表鎖
表鎖:開銷小喷鸽,加鎖快,不會(huì)出現(xiàn)死鎖現(xiàn)象灸拍,鎖的粒度大做祝,發(fā)生鎖沖突的概率高
并發(fā)支持較低
行鎖:開銷大,加鎖慢鸡岗,會(huì)出現(xiàn)死鎖混槐,鎖的粒度小,發(fā)生鎖沖突的概率低轩性,并發(fā)支
持較高声登;
innoDB鎖的類型
1)讀鎖
類似多線程中的讀寫鎖的讀鎖 一個(gè)事務(wù)獲取到讀鎖之后,別的事務(wù)也可以獲取該
讀鎖揣苏,但是不能獲取到寫鎖
2)寫鎖
類似多線程中的讀寫鎖的寫鎖? 一個(gè)事務(wù)獲得寫鎖之后 其他的事務(wù)不能獲取讀鎖和
寫鎖
3)意向鎖
意向鎖是表級(jí)鎖? 分為意向共享鎖(需要先獲取讀鎖) 和意向排他鎖(需要先獲取寫鎖)
它的作用和MDL鎖類似悯嗓,都是防止在事務(wù)進(jìn)行中,執(zhí)行DDL語句的操作致使數(shù)據(jù)的不一致
4)MDL鎖
事務(wù)開啟之后會(huì)自動(dòng)獲取MDL 鎖卸察, 另外一個(gè)事務(wù)就不能執(zhí)行DDL 語句操作
即不能修改表的結(jié)構(gòu)脯厨, 它用于保證表中元數(shù)據(jù)的信息
innoDB行鎖種類
1)單個(gè)行記錄的鎖
是加載索引項(xiàng)上面的, 當(dāng)同時(shí)操作同一條數(shù)據(jù)的時(shí)候坑质,會(huì)出現(xiàn)鎖競爭和等待
現(xiàn)象合武, 主鍵索引和唯一索引临梗,都是使用的單個(gè)行記錄鎖,同時(shí)RC(讀已提交)
離級(jí)別稼跳,只有行記錄鎖盟庞。
2)間隙鎖
在RR(可重復(fù)讀)隔離級(jí)別中,為了避免出現(xiàn)幻讀岂贩,就使用了間隙鎖茫经,他是一個(gè)
范圍鎖,假如 查詢score<90 的記錄萎津,那么這個(gè)范圍內(nèi)的所有數(shù)據(jù)都不能執(zhí)行數(shù)據(jù)
的修改操作。? 注意:RC(讀已提交)隔離級(jí)別的情況下 間隙鎖不起作用抹镊。
3)記錄鎖和間隙鎖的組合叫做 next-key lock
當(dāng)innoDB掃描索引索引記錄時(shí)锉屈,會(huì)先對(duì)選中的索引記錄加上記錄鎖,然后再
對(duì)索引兩邊的間隙加上間隙鎖垮耳。
如score<80 的范圍 颈渊,同時(shí)也會(huì)再80加上鎖
死鎖
類似多線程死鎖現(xiàn)象。
上述例子 都是使用begin開啟了事務(wù) 而沒有使用commit 提交或者rollback回滾事務(wù)终佛。
生產(chǎn)環(huán)境中如何避免死鎖現(xiàn)象的產(chǎn)生
1)如果多個(gè)不同的程序會(huì)并發(fā) 存取多個(gè)表俊嗽,或者涉及到多行記錄時(shí),盡量約定以相同的順序訪問表铃彰,可以大大降低死鎖的現(xiàn)象绍豁。
2)業(yè)務(wù)中盡量使用小事務(wù),避免使用大事務(wù)牙捉,要及時(shí)提交或者回滾事務(wù)竹揍,可以減少死鎖現(xiàn)象的產(chǎn)生頻率。
3)在同一個(gè)事務(wù)中邪铲,盡可能做到一次鎖定所需要的所有的資源芬位,減少死鎖產(chǎn)生的概率。
4)相對(duì)于非常容易產(chǎn)生死鎖的業(yè)務(wù)部分带到,可以嘗試升級(jí)鎖的粒度昧碉,使用表鎖,來避免死鎖現(xiàn)象的產(chǎn)生揽惹。
鎖的監(jiān)控
通常情況下被饿,當(dāng)出現(xiàn)鎖的問題時(shí),我們習(xí)慣性通過show full processlist 和show engine innodb status 命令來判斷事務(wù)中鎖問題出現(xiàn)的情況永丝。其實(shí)還有三張?zhí)厥獾谋砬率<丛?infomation_schema 庫下的 INNODB_TRX 、INNODB_LOCKS慕嚷、INNODB_LOCK_WITS哥牍。 這三張表可以更方便的來幫助我們監(jiān)控當(dāng)前的事務(wù)毕泌,并分析可能存在的鎖問題。
主要字段的介紹
trx_id :唯一的事務(wù)id
trx_state:當(dāng)前事務(wù)的狀態(tài)嗅辣, lock wait 和running
trx_wait_started:事務(wù)的開始時(shí)間
trx_qurery:事務(wù)運(yùn)行的sql語句
trx_operation_state:事務(wù)的運(yùn)行狀態(tài)
還可以通過查看INNODB_LOCKS 和INNODB_LOCK_WAITS兩張表 來查看 持有鎖和鎖等待的現(xiàn)象撼泛。