MySQL鎖之源碼探索
來自專欄 攜程技術中心
鎖是計算機程序運行時協調並發訪問同一數據資源的機制。對於資料庫系統來說,數據是一種供許多用戶共享的資源,那麼如何保證數據並發訪問的一致性、有效性是必須解決的一個問題。所以,鎖對於資料庫來說,是非常重要的一個功能。通過各種鎖,實現了資料庫事務中的隔離性。本篇文章將從源碼層面介紹MySQL的元數據鎖和InnoDB的實現。
一、MySQL的架構與鎖
MySQL在架構上分為兩層,服務和存儲引擎層。服務層集中了網路通訊、語法分析和計劃生成等通用功能;存儲引擎層主要負責數據的存儲。元數據的並發管理集中在服務層,數據的並發管理在存儲引擎層。因此對於元數據的鎖在服務層進行實現,數據的隔離特性在存儲引擎層實現。本篇將介紹服務層的元數據鎖的實現,以及現下使用率最高的具有ACID特性的InooDB的數據鎖。
二、元數據鎖
2.1 元數據鎖類型
2.2 元數據鎖申請與釋放
在申請元數據鎖的同時,會指定鎖釋放的時間。在程序執行到指定位置時,如語句執行結束或者事務執行結束,會檢查元數據鎖的上鎖情況,並釋放那些需要在該位置釋放的元數據鎖。
抽象元數據鎖的上鎖和釋放的過程,整理為如下流程圖
2.3 元數據鎖關係
MySQL的元數據也是有從屬關係的。有些元數據進行上鎖的同時,需要配合其他元數據鎖,這裡稱這種關係為從屬關係。這種從屬關係如下圖所示,其箭頭所指方向為元數據鎖所依賴關係。比如在為SCHEMA元數據加鎖時,需要GLOBAL元數據鎖。
2.4 元數據鎖級別
由於對元數據的訪問存在不同的需求,因此設置不同級別鎖級別,用於對元數據及數據的訪問控制。
2.5 元數據鎖源碼
該部分介紹MySQL源碼的主要源文件和主要函數。其中源文件以mdl.h/http://mdl.cc為核心,定義了元數據鎖的主要數據結構和函數,http://lock.cc/sql_db.cc等源文件使用元數據鎖所定義的數據結構和函數。
主要源文件及其關係如下,藍框內所列源文件依賴於紅框內的源文件所定義的內容。
主要函數如下圖關係所列
三、InnoDB鎖
3.1 事務隔離級簡介
存儲引擎InnoDB實現事務的四個隔離級,也就是讀未提交和讀提交等四個事務隔離級。所謂事務隔離級,是並發訪問中控制數據讀寫的方式。在這裡先簡單介紹這四個事務隔離級的來龍去脈,以便於理解MySQL的鎖機制。
InnoDB事務採用不同的鎖機制,會產生不同的現象。
事務隔離級和各種現象的關係,「X」表示在該事務隔離級下現象可發生,「--」表示在該事務隔離級下現象不會發生。
3.2 InnoDB的鎖類型
InnoDB為保護並發訪問下的數據,根據不同的粒度對數據進行。
3.3 InnoDB的鎖級別
InnoDB的鎖
各個級別鎖之間存在兼容性問題,如下表格列出各個級別鎖之間的兼容性。「X」表示不兼容,「O」表示兼容。
3.4 間隙鎖
InnoDB間隙鎖(next-key lock)的用處是在repeatable read的隔離級下防止幻讀現象的出現,所以一定要記住,在其他隔離級下是不會出現間隙鎖的。間隙鎖的原理是在通過對行鎖進行特殊標識(此時的行鎖就被稱為間隙鎖),指出在該範圍內行記錄的左開右閉區間被封鎖,不可進行更新操作。正是採用這種針對行記錄之間間隙上鎖方式,所以稱為間隙鎖或者next-key鎖。
如下圖所示,假設索引中的key值為5、17、23和29。當執行如下SQL:begin; select * from t4 where id2=16 forupdate;會對key:17創建一個行鎖,並標識該行鎖為間隙鎖,其鎖定區間為紅框內6到17,也就是這個區間的值域發生了變化,如果再發生變化可能會影響該區域的數據行集合,所以需要鎖定該區域為不可更新。
3.5 源碼結構
核心代碼包含了有關鎖的宏定義和函數定義等鎖的類型定義和操作定義,應用代碼為使用這些宏和函數的模塊。
【作者簡介】姜宇祥,2012年加入攜程,10年資料庫核心代碼開發經驗,相關開發涉及達夢,MySQL資料庫。現致力於攜程MySQL的底層研發,為特殊問題定位和處理提供技術支持。
更多來自攜程技術人的一手乾貨,歡迎搜索關注「攜程技術中心」微信公號。
推薦閱讀:
※如何使用 MySQL workbench 生成 EER 圖?
※MySQL性能優化、故障排查及最佳實踐秘籍,阿里雲資料庫專家玄慚的「武功」全記錄
※MyCLI :一個支持自動補全和語法高亮的 MySQL/MariaDB 客戶端
※MongoDB 3.0到來
※pandas數據保存至Mysql資料庫
TAG:MySQL |