十4、MySQL中的鎖機制 - 系統的擼一遍MySQL

以前在上文已經記錄過鎖的簡單應用今天更深刻的瞭解一下MySQL中的鎖。php

鎖的類型

鎖類型 存儲引擎 特色
表級鎖 MyISAM、MEMORY、InnoDB(非默認) 開銷小,加鎖快,不會死鎖,顆粒大,併發低。
行級鎖 InnoDB 開銷大,加鎖慢,會死鎖,顆粒小,併發高。
頁面鎖 BDB 介於以上兩種之間,會死鎖。

MyISAM中的表級鎖

鎖的模式

表級鎖支持兩種模式,共享讀鎖和獨佔寫鎖。sql

共享讀鎖

READ鎖定後,當前線程不能夠寫入,其餘線程寫入會被阻塞到解鎖後執行,查詢不受影響。併發

獨佔寫鎖

WRITE鎖定後,當前線程能夠插入查詢,其餘進行插入查詢會被阻塞到解鎖後執行。spa

查看錶等待數量.net

//查看錶等待次數
show status like 'table%';

通常會體如今 table_locks_waited中,若是比較高說明發生大量鎖等待。線程

鎖的用法

MySQL執行讀寫操做會自動進行鎖定,通常不須要顯示指定。code

鎖的使用方法能夠參考:鎖的簡單應用blog

LOCK TABLES table_name READ LOCAL;

LOCAL表示容許獲取讀鎖的時候在表結尾進行併發插入。索引

MySQL能夠經過 concurrent_insert 來控制併發插入。進程

concurrent_insert 爲 0 的時候不容許併發插入。

concurrent_insert 爲1 的時候,若是表中不存在空洞能夠在結尾插入。

concurrent_insert 爲 2 的時候,是否有空洞都容許結尾插入。

鎖的調度

若是加鎖的時候已經被其餘線程鎖定,則會阻塞到其餘線程解鎖。

若是兩個進程同時進行讀鎖和寫鎖的請求,那麼寫鎖會優先執行,哪怕讀鎖先到。

咱們能夠經過 low-priorty-updates 參數來設置優先級別。

SET LOW_PRIORITY_UPDATES=1;
SET LOW_PRIORITY_INSERT=1;
SET LOW_PRIORITY_DELETE=1;

經過設置來下降寫的優先級。

同時還能夠經過設置 max_write_lock_count 來實現鎖等待超過必定數量後讀優先,用於避免大量寫操做致使查詢阻塞。

InnoDB中的行幾鎖和事務

事務的ACID原則

原子性

事務做爲一個單獨的處理單元具備原子性,要麼所有執行,要麼所有不執行

一致性

事務的開始和結束都保持一致狀態,事務結束的時候必須保證數據是正確的。

隔離性

併發事務的狀況下,不容許互相影響,每一個事務必須是隔離開的。

持久性

事務一旦提交便永久生效。

併發事務出現的問題

更新丟失

兩個併發事務A和B,A和B同時讀取了數據,A修改數據提交後,B頁修改數據進行提交,會覆蓋A種修改的數據。

髒讀

兩個併發事務A和B,A讀取並修改了數據可是沒有提交,B此時讀取了A修改後的數據並提交,此時A回滾了數據,那麼B提交的數據會成爲髒數據。

不可重複讀

一個事務讀取數據後,再次讀取數據(同一條數據)發現兩次數據不一致。

幻讀

一個事務讀取數據後,再次讀取數據(相同條件讀取的數據),發現其餘事務插入了知足條件的新數據。

事務的4種隔離機制

未提交讀

經過排他鎖避免更新丟失。

這個級別的事務能夠讀取到其餘事務的未提交數據,因此會產生髒讀。

已提交讀

經過排他鎖和共享空間鎖來避免更新丟失和髒讀。

這個級別的事務能夠讀取到其餘事務已經提交的數據,因此屢次讀取會出現「不可重複讀」。

可重複讀

經過排他鎖和共享空間鎖來避免更新丟失和髒讀,在進行讀鎖的時候禁止寫鎖執行,寫鎖的時候禁止任何鎖執行,用於避免重複讀。

可序列化

最爲嚴格的隔離機制,經過串行的方式保證事務一個一個執行。

//查看隔離級別
select @@global.tx_isolation,@@tx_isolation;

查看InnoDB鎖狀態

show status like 'innodb_row_lock%';

經過查看返回結果中 鎖等待次數和平均等待時間來判斷當前鎖情況,若是比較高說明當前鎖競爭嚴重,能夠經過查看 schema.innodb_locks來進一步查詢。

InnoDB的行鎖

共享鎖(S):對一行數據開啓共享鎖,會阻止其餘數據對這行數據開啓排他鎖。

排他鎖(X):得到排他鎖的數據能夠寫數據,其餘數據不能夠得到共享鎖或排他鎖。

爲了兼容表級鎖,實現瞭如下兩種鎖。

意向共享鎖(IS):事務獲得共享鎖以前先取得該鎖。

意向排他鎖(IX):事務獲得排他鎖以前先取得該鎖。

加鎖的模式

InnoDB種不須要顯式的加鎖,會在執行語句時候自動加鎖解鎖。

InnoDB行鎖經過給索引上的索引項加鎖,沒有索引會加載彙集索引上。

三種索引方式

一、Record lock:直接對索引項加鎖

二、Gap lock:對索引項第一條和最後一條的位置加鎖(GAP鎖)用於防止幻讀(RC、RR隔離級別)。

三、Next-key lock:二者結合

InnoDB加鎖若是使用索引(非主鍵),會同時給索引項和彙集索引項加鎖。

範圍查詢的時候會鎖住範圍內的全部索引項。

注意:若是檢索數據沒有經過索引條件檢索(全表掃描),那麼將對錶中全部數據加鎖。

相關文章
相關標籤/搜索