中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL的全局鎖和表級鎖的具體使用方法

發布時間:2021-08-20 15:37:30 來源:億速云 閱讀:197 作者:chen 欄目:開發技術

這篇文章主要介紹“MySQL的全局鎖和表級鎖的具體使用方法”,在日常操作中,相信很多人在MySQL的全局鎖和表級鎖的具體使用方法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”MySQL的全局鎖和表級鎖的具體使用方法”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

目錄
  • 前言

  • 全局鎖

  • 表級鎖

    • 表鎖

    • 元數據鎖(Metadata Locking,簡稱:MDL鎖)

  • 總結

    前言

    在真實的企業開發環境中使用MySQL,MySQL肯定不會只有我一個人使用,而是一個團隊顯式的使用MySQL,或者是業務隱式的使用MySQL,那么多個用戶或者客戶端連接使用的時候,我們應該考慮一個問題:如果保證數據并發訪問的一致性呢?這一篇我就來聊聊MySQL的鎖,不涉及MySQL的事務隔離級別。

    全局鎖

    MySQL的全局鎖會關閉所有打開的表,并使全部的表處于只讀狀態,它們的命令為:

    # 全局鎖,簡稱FTWRL
    FLUSH TABLES WITH READ LOCK;
    
    # 解鎖命令
    UNLOCK TABLES;

    對FTWRL進行實驗:(以下的所有實驗都是在MySQL8.0.22完成的)

    session1session2
    FLUSH TABLES WITH READ LOCK;
    select * from test limit 1;
    (正常返回結果)


    select * from test limit 1;
    (正常返回結果)
    insert into test(a,b,c) values(6,6,6);
    (報錯)


    insert into test(a,b,c) values(8,8,8);# sql1
    (阻塞)
    UNLOCK TABLES;

    insert into test(a,b,c) values(8,8,8);# sql1
    (session1解鎖后,sql1立馬執行成功)

    從以上實驗可以得出:當執行FTWRL后,所有的表變成了只讀狀態,其他更新的操作將會被阻塞。

    全局鎖的主要作用就是做全庫邏輯備份,也就是把數據庫的每個表都select出來存成文本。

    當備份過程中,整個數據庫處于只讀狀態,風險也是及其的大。如果是在主庫備份,將會導致所有的業務表都不能修改數據;如果是在從庫備份,這個時候從庫不能執行主庫傳過來的binlog,會導致主從延遲。

    好在InnoDB存儲引擎支持事務,mysqldump有一個參數single-transaction,可以在事務中創建一致性快照,然后進行所有表備份。在有這個參數下,備份期間可以進行數據修改,所以正常開發中建議使用InnoDB存儲引擎。

    表級鎖

    表級鎖分為兩種,一種是表鎖,另一種是元數據鎖。

    表鎖

    表鎖分為表讀鎖和表寫鎖,在MySQL的命令是:

    # 表讀鎖
    lock tables test read;
    
    # 表寫鎖
    lock tables test write;

    接下來通過實驗看下表讀鎖和表寫鎖有什么區別吧

    表讀鎖

    session1session2
    lock tables test read;
    select * from test limit1;
    (正常返回結果)


    select * from test limit 1;
    (正常返回結果)
    insert into test(a,b,c) values(6,6,6);
    (報錯)


    insert into test(a,b,c) values(8,8,8); # sql1
    (阻塞)
    unlock tables;

    insert into test(a,b,c) values(8,8,8); # sql1
    (session1解鎖后,sql1立馬寫入成功)

    在session1會話加上了表讀鎖,這個時候session1和session2都可以正常的讀數據,但是session1寫數據會報錯,session2寫數據會被阻塞,等到session1解鎖了,session2的寫數據才能執行成功。

    從這個實驗可以得出:表加上了表讀鎖之后,本線程和其他線程都可以讀數據,本線程寫數據會報錯,其他線程寫數據會阻塞。

    表寫鎖

    session1session2
    lock tables test write;
    select * from test limi1;
    (正常返回結果)


    select * from test limit 1; # sql1
    (阻塞)
    unlock tables;

    select * from test limit; # sql1
    (session1解鎖后,sql1立馬返回結果)
    lock tables test write;
    insert into test(a,b,c) values(6,6,6);
    (插入成功)


    insert into test(a,b,c) values(8,8,8);# sql 2
    (阻塞)
    unlock tables;

    insert into test(a,b,c) values(8,8,8);# sql2
    (session1解鎖后,sql2立馬執行成功)

    從以上實驗可以得出:表加上了表寫鎖之后,本線程可以進行讀寫操作,其他線程的讀寫操作都會被阻塞。

    元數據鎖(Metadata Locking,簡稱:MDL鎖)

    在MySQL中,數據庫的DDL不屬于事務范疇,如果你在session1中select一行數據,這個時候session2給這張表新增了一列xxx,這個時候可能會出現事務特性被破壞、binlog順序錯亂等bug(MySQL官網上有公布出類似的bug,感興趣可以自行去了解)。

    為了解決以上的問題,從MySQL5.5.3引入了元數據鎖,MDL鎖不需要顯式使用,MySQL會默認加上,它的作用就是保證數據庫讀寫正確性。以下全部用MDL表示元數據鎖。

    當你對一張表進行增刪查改的時候會默認加上MDL讀鎖;當你對一張表進行表結構更改的時候會默認加上MDL寫鎖。

    session1session2session3session4
    begin;


    select * from test lmi1;
    (正常返回結果)




    select * from test limit 1;
    (正常返回結果)




    alter table test add d int;
    (阻塞)




    select * from test limit 1;
    (阻塞)

    一開始session1會話查詢test的時候,獲取到了MDL讀鎖,可以正常查詢到數據。然后session2會話查詢數據也會獲取MDL讀鎖,不沖突,也可以正常查詢到數據返回。

    但是到了session3會話的時候,需要獲取MDL寫鎖,這個時候因為session1的MDL讀鎖沒有釋放,所以會阻塞。后面session4也需要MDL讀鎖,但是因為session3被阻塞了,所以session4也會被阻塞。

    假如這是一張線上業務表,這種場景將會使后面的任何操作都失效,表現出來就是這張表變得無法寫和讀。如果客戶端配置了MySQL重試機制的話,會在超時的時候重新建立一個session會話重新請求,然后MySQL就會因為線程不停新增而崩潰。

    從上面的例子可以知道MDL鎖是在語句執行的時候默認加上的,但是語句執行完是不會釋放的,只有等整個事務提交了才會釋放MDL鎖。

    所以對于我們開發者來說,在工作中應該盡量避免慢查詢、盡量保證事務及時提交、避免大事務等,對于DBA來說,也應該盡量避免在業務高峰期執行DDL操作。

    總結

    • 全局鎖會讓所有的表變成只讀狀態,所有更新操作都會被阻塞

    • 表讀鎖是本線程和其他線程都可以讀,本線程寫會報錯,其他線程寫會阻塞

    • 表寫鎖是本線程可以讀寫,其他線程讀寫都會阻塞

    • 引入MDL鎖解決事務和DDL同時執行引發的bug

    到此,關于“MySQL的全局鎖和表級鎖的具體使用方法”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    龙州县| 开平市| 衡山县| 赞皇县| 阳城县| 抚远县| 西乌珠穆沁旗| 绥棱县| 贵溪市| 荣成市| 西和县| 陇川县| 道孚县| 永清县| 清镇市| 托克逊县| 崇义县| 岳阳县| 岳池县| 清河县| 龙海市| 遂平县| 九龙城区| 河间市| 若羌县| 长岭县| 通海县| 白朗县| 叙永县| 江西省| 左云县| 陇川县| 会东县| 闸北区| 崇礼县| 翼城县| 广河县| 南澳县| 含山县| 台南市| 淳安县|