thread 1、begin;
創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供疏附網(wǎng)站建設、疏附做網(wǎng)站、疏附網(wǎng)站設計、疏附網(wǎng)站制作等企業(yè)網(wǎng)站建設、網(wǎng)頁設計與制作、疏附企業(yè)網(wǎng)站模板建站服務,十載疏附做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡服務。
更新表;沒有提交,也沒有回滾操作
thread2、create index 在這個表上
這時候客戶端超時中斷
再次連接會話查詢此表被阻塞,無法查詢
thread3、查詢 select * from test;
root@localhost : yaochong 17:08:27> select id,user,host,db,command,time,state,info from information_schema.processlist where user <>'system user' and info not like '%system user%'; +-------+------+-----------+----------+---------+------+---------------------------------+---------------------------------------------------------------+ | id | user | host | db | command | time | state | info | +-------+------+-----------+----------+---------+------+---------------------------------+---------------------------------------------------------------+ | 10161 | root | localhost | yaochong | Query | 3386 | Waiting for table metadata lock | select * from test | | 10092 | root | localhost | yaochong | Query | 6375 | Waiting for table metadata lock | alter table test add key(name) , ALGORITHM=INPLACE, LOCK=NONE | +-------+------+-----------+----------+---------+------+---------------------------------+---------------------------------------------------------------+ 2 rows in set (0.00 sec)
原因參考如下MDL的讀寫鎖互斥
為什么C等待拿鎖之后,D也會阻塞?其實這里并沒有解釋清楚。因為如果按并發(fā)理解的話,
C,D應當是同等級,都有可能拿到鎖的。但C讀寫鎖互斥,D讀讀不互斥,這樣的話就跟上圖所述相悖了。
就,查了一下。
(鳴謝 一夢如是YFL提供的文章)
首先是MDL(metaData Lock)的概念。元數(shù)據(jù)鎖是server層的鎖,表級鎖,主要用于隔離DML(Data Manipulation Language,數(shù)據(jù)操縱語言,如select)和DDL(Data Definition Language,數(shù)據(jù)定義語言,如改表頭新增一列)操作之間的干擾。 每執(zhí)行一條DML、DDL語句時都會申請MDL鎖, DML操作需要MDL讀鎖,DDL操作需要MDL寫鎖(MDL加鎖過程是系統(tǒng)自動控制,無法直接干預,讀讀共享,讀寫互斥,寫寫互斥)
申請MDL鎖的操作會形成一個隊列,
隊列中寫鎖獲取優(yōu)先級高于讀鎖
。一旦出現(xiàn)寫鎖等待,不但當前操作會被阻塞,同時還會阻塞后續(xù)該表的所有操作。事務一旦申請到MDL鎖后,直到事務執(zhí)行完才會將鎖釋放。(這里有種特殊情況如果事務中包含DDL操作,MySQL會在DDL操作語句執(zhí)行前,隱式提交commit,以保證該DDL語句操作作為一個單獨的事務存在,同時也保證元數(shù)據(jù)排他鎖的釋放,例如id 44的語句改為
這樣就能解釋通為什么session C被阻塞后,session D也運行不了的原因了。
簡而言之MDL鎖互斥,select也要申請MDL的讀鎖,這一點真是有點惡心。