背景
說到mysql 5.5加主鍵導致阻塞源表的讀的問題。
有同學提到從呼叫函式看,在預設的old_alter_table=off的情況下,加主鍵過程沒有看到copy to tmp table。
這裡我們再細說一下。
說說fast index creation
在mysql 5.1以後innodb引入了fast index creation。在有這個feature之前,mysql認為所有的加減索引操作都必須建立臨時表、拷貝資料、刪除源表。
有了這個神奇的功能之後,innodb跟mysql說,稍等,要是加索引,不要你拷貝資料了,「放著我來」。怎麼作的呢?
1) 掃瞄源表,將每行中用於索引的字段取出來
2) 排序構造新索引
3) 插入源表中
這個就是我們說的inplace-ddl了,大家看到,沒有拷貝新錶的操作。效能因此也提高了。這個過程叫做row_merge_build_indexes。
再說說加主鍵
對於innodb來說,資料也是以索引組織的,因此加主鍵,在概念上說,也是加索引。於是在old_alter_table=off的情況下,mysql照著上面的約定,呼叫row_merge_build_indexes。
那麼innodb是不是在源表加主鍵呢?
這顯然不可能。
fast-index-creation的精髓是只需要讀主鍵資料,生成新索引插入到源表中。若加的是主鍵,說明原來沒有定義主鍵(多麼正確的廢話),這時候innodb是使用系統分配的row_id作為主鍵。當我們增加主鍵以後,不可能「構造主鍵,插入源表」----那樣就倆主鍵了。。。
原始碼實現
實際上row_merge_build_indexes有兩個引數(old_table, new_table)。
若新增的索引中不包含主鍵,則new_table == old_tablie,否則不等。
對於不等的情況,這個過程就變成
1) 掃瞄old_table主鍵上的資料
2) 按照新增的索引插入到new_table中
3)
而由於「主鍵」索引的葉子節點,實際上是包含所有資料,所以這個過程,其實就是
copy table。
對於new_table!=old_table的情況,在拷貝資料期間只需要加共享鎖即可,只是5.5下沒有意識到這個問題而已。
MySQL5 5加主鍵鎖讀問題
背景 有同學討論到mysql 5.5下給大表加主鍵時會鎖住讀的問題,懷疑與fast index creation有關,這裡簡單說明下。對照現象 為了說明這個問題的原因,有興趣的同學可以做對比實驗。1 在給innodb表建立主鍵期間,會鎖住該錶上的讀資料 2 但是同樣的表執行刪除主鍵期間,不會鎖住該錶...
MySQL5 5加主鍵鎖讀問題
mysql5.5加主鍵鎖讀問題 背景 有同學討論到mysql 5.5下給大表加主鍵時會鎖住讀的問題,懷疑與fast index creation有關,這裡簡單說明下。對照現象 為了說明這個問題的原因,有興趣的同學可以做對比實驗。1 在給innodb表建立主鍵期間,會鎖住該錶上的讀資料 2 但是同樣的...
mysql5 5 遇到的路徑問題
下面是my.ini裡面的引數 basedir c program files mysql mysql server 6.0 datadir 存放表結構的路徑 innodb data home dir 這個是存放表資料的路徑 ibdata1 存放表資料 你應該是使用的innodb,檢查你的my.cnf...