因爲鎖的內容涉及比較多,會分多篇文章講解。本文主要從鎖的種類講解下,先搞清楚到底有哪些鎖而後咱們後面再根據不一樣鎖不一樣問題來詳細說明。因此如今先把精力放在搞清楚到底有哪些鎖 mysql
Flush tables with read lock;
複製代碼
加上全局所後,整個數據庫就是隻讀的了。 其餘客戶端鏈接後沒法修改數據。須要注意的是,若是加鎖的客戶端斷開鏈接,那麼鎖就會解除。
若是須要備份整個數據庫,那麼可使用全局鎖,使在備份過程當中只容許讀,保障備份數據的一致性。
雖然全局鎖能夠保障備份數據時候的一致性,可是因爲變成只讀,那麼可定會影響業務的進行。咱們也沒見過由於備份數據庫致使線上服務沒法正常工做啊。因此通常狀況下,生成中的確不多用到這個功能,取而代之的是mysqldump 工具,使用–single-transaction 參數,因爲Innodb 的MVCC能力,因此能夠保障備份事數據一致性的同時又不上鎖。(這也是InnoDb 基本取代MyISAM 引擎的緣由之一)sql
咱們都知道MyISAM 與 InnoDB 的一個區別是,MyISAM支持的是表級鎖,而InnoDB能夠支持行級鎖,因此InnoDB 的併發性更好一點。 可是這不意味着這InnoDB中沒有表級鎖。InnoDB 一樣存在表級別鎖
。數據庫
先來看這樣一個場景,我有一張student 表,其中字段有 id,name ,age 三個字段。表中有100萬條數據。假設如今有個長事務正在進行,正在給student表其中5萬人審覈年齡並修改爲正確年齡。若是這個事務要持續1小時。期間,咱們同時須要更新表結構,給student表添加一個address字段。
咱們會發現表結構更新語句會被阻塞,須要等到長事務結束才更新表結構。
那麼更新表結構是被什麼阻塞呢? 顯而易見的時事務更新對應數據的年齡,那麼其中有5萬條數據加上了行級鎖。是被這個行級鎖阻塞的的嗎?其實不是。 這裏Mysql 引入了MDL(metadata lock) 元數據鎖
。簡單來講他是用來鎖表的,是個表級別鎖。MDL也分爲讀鎖和寫鎖。
例子中修改數據時,開始前會先給表student 加 MDL 的讀鎖
,來鎖住整個表,防止表中數據在查詢,修改的時候表的結構被改變
。因爲咱們須要給student表添加字段的時候會給表添加MDL的寫鎖
。這是MDL寫鎖只能等待MDL讀鎖被釋放才能加上去而被阻塞。
概況下MDL 的加鎖規律就是: 表作查詢,修改,新增,刪除時會對錶先加MDL的讀鎖
,而後再加對應的行鎖。 而對表結構作修改
時,會對錶加MDL的寫鎖
。併發
Record Locks (記錄鎖)
能夠分爲讀(S)記錄鎖,和寫(X)記錄鎖。用來鎖住記錄Gap Locks (間隙鎖)
,用來防止幻影Next-Key Locks (Next-Key 鎖)
,記錄鎖和間隙鎖的合體要講解行數的加鎖機制比較麻煩,後續另外一篇文章詳細聊。這裏咱們只要知道InnoDB支持行鎖,而MyISAM 是不支持的。工具
共享鎖能夠同時獲取,而獨佔鎖至於在對象上沒有存在任何鎖
的狀況下能夠獲取
事務A, 查詢
表student 中id 爲1,2,3的數據,那麼事務A就分別給數據1,2,3添加了共享行鎖。
事務B, 查詢
表student 中id 爲1,3,5的數據,那麼事務B就分別給數據1,3,5添加了共享行鎖。
若是事務A,B都未提交,這時候數據1,3分別掛了2把共享鎖。
事務C, 想要修改
表student id 爲 1 的數據,那麼他須要給數據1掛上獨佔鎖,因爲1已經有共享鎖存在,他被掛起等待。
因爲共享鎖和獨佔鎖的特性,就會產生一個死鎖問題
,這個問題我也會另開一篇詳細說明。spa
根據鎖的加鎖範圍咱們能夠有 全局鎖,表鎖(MDL爲表鎖的一種),行鎖。而行鎖又細分紅了幾種不一樣的鎖。 同時無論是表鎖,仍是行鎖可能根據兼容性來分,又會有共享表鎖,獨佔表鎖,共享行鎖,獨佔行鎖等code