這是我參與8月更文挑戰的第6天,活動詳情查看:8月更文挑戰mysql
MySQL 全局鎖會申請一個全局的讀鎖,對整個庫加鎖。程序員
全局鎖的通常使用場景是:全局邏輯備份。sql
全局鎖的實現方式有兩種:數據庫
//第一種方法
flush tables with read lock(FTWRL)
//第二種方法
set global readonly=true
複製代碼
當數據庫處於全局鎖的狀態時,其餘線程的一下語句會被阻塞:數據更新語句(數據的增刪改)、數據定義語句(建表、索引變動、修改表結構等)和更新類事務的提交語句。markdown
釋放全局鎖架構
unlock tables;
複製代碼
建立數據庫 `test`工具
CREATE TABLE `test` (
`name` varchar(32) NOT NULL DEFAULT '',
`bid` int(10) unsigned NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='測試';
複製代碼
插入數據:oop
insert into test values('A', 1), ('B',2),('C',3);
複製代碼
查看錶數據post
> select * from test;
+------+-----+
| name | bid |
+------+-----+
| A | 1 |
| B | 2 |
| C | 3 |
+------+-----+
複製代碼
加鎖學習
flush tables with read lock;
複製代碼
新增數據
insert into test values('D', 4);
複製代碼
執行 insert 操做後,直接返回錯誤結果:
ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock
複製代碼
執行查詢操做,能夠正常返回結果:
> select * from test;
#返回結果:
+------+-----+
| name | bid |
+------+-----+
| A | 1 |
| B | 2 |
| C | 3 |
+------+-----+
複製代碼
能夠看到,當咱們加上全局鎖的時候,數據及表更新操做都沒辦法執行,但表查詢不受影響。這樣會給咱們的業務形成很大的影響(沒法修改數據),索性 Innodb 引擎的可重複讀隔離級別可讓咱們不阻塞數據變動的同時導出數據。
官方自帶的邏輯備份工具是 mysqldump。當 mysqldump 使用參數–single-transaction 的時候,導數據以前就會啓動一個事務,來確保拿到一致性視圖。而因爲 MVCC 的支持,這個過程當中數據是能夠正常更新的。
你必定在疑惑,有了這個功能,爲何還須要 FTWRL 呢?
一致性讀是好,但前提是引擎要支持這個隔離級別。
好比,對於 MyISAM 這種不支持事務的引擎,若是備份過程當中有更新,老是隻能取到最新的數據,那麼就破壞了備份的一致性。這時,咱們就須要使用 FTWRL 命令了。
single-transaction 方法只適用於全部的表使用事務引擎的庫。
若是有的表使用了不支持事務的引擎,那麼備份就只能經過 FTWRL 方法。這每每是 DBA 要求業務開發人員使用 InnoDB 替代 MyISAM 的緣由之一。
在有些系統中,readonly 的值會被用來作其餘邏輯,好比用來判斷一個庫是主庫仍是備庫。所以,修改 global 變量的方式影響面更大,我不建議你使用。
在異常處理機制上有差別。若是執行 FTWRL 命令以後因爲客戶端發生異常斷開,那麼 MySQL 會自動釋放這個全局鎖,整個庫回到能夠正常更新的狀態。而將整個庫設置爲 readonly 以後,若是客戶端發生異常,則數據庫就會一直保持 readonly 狀態,這樣會致使整個庫長時間處於不可寫狀態,風險較高。
做者:架構精進之路,十年研發風雨路,大廠架構師,CSDN 博客專家,專一架構技術沉澱學習及分享,職業與認知升級,堅持分享接地氣兒的乾貨文章,期待與你一塊兒成長
關注並私信我回復「01」,送你一份程序員成長進階大禮包,歡迎勾搭。
🎉 文章首發於我的公衆號「架構精進之路」,原文連接:用實例帶你瞭解 MySQL 全局鎖
Thanks for reading!