MySQL全局鎖和表鎖

  • MySQL爲處理併發問題提出數據庫鎖設計
    • 根據加鎖的範圍,MySQL裏面的鎖能夠大體分爲全局鎖、表級鎖和行鎖三類。
  • 全局鎖
    • 就是對整個數據庫實例加鎖。MySQL提供了一個加全局鎖的方法,命令是:
    • Flush tables with read lock (FTWRL)
    • 這個語句讓數據庫處於只讀狀態,其餘的線程的如下語句會被阻塞:數據更新語句(數據的增刪查改)、數據定義語句(包括建表、修改表結構等)和更新事務的提交語句。
  • 全局鎖的典型使用場景是,作全庫邏輯備份。也就是把數據庫的每一個表都select出來存成文本。
    • 讓整個數據庫只讀的弊端
      一、若是在主庫上備份,在備份期間不能執行更新,業務基本上就得停擺;
      二、若是在從庫上備份,那麼備份期間從庫不能執行主庫同步過來的binlog,致使主從延遲。
    • 如何備份數據庫還能不影響數據庫的正常功能?
      在可重複讀隔離級別下開啓一個事務。
      官方自帶的邏輯備份工具是mysqldump,使用參數是single-transaction的時候,導數據以前就會啓動一個事務,來確保拿到一致性視圖。因爲MVCC的支持,這個過程當中數據是能夠正常更新的。
      single-transaction方法只適用於全部的表使用事務引擎的庫。

 

  • 何時須要FTWRL呢?
    • 一致性讀是好,可是前提是引擎要支持這個隔離級別。對於MyISAM這種不支持事務引擎的,就須要使用FTWRL

 

 

  • 爲何使用FTWRL而不是其它全庫只讀功能?好比set global readonly = true的方式?
    • 一、有些系統中,readonly的值會被用來作其餘邏輯,好比用來判斷一個庫是主庫仍是備庫。修改global變量的方式影響面更大。
    • 二、在異常處理機制上有差別。執行FTWRL這個命令的客戶端異常斷開,那麼MySQL會自動釋放這個全局鎖。而整個庫設置爲readonly以後,若是客戶端發生異常,則數據庫就會一直保持readonly狀態。

 

 

表級鎖,MySQL的表級鎖也分爲兩種:一種是表鎖,一種是元數據鎖(meta data lock,MDL)mysql

 

 

  • 表鎖:
    • 表鎖的語法是:lock tables ... read/write。
    • lock tables 語法即能限制其餘線程的讀寫操做,也能限制本線程接下來的讀寫操做。
    • 沒有更細粒度的鎖的時候,表鎖能夠用來處理併發的方式。InnoDB支持行鎖,因此就不須要使用表鎖了。

 

元數據鎖MDL(metadata lock)
  • MDL不須要顯示使用,在訪問一個表的時候會被自動加上。
  • 在MySQL 5.5版本中引入了MDL,當對一個表作增刪查改操做的時候,加MDL讀鎖;當對錶結構變動操做的時候,加MDL寫鎖。

 

 

  • 讀鎖之間不互斥

 

 

  • 讀寫鎖之間、寫鎖之間是互斥的。

 

 

給一個小表加個字段,致使整個庫掛了?

 

如圖所示,sessionA和sessionB不會互斥,可是sessionC在讀鎖沒有釋放的時候請求MDL寫鎖,就會阻塞,那後面須要寫鎖的也被阻塞了,若是這個表的查詢操做還很是頻繁,並且客戶端有重試機制,這個庫的線程很快就會爆滿,這個庫就崩掉了。
  • 如何安全的給小表加個字段?
    • 一、解決長事務、事務不提交,就會一直佔着MDL鎖。MySQL的information_schema庫的innodb_trx表中,能夠查找到當前執行中的事務。
    • 比較理想的機制是,在alter table語句裏面設定等待時間,若是在等待時間內拿到MDL寫鎖最好,拿不到就放棄。之後重試。
    • MariaDB已經合併AliSQL的這個功能,因此這兩個開源分支項目都支持DLL NOWAIT/WAIT n這個語法。
    • ALTER TABLE tbl_name NOWAIT add column ...
ALTER TABLE tbl_name WAIT N add column ... 
  • 四個數據庫設計語言:DDL(數據定義語言)、DML(數據操做語言)、DCL(數據控制語言)、TCL(事務控制語言)
  • MVCC
MVCC(Multi-Version Concurrency Control)即多版本併發控制。
MySQL的大多數事務型(如InnoDB,Falcon等)存儲引擎實現的都不是簡單的行級鎖。基於提高併發性能的考慮,他們通常都同時實現了MVCC。當前不只僅是MySQL,其它數據庫系統(如Oracle,PostgreSQL)也都實現了MVCC。值得注意的是MVCC並無一個統一的實現標準,因此不一樣的數據庫,不一樣的存儲引擎的實現都不盡相同。
  • 小結
    • 若是你發現你的應用程序裏有lock tables這樣的語句,須要追查一下,比較可能的狀況是:
      一、要麼是系統再用MyISAM這類不支持事務的引擎,要安排升級換引擎;
      二、引擎升級了,代碼尚未升級。把lock tables 和 unlock tables 改爲begin 和commit,問題就解決了。
  • 思考
    備份通常都會在備庫上進行,在用single-transaction方法作邏輯備份的過程當中,若是主庫上的一個小表作了一個DDL,好比給表加了一列,這時候,從備庫上會看到什麼現象?
相關文章
相關標籤/搜索