Mysql InnoDB鎖

來源:互聯網
上載者:User

Mysql常用儲存引擎的鎖機制

MyISAM和MEMORY採用表級鎖(table-level locking)

BDB採用頁面鎖(page-leve locking)或表級鎖,預設為頁面鎖

InnoDB支援行級鎖(row-level locking)和表級鎖,預設為行級鎖

各種鎖特點

表級鎖:開銷小,加鎖快;不會出現死結;鎖定粒度大,發生衝突的機率最高,並發度最低

行級鎖:開銷大,加鎖慢;會出現死結;鎖定粒度最小,發生鎖衝突的機率最低,並發度也最高

頁面鎖:開銷和加鎖時間介於表鎖和行鎖之間;會出現死結;鎖定粒度介於表鎖和行鎖之間,並發度一般

InnoDB儲存引擎的鎖

InnoDB儲存引擎實現了如下兩種鎖

1、共用鎖定(S Lock),允許事務讀一行資料

2、獨佔鎖定(X Lock),允許事務更新或者刪除一行資料

共用鎖定和獨佔鎖定的相容如所示

 

一致性的非鎖定讀

一致性的非鎖定行讀(consistent nonlocking read)是指InnoDB儲存引擎通過行多版本控制(multi versioning)的方式來讀取當前執行時間資料庫中行的資料。如果讀取的行正在執行DELETE、UPDATE操作,這是讀取操作不會因此而會等待行上鎖的釋放,相反,InnoDB會去讀取行的一個快照資料。

之所以稱其為非鎖定讀,因為不需要等待訪問的行上X鎖的釋放。快照資料是指改行之前版本的資料,該實現是通過undo段來實現的。但是在不同交易隔離等級下,讀取的方式不同,並不是每個交易隔離等級下讀取的都是一致性讀。

例如:

對於read committed的交易隔離等級,他總是讀取行的最新版本,如果行被鎖定了,則讀取該行版本的最新一個快照。

對於repeatable read(innoDB儲存引擎的預設隔離等級),總是讀取事務開始時的行資料。

 非鎖定讀的機制大大提高了資料讀取的並發性,在Innodb儲存引擎預設設定下,這是預設的讀取方式,但是在某些情況下,可以對讀進行加鎖,比如:

1、顯式對讀進行加鎖,如使用 select --- for update ;select --- lock in share mode

2、在外鍵的插入和更新上,因為在外鍵的插入和更新上,對於資料的隔離性要求較高,在插入前需要掃描父表中的記錄是否存在,所以,在外鍵的插入刪除上,InnoDB會使用加S鎖的方式來實現。

InnoDB鎖的演算法

1、Record Lock:單個行記錄上的鎖

2、Gap Lock:間隙鎖,鎖定一個範圍,但不包含記錄本身

3、Next-key Lock:Gap Lock+Record Lock,鎖定一個範圍,並且鎖定記錄本身

Record Lock總是會去鎖住索引記錄,如果InnoDB儲存引擎表建立的時候沒有設定任何一個索引,這時InnodB儲存引擎會使用隱式的主鍵來進行鎖定,在Repeatable Read隔離等級下,Next-key Lock 演算法是預設的行記錄鎖定演算法。

鎖帶來的問題

1、丟失更新

如何避免丟失更新:讓事務變成串列操作,而不是並發的操作,即對每個事務開始---對讀取記錄加獨佔鎖定。

2、髒讀

髒讀即一個事務可以讀到另一個事務中未提交的資料,這違反了資料庫的隔離性。

髒讀發生的條件是需要事務的隔離等級為Read uncommitted。

3、不可重複讀取

不可重複讀取與髒讀的區別是:髒讀是讀到未提交的資料,而不可重複讀取讀到的是已經提交的資料。

一般來說,不可重複讀取是可以接受的,在InnoDB儲存引擎中,通過使用Next-Key Lock演算法來避免不可重複讀取的問題。

值得注意的是,預設情況下InnoDB儲存引擎不會復原逾時引發的錯誤異常。

死結的相關問題

1、死結發生的條件

互斥條件:一個資源每次只能被一個進程使用;請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放;不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪;迴圈等待條件:若干進程之間形成一種頭尾相接的迴圈等待資源關係。

2、死結檢測(根據網上的經驗)

Innodb檢測死結有兩種情況,一種是滿足迴圈等待條件,還有另一種策略:鎖結構超過mysql配置中設定的最大數量或鎖的遍曆深度超過設定的最大深度時,innodb也會判斷為死結(這是提高效能方面的考慮,避免事務一次佔用太多的資源)。

因迴圈等待條件而產生的死結只有可能是四種形式:兩張表兩行記錄交叉申請互斥鎖、同一張表則存在主鍵索引鎖衝突、主鍵索引鎖與非聚簇索引鎖衝突、鎖定擴大導致的鎖等待隊列阻塞。

3、死結避免(根據網上的經驗)

1.如果使用insert…select語句備份表格且資料量較大,在單獨的時間點操作,避免與其他sql語句爭奪資源,或使用select into outfile加上load data infile代替 insert…select,這樣不僅快,而且不會要求鎖定
2. 一個鎖定記錄集的事務,其操作結果集應盡量簡短,以免一次佔用太多資源,與其他交易處理的記錄衝突。
3.更新或者刪除表格式資料,sql語句的where條件都是主鍵或都是索引,避免兩種情況交叉,造成死結。對於where子句較複雜的情況,將其單獨通過sql得到後,再在更新語句中使用。
4. sql語句的巢狀表格格不要太多,能拆分就拆分,避免佔有資源同時等待資源,導致與其他事務衝突。
5. 對定點運行指令碼的情況,避免在同一時間點運行多個對同一表進行讀寫的指令碼,特別注意加鎖且操作資料量比較大的語句。
6.應用程式中增加對死結的判斷,如果事務意外結束,重新運行該事務,減少對功能的影響。

4、死結解決

1)先執行show processlist找到死結線程號.然後Kill pid

2)Show innodb status檢查引擎狀態 ,可以看到哪些語句產生死結

3)查看information_schema架構下的innodb_locks、innodb_trx、innodb_lock_waits等表

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.