1. 鎖分類 MySQL中主要分為全局鎖、表級鎖和行鎖三類。本篇主要涉及全局鎖和表級鎖。 2. 全局鎖 全局鎖是對整個資料庫實例進行加鎖。 Flush table with read lock(FRTWRL)該命令用於加全局鎖。使用該命令之後,整個庫處於只讀狀態,不能執行數據的增刪改查、建表、修改表 ...
1. 鎖分類
MySQL中主要分為全局鎖、表級鎖和行鎖三類。本篇主要涉及全局鎖和表級鎖。
2. 全局鎖
全局鎖是對整個資料庫實例進行加鎖。
Flush table with read lock(FRTWRL)該命令用於加全局鎖。使用該命令之後,整個庫處於只讀狀態,不能執行數據的增刪改查、建表、修改表和更新類事務的提交操作。
使用命令unlock tables接觸鎖。
全局鎖的典型使用場景是做全庫的數據備份。不加全局鎖備份的話,備份系統拿到的不是一個邏輯時間點的庫,這個視圖邏輯是不一致的。
在可重覆讀隔離級別下,開啟一個事務,那麼這個事務裡裡面的操作看到的數據是一致的。
官方自帶的邏輯備份工具是mysqldump。當mysqldump 使用參數-single-transaction的時候,導出數據的時候,會啟動一個事務,**來確保拿到一致性視圖。**但此功能需要引擎支持這個隔離級別。
set global readonly=true也可以讓全庫進入到只讀狀態。但還是建議使用FRTWRL進行操作,主要是因為:
readonly的值會被用來做其他邏輯,比如判斷一個庫是否是主庫
異常機制有差別。如果執行FRTWRL命令之後由於客戶端發生異常斷開,那麼MySQL會自動釋放這個全局鎖;如果是readonly方式,異常之後,資料庫一直保存readonly狀態。
3. 表級鎖
MySQL中的表級鎖有兩種,分別是表鎖和元數據鎖(meta data lock,MDL)
3.1 表鎖
表級鎖的語法是lock tables ... read/write.使用unlock tables主動釋放鎖,也可以在客戶端斷開的時候自動釋放。
lock tables除了會限制別的線程的讀寫外,也限定了本線程的接下來的操作對象。比如:在某個線程A中執行lock tables t1
read,t2 write;這個語句,則其他線程寫t1、讀寫t2的語句都會被阻塞。同時A線程在執行unlock
tables;之前,也只能執行讀t1、讀寫t2的操作且不能訪問其他表。
鏈接:https://pan.baidu.com/s/1v5gm7n0L7TGyejCmQrMh2g 提取碼:x2p5
免費分享,但是X度限制嚴重,如若鏈接失效點擊鏈接或搜索加群 群號936682608。
3.2 元數據鎖
MySQL 5.5 中引入,不需要顯示使用,在訪問表的時候會被自動加上。當對一個表進行增刪改查的時候,加MDL讀鎖;當對錶結構進行修改時,加MDL寫鎖。
讀鎖之間不互斥,因此可以有多個線程對一張表增刪改查
讀寫鎖之間、寫鎖之間互斥
4. 修改表結構導致資料庫掛了的示例
41. 現象
假設有以下的一個操作
可以看到session A啟動一個事務,並做了一次查詢操作,但是還沒有提交,這個時候會對錶t加一個MDL讀鎖;此時session
B啟動,由於session B也是查詢操作,需要的是MDL讀鎖,可以正常執行;session C是修改操作,需要MDL寫鎖,但因為session
A的MDL沒有釋放,所以session C會被阻塞,session D查詢操作,也需要個MDL讀鎖,但是因為session
C的寫鎖被堵塞,所以session D也會被阻塞,這個t表的完全不可讀了。
如果這個表上的查詢很頻發,而且客戶端有重試機制,超時之後會再起一個session 查詢,這個庫的鏈接很快就被戰滿而爆掉。
4.2 解決方式
跟蹤事務表information_schema庫的innodb_trx,在執行表結構變動之前,查看是否有長事務在執行。
在MariaDB、AliDB支持在alter table語句裡面設定等待時間
1 2 |
alter table table_name NOWAIT add column ...
alter table table_name WAIT add column ...
|