最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL表結(jié)構(gòu)變更你不可不知的Metadata Lock詳解

 更新時(shí)間:2018年08月14日 10:47:26   作者:iVictor  
這篇文章主要給大家介紹了關(guān)于MySQL表結(jié)構(gòu)變更你不可不知的Metadata Lock的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

想必玩過(guò)mysql的人對(duì)Waiting for table metadata lock肯定不會(huì)陌生,一般都是進(jìn)行alter操作時(shí)被堵住了,導(dǎo)致了我們?cè)趕how processlist 時(shí),看到線(xiàn)程的狀態(tài)是在等metadata lock。本文會(huì)對(duì)MySQL表結(jié)構(gòu)變更的Metadata Lock進(jìn)行詳細(xì)的介紹。

在線(xiàn)上進(jìn)行DDL操作時(shí),相對(duì)于其可能帶來(lái)的系統(tǒng)負(fù)載,其實(shí),我們最擔(dān)心的還是MDL其可能導(dǎo)致的阻塞問(wèn)題。

一旦DDL操作因獲取不到MDL被阻塞,后續(xù)其它針對(duì)該表的其它操作都會(huì)被阻塞。典型如下,如阻塞稍久的話(huà),我們會(huì)看到Threads_running飆升,CPU告警。

mysql> show processlist;
+----+-----------------+-----------+-----------+---------+------+---------------------------------+------------------------------------+
| Id | User | Host | db | Command | Time | State  | Info  |
+----+-----------------+-----------+-----------+---------+------+---------------------------------+------------------------------------+
| 4 | event_scheduler | localhost | NULL | Daemon | 122 | Waiting on empty queue | NULL  |
| 9 | root | localhost | NULL | Sleep | 57 |   | NULL  |
| 12 | root | localhost | employees | Query | 40 | Waiting for table metadata lock | alter table slowtech.t1 add c1 int |
| 13 | root | localhost | employees | Query | 35 | Waiting for table metadata lock | select * from slowtech.t1 |
| 14 | root | localhost | employees | Query | 30 | Waiting for table metadata lock | select * from slowtech.t1 |
| 15 | root | localhost | employees | Query | 19 | Waiting for table metadata lock | select * from slowtech.t1 |
| 16 | root | localhost | employees | Query | 10 | Waiting for table metadata lock | select * from slowtech.t1 |
| 17 | root | localhost | employees | Query | 0 | starting  | show processlist  |
+----+-----------------+-----------+-----------+---------+------+---------------------------------+------------------------------------+
rows in set (0.00 sec)

如果發(fā)生在線(xiàn)上,無(wú)疑會(huì)影響到業(yè)務(wù)。所以,一般建議將DDL操作放到業(yè)務(wù)低峰期做,其實(shí)有兩方面的考慮,1. 避免對(duì)系統(tǒng)負(fù)載產(chǎn)生較大影響。2. 減少DDL被阻塞的概率。 

MDL引入的背景

MDL是MySQL 5.5.3引入的,主要用于解決兩個(gè)問(wèn)題,

RR事務(wù)隔離級(jí)別下不可重復(fù)讀的問(wèn)題

如下所示,演示環(huán)境,MySQL 5.5.0。

session1> begin;
Query OK, 0 rows affected (0.00 sec)

session1> select * from t1;
+------+------+
| id | name |
+------+------+
| 1 | a |
| 2 | b |
+------+------+
rows in set (0.00 sec)

session2> alter table t1 add c1 int;
Query OK, 2 rows affected (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0

session1> select * from t1;
Empty set (0.00 sec)

session1> commit;
Query OK, 0 rows affected (0.00 sec)

session1> select * from t1;
+------+------+------+
| id | name | c1 |
+------+------+------+
| 1 | a | NULL |
| 2 | b | NULL |
+------+------+------+
rows in set (0.00 sec)

可以看到,雖然是RR隔離級(jí)別,但在開(kāi)啟事務(wù)的情況下,第二次查詢(xún)卻沒(méi)有結(jié)果。

主從復(fù)制問(wèn)題

包括主從數(shù)據(jù)不一致,主從復(fù)制中斷等。

如下面的主從數(shù)據(jù)不一致。

session1> create table t1(id int,name varchar(10)) engine=innodb;
Query OK, 0 rows affected (0.00 sec)

session1> begin;
Query OK, 0 rows affected (0.00 sec)

session1> insert into t1 values(1,'a');
Query OK, 1 row affected (0.00 sec)

session2> truncate table t1;
Query OK, 0 rows affected (0.46 sec)

session1> commit;
Query OK, 0 rows affected (0.35 sec)

session1> select * from t1;
Empty set (0.00 sec)

再來(lái)看看從庫(kù)的結(jié)果

session1> select * from slowtech.t1;
+------+------+------+
| id | name | c1 |
+------+------+------+
| 1 | a | NULL |
+------+------+------+
row in set (0.00 sec)

看看binlog的內(nèi)容,可以看到,truncate操作記錄在前,insert操作記錄在后。

# at 7140
#180714 19:32:14 server id 1 end_log_pos 7261 Query thread_id=31 exec_time=0 error_code=0
SET TIMESTAMP=1531567934/*!*/;
create table t1(id int,name varchar(10)) engine=innodb
/*!*/;

# at 7261
#180714 19:32:30 server id 1 end_log_pos 7333 Query thread_id=32 exec_time=0 error_code=0
SET TIMESTAMP=1531567950/*!*/;
BEGIN
/*!*/;
# at 7333
#180714 19:32:30 server id 1 end_log_pos 7417 Query thread_id=32 exec_time=0 error_code=0
SET TIMESTAMP=1531567950/*!*/;
truncate table t1
/*!*/;
# at 7417
#180714 19:32:30 server id 1 end_log_pos 7444 Xid = 422
COMMIT/*!*/;

# at 7444
#180714 19:32:34 server id 1 end_log_pos 7516 Query thread_id=31 exec_time=0 error_code=0
SET TIMESTAMP=1531567954/*!*/;
BEGIN
/*!*/;
# at 7516
#180714 19:32:24 server id 1 end_log_pos 7611 Query thread_id=31 exec_time=0 error_code=0
SET TIMESTAMP=1531567944/*!*/;
insert into t1 values(1,'a')
/*!*/;
# at 7611
#180714 19:32:34 server id 1 end_log_pos 7638 Xid = 421
COMMIT/*!*/;

如果會(huì)話(huà)2執(zhí)行的是drop table操作,還會(huì)導(dǎo)致主從中斷。

有意思的是,如果會(huì)話(huà)2執(zhí)行的是alter table操作,其依舊會(huì)被阻塞,阻塞時(shí)間受innodb_lock_wait_timeout參數(shù)限制。

mysql> show processlist;
+----+------+-----------+----------+---------+------+-------------------+---------------------------+
| Id | User | Host | db | Command | Time | State  | Info   |
+----+------+-----------+----------+---------+------+-------------------+---------------------------+
| 54 | root | localhost | NULL | Query | 0 | NULL  | show processlist  |
| 58 | root | localhost | slowtech | Sleep | 1062 |   | NULL   |
| 60 | root | localhost | slowtech | Query | 11 | copy to tmp table | alter table t1 add c1 int |
+----+------+-----------+----------+---------+------+-------------------+---------------------------+
rows in set (0.00 sec)

MDL的基本概念

首先,看看官方的說(shuō)法,

To ensure transaction serializability, the server must not permit one session to perform a data definition language (DDL) statement on a table that is used in an uncompleted explicitly or implicitly started transaction in another session.

The server achieves this by acquiring metadata locks on tables used within a transaction and deferring release of those locks until the transaction ends.

A metadata lock on a table prevents changes to the table's structure.

This locking approach has the implication that a table that is being used by a transaction within one session cannot be used in DDL statements by other sessions until the transaction ends.

從上面的描述可以看到,

1. MDL出現(xiàn)的初衷就是為了保護(hù)一個(gè)處于事務(wù)中的表的結(jié)構(gòu)不被修改。

2. 這里提到的事務(wù)包括兩類(lèi),顯式事務(wù)和AC-NL-RO(auto-commit non-locking read-only)事務(wù)。顯式事務(wù)包括兩類(lèi):1. 關(guān)閉AutoCommit下的操作,2. 以begin或start transaction開(kāi)始的操作。AC-NL-RO可理解為AutoCommit開(kāi)啟下的select操作。

3. MDL是事務(wù)級(jí)別的,只有在事務(wù)結(jié)束后才會(huì)釋放。在此之前,其實(shí)也有類(lèi)似的保護(hù)機(jī)制,只不過(guò)是語(yǔ)句級(jí)別的。

需要注意的是,MDL不僅僅適用于表,同樣也適用于其它對(duì)象,如下表所示,其中,"等待狀態(tài)"對(duì)應(yīng)的是"show processlist"中的State。

 

為了提高數(shù)據(jù)庫(kù)的并發(fā)度,MDL被細(xì)分為了11種類(lèi)型。

  • MDL_INTENTION_EXCLUSIVE
  • MDL_SHARED
  • MDL_SHARED_HIGH_PRIO
  • MDL_SHARED_READ
  • MDL_SHARED_WRITE
  • MDL_SHARED_WRITE_LOW_PRIO
  • MDL_SHARED_UPGRADABLE
  • MDL_SHARED_READ_ONLY
  • MDL_SHARED_NO_WRITE
  • MDL_SHARED_NO_READ_WRITE
  • MDL_EXCLUSIVE

常用的有MDL_SHARED_READ,MDL_SHARE D_WRITE及MDL_EXCLUSIVE,其分別用于SELECT操作,DML操作及DDL操作。其它類(lèi)型的對(duì)應(yīng)操作可參考源碼sql/mdl.h。

對(duì)于MDL_EXCLUSIVE,官方的解釋是,

/*
An exclusive metadata lock.
A connection holding this lock can modify both table's metadata and data.
No other type of metadata lock can be granted while this lock is held.
To be used for CREATE/DROP/RENAME TABLE statements and for execution of
certain phases of other DDL statements.
*/

簡(jiǎn)而言之,MDL_EXCLUSIVE是獨(dú)占鎖,在其持有期間是不允許其它類(lèi)型的MDL被授予,自然也包括SELECT和DML操作。

這也就是為什么DDL操作被阻塞時(shí),后續(xù)其它操作也會(huì)被阻塞。

關(guān)于MDL的補(bǔ)充

1. MDL的最大等待時(shí)間由lock_wait_timeout參數(shù)決定,其默認(rèn)值為31536000(365天)。在使用工具進(jìn)行DDL操作時(shí),這個(gè)值就不太合理。事實(shí)上,pt-online-schema-change和gh-ost對(duì)其就進(jìn)行了相應(yīng)的調(diào)整,其中,前者60s,后者3s。

2. 如果一個(gè)SQL語(yǔ)法上有效,但執(zhí)行時(shí)報(bào)錯(cuò),如,列名不存在,其同樣會(huì)獲取MDL鎖,直到事務(wù)結(jié)束才釋放。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • 解讀MySQL的客戶(hù)端和服務(wù)端協(xié)議

    解讀MySQL的客戶(hù)端和服務(wù)端協(xié)議

    這篇文章主要介紹了MySQL的客戶(hù)端和服務(wù)端協(xié)議的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下
    2021-05-05
  • 虛擬機(jī)linux端mysql數(shù)據(jù)庫(kù)無(wú)法遠(yuǎn)程訪(fǎng)問(wèn)的解決辦法

    虛擬機(jī)linux端mysql數(shù)據(jù)庫(kù)無(wú)法遠(yuǎn)程訪(fǎng)問(wèn)的解決辦法

    最近在項(xiàng)目搭建過(guò)程中遇到一問(wèn)題,有關(guān)虛擬機(jī)linux端mysql數(shù)據(jù)庫(kù)無(wú)法遠(yuǎn)程訪(fǎng)問(wèn),通過(guò)查閱相關(guān)數(shù)據(jù)庫(kù)資料問(wèn)題解決,下面把具體的解決辦法分享給大家,有需要的朋友可以參考下
    2015-08-08
  • MySql 存儲(chǔ)引擎和索引相關(guān)知識(shí)總結(jié)

    MySql 存儲(chǔ)引擎和索引相關(guān)知識(shí)總結(jié)

    這篇文章主要介紹了MySql 存儲(chǔ)引擎和索引相關(guān)知識(shí)總結(jié),文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • mysql實(shí)現(xiàn)自增序列的示例代碼

    mysql實(shí)現(xiàn)自增序列的示例代碼

    這篇文章主要介紹了mysql實(shí)現(xiàn)自增序列的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • mysql 5.6.23 winx64.zip安裝詳細(xì)教程

    mysql 5.6.23 winx64.zip安裝詳細(xì)教程

    這篇文章主要介紹了mysql 5.6.23 winx64.zip安裝詳細(xì)教程,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-02-02
  • MySQL實(shí)現(xiàn)去重的幾種方法小結(jié)

    MySQL實(shí)現(xiàn)去重的幾種方法小結(jié)

    在MySQL中,SELECT DISTINCT 和 GROUP BY 可以用來(lái)去除重復(fù)記錄,二者有相似的功能,但在某些情況下有所不同,本文將通過(guò)代碼示例給大家詳細(xì)介紹這幾種方法,感興趣的小伙伴跟著小編一起來(lái)看看吧
    2024-07-07
  • mysql優(yōu)化之query_cache_limit參數(shù)說(shuō)明

    mysql優(yōu)化之query_cache_limit參數(shù)說(shuō)明

    query_cache_limit指定單個(gè)查詢(xún)能夠使用的緩沖區(qū)大小,缺省為1M,一般不需要優(yōu)化
    2021-07-07
  • MySQL優(yōu)化教程之慢查詢(xún)?nèi)罩緦?shí)踐

    MySQL優(yōu)化教程之慢查詢(xún)?nèi)罩緦?shí)踐

    在MySQL中慢查詢(xún)?nèi)罩局饕脕?lái)記錄響應(yīng)時(shí)間超過(guò)閾值的SQL,下面這篇文章主要給大家介紹了關(guān)于MySQL優(yōu)化教程之慢查詢(xún)?nèi)罩镜南嚓P(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • MySQL?數(shù)據(jù)庫(kù)范式化設(shè)計(jì)理論總結(jié)

    MySQL?數(shù)據(jù)庫(kù)范式化設(shè)計(jì)理論總結(jié)

    這篇文章主要介紹了MySQL?數(shù)據(jù)庫(kù)范式設(shè)計(jì)理論總結(jié),數(shù)據(jù)庫(kù)的規(guī)劃化范式設(shè)計(jì),在邏輯結(jié)構(gòu)上可以讓結(jié)構(gòu)更加細(xì)粒度,容易理解,下文我們就來(lái)了解具體的內(nèi)容介紹吧
    2022-04-04
  • Navicat配置mysql數(shù)據(jù)庫(kù)用戶(hù)權(quán)限問(wèn)題

    Navicat配置mysql數(shù)據(jù)庫(kù)用戶(hù)權(quán)限問(wèn)題

    這篇文章主要介紹了Navicat配置mysql數(shù)據(jù)庫(kù)用戶(hù)權(quán)限問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03

最新評(píng)論

左云县| 安塞县| 祁门县| 卢氏县| 马尔康县| 沧州市| 宜春市| 古田县| 潍坊市| 启东市| 扶余县| 乌兰县| 中宁县| 宁河县| 北京市| 拉孜县| 同仁县| 遂溪县| 虹口区| 门源| 玉田县| 普宁市| 永川市| 微博| 米易县| 哈尔滨市| 乐亭县| 揭西县| 赤城县| 安化县| 琼结县| 石林| 石渠县| 乌审旗| 岳阳市| 石泉县| 西平县| 攀枝花市| 同仁县| 抚顺县| 渑池县|