全局鎖和表鎖

瞭解MySQL的全局鎖和表級鎖mysql

全局鎖

  • 對整個數據庫實例加鎖
  • 使用場景:作全庫邏輯備份時,爲了保證備份期間的庫在同一個邏輯時間點,即一致性視圖(相似於可重複讀隔離級別的效果)

全局鎖兩種方式:sql

  • Flush tables with read lock(FTWRL) 使數據庫處於只讀狀態,數據的增刪改、數據定義語句和更新類事務的提交語句都會被阻塞
  • mysqldump 官方自帶的邏輯備份工具,參數 -single-transaction 會在導數據以前啓動一個事務,確保拿到一致性視圖

以上兩種方式不一樣點:
使用mysqldump 前提是 引擎支持隔離級別 ,因此single-transaction方法只適用於支持事務引擎的庫;MyISAM不支持事務,因此只能使用FTWRL命令數據庫

set global readonly = true 
複製代碼

這條語句也能夠作到全庫只讀,可是不建議使用:安全

  • 有時readonly會用來判斷庫是主庫仍是備庫,所以修改global變量的方式影響會比較大
  • 異常處理方面:FTWRL後客戶端異常斷開,MySQL會自動釋放全局鎖,庫恢復正常;設置readonly,客戶端異常,則會保持readonly,會致使長時間處於不可寫狀態,風險較高

以上哪一種方式,一個庫被全局上鎖後,對立面任何一個表作字段操做,都會被鎖住的多線程

即便沒有全局加鎖,有了表級鎖,加字段也會遇到問題併發

表級鎖

MySQL有兩種表級別的鎖:一種是表鎖、另外一種是元數據鎖(metadata lock,MDL)工具

表級鎖的語法:lock tables xxx read/write

例如 線程A執行了lock table t1 read,t2 write 效果是 包括A線程在內的全部線程對於t1表只可讀,寫被阻塞;t2表讀寫都被阻塞
lock tables操做能夠用unlock tables主動釋放,也能夠在客戶端斷開的時候自動釋放。post

該操做不只阻塞其餘線程的操做,也阻塞了當前線程的操做學習

對於innoDB這種支持行鎖的引擎,通常不使用lock tables命令控制併發,影響過大spa

另外一種表級鎖:MDL(metadata lock)

MDL在訪問一個表的時候會自動加上,MDL的做用是,保證讀寫的正確性。當表作增刪改查操做時,加MDL讀鎖;當對錶結構變動的時候,加MDL寫鎖。

  • 讀鎖之間不互斥,多線程可對同一張表增刪改查
  • 讀寫鎖之間、寫鎖之間互斥。兩個線程同時給一個表增長字段,則第二個須要等待第一個執行完才能繼續
  • MDL鎖在語句執行開始時申請,事務結束後釋放

如何給小鎖安全的加字段

  • 解決長事務,當作DDL變動的表中正好在執行長事務,則從information_schema庫的innodb_trx找到當前執行長事務,先kill掉長事務或者暫停DDL
  • 比較理想的狀態:修改表結構語句alter table能夠設置等待時間,若是該時間內拿不到MDL鎖,則該時間內拿不到MDL鎖,則放棄執行,不會阻塞後面的語句
    MariaDB/ALiSQL已經支持 DDL NOWAIT/WAIT n 這個語法
alter table tb1_name NOWAIT add column...
alter table tb1_name WAIT N add column...   
複製代碼

總結

對於使用innoDB引擎的庫,建議使用–single-transaction 參數,對應用會更友好。


本文爲極客時間《MySQL實戰45講》 的學習筆記,其中含有部分原文,若有侵權行爲請聯繫我馬上刪除

第一節:一條SQL查詢語句的執行過程

相關文章
相關標籤/搜索