MySQL的鎖

MySQL的鎖

一. 全局鎖

  1. Flush tables with read lock (FTWRL):這個命令可以加一個全局鎖,讓整個數據庫處於只讀狀態,這樣所有的DDL、DML和更新事務的操作都會被阻塞。
  2. 全局鎖的典型使用場景,是做全庫邏輯備份。
  3. 讓這個庫只讀的風險:
    1. 如果在主庫上備份,那麼在備份期間都不能執行更新,業務基本上就要停擺;
    2. 如果在從庫上備份,那麼備份期間從庫不能執行主庫同步過來的 binlog,會導致主從同步延遲。
  4. 使用FTWRL全局鎖進行數據備份不是一個很好的方式。最好使用MySQL官方提供的mysqldump。mysqldump 使用參數–single-transaction 的時候,導數據之前就會啓動一個事務,來確保拿到一致性視圖。而由於 MVCC 的支持,這個過程中數據是可以正常更新的。**但是single-transaction 方法只適用於所有的表使用了支持事務的存儲引擎的庫。**如果有的表使用了不支持事務的引擎,那麼備份就只能通過 FTWRL進行數據備份。這往往是 DBA 要求業務開發人員使用 InnoDB 替代MyISAM的原因之一。

二. 表級鎖

  1. 表鎖:語法:lock tables … read/write。**需要注意,lock tables 語法除了會限制別的線程的讀寫外,也限定了本線程接下來的操作對象。**比如線程A對錶T加了讀鎖,那麼對錶T的修改會報錯。
  2. MDL(metadata lock)元數據鎖:在 MySQL 5.5 版本中引入了 MDL。MDL是表結構級別的鎖當對一個表中的數據做增刪改查操作是,加MDL讀鎖;當對一個表的結構進行修改時,加MDL寫鎖。這個加鎖是自動的,無需人工干預。
    1. MDL讀鎖之間不互斥,因此你可以有多個線程同時對一張表增刪改查。
    2. MDL讀寫鎖之間、寫鎖之間是互斥的,用來保證變更表結構操作的安全性。因此,如果有兩個線程要同時給一個表加字段,其中一個要等另一個執行完才能開始執行。
  3. MariaDB支持了MDL鎖超時的功能,在超時時間後仍獲取不到MDL鎖就會放棄,不會一直阻塞。

三. 行級鎖

  1. 行級鎖是在引擎層實現的。某些引擎支持行級鎖(如InnoDB),有些則不支持(MyISAM)。
  2. **兩階段鎖協議:在 InnoDB 事務中,行鎖是在需要的時候才加上的,但並不是不需要了就立刻釋放,而是要等到事務結束時才釋放。**因此,如果你的事務中需要鎖多個行,要把最可能造成鎖衝突、最可能影響併發度的鎖儘量往後放。
  3. 死鎖:當併發系統中不同線程出現循環資源依賴,涉及的線程都在等待別的線程釋放資源時,就會導致這幾個線程都進入無限等待的狀態,稱爲死鎖。
  4. 死鎖自動檢測:設置innodb_deadlock_detect = on。當MySQL檢測到死鎖是,會主動回滾死鎖鏈條中的某一個事務,讓其他事務得以繼續執行。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章