背景
有同學討論到mysql 5.5下給大表加主鍵時會鎖住讀的問題,懷疑與fast index creation有關,這裡簡單說明下。
對照現象
為了說明這個問題的原因,有興趣的同學可以做對比實驗。
1) 在給innodb表建立主鍵期間,會鎖住該錶上的讀資料
2) 但是同樣的表執行刪除主鍵期間,不會鎖住該錶上的讀操作
----這說明與是否fast index creation無關,因為這兩個操作在資料層面的行為應該是類似的,實際上,建立/刪除主鍵都必須copy data。
3) 在建立主鍵期間,會鎖住該錶上執行的show create table
----用1、3的現象可以猜測出,實際上與meta data lock有關。
關於meta data lock(mdl)
mysql 5.5中引入了mdl,當需要訪問、修改表結構時,都需要對meta data加鎖(讀或寫)。比如,當乙個執行緒需要修改表結構的任意一部分時,此時需要阻塞對錶結構的訪問,當然也需要阻塞對資料行的訪問。
加主鍵流程
當對乙個表作加主鍵操作時,大致流程如下
1) mdl加寫鎖
2) 運算元據,最耗時部分,注意需要copy data,因此流程上是
a)建立乙個臨時表a,表a定義為修改後的表結構
b)從原表讀取資料插入表a
c)刪除原表,將表a重新命名為原表名
3) mdl釋放寫鎖
從這個流程可以看到,在最耗時的部分,meta data是被乙個x鎖保護的。因此在此期間,show create table或者select data都是會被阻塞。
這解釋了上面的1) 3)。
刪除主鍵流程
1) mdl加讀鎖
2) 運算元據,最耗時部分
a) 建立乙個臨時表a,表a定義為修改後的表結構
b) 從原表讀取資料插入表a
3) mdl將讀鎖公升級為寫鎖
c) 刪除原表,將表a重新命名為原表名
4) mdl釋放寫鎖
這個在最耗時的資料操作部分,加的是mdl的讀鎖,這樣不會影響訪問原表的表結構或資料(當然要做更新是不行的)。而最後公升級為寫鎖的時間,只是做重新命名表的操作,阻塞的時間就很短。
結論1) 顯然第二個流程更合理
2) 這個可以認為是mysql乙個可改進的點,並且在
5.6下已經改進
3) 這個問題與是copy data還是inplace方式執行ddl無關,實際上由於innodb的聚集索引組織結構,增、刪主鍵都是必須得copy data的。
**********更新====
有同學問說為什麼在5.5 set old_alter_table=on;之後是不會阻塞讀的? 因為開啟old_alter_table之後,mysql認為這次無論如何是要copy data的,所以鎖用的是「
刪除主鍵流程」
的策略。
實際上無論old_alter_table是否開啟,對主鍵操作都是必須copy data的,5.6的改進就是基於這個判斷。
MySQL5 5加主鍵鎖讀問題
mysql5.5加主鍵鎖讀問題 背景 有同學討論到mysql 5.5下給大表加主鍵時會鎖住讀的問題,懷疑與fast index creation有關,這裡簡單說明下。對照現象 為了說明這個問題的原因,有興趣的同學可以做對比實驗。1 在給innodb表建立主鍵期間,會鎖住該錶上的讀資料 2 但是同樣的...
MySQL5 5加主鍵鎖讀問題 續
背景 說到mysql 5.5加主鍵導致阻塞源表的讀的問題。有同學提到從呼叫函式看,在預設的old alter table off的情況下,加主鍵過程沒有看到copy to tmp table。這裡我們再細說一下。說說fast index creation 在mysql 5.1以後innodb引入了f...
mysql5 5 遇到的路徑問題
下面是my.ini裡面的引數 basedir c program files mysql mysql server 6.0 datadir 存放表結構的路徑 innodb data home dir 這個是存放表資料的路徑 ibdata1 存放表資料 你應該是使用的innodb,檢查你的my.cnf...