MySQL Online DDL 原理
MySQL Online DDL 原理
語法:
增加列:
alter table 表名 add column 列名 資料型別, ALGORITHM 演算法; alter table hank add column name1 varchar(16),ALGORITHM INPLACE/COPY/DEFAULT;
不指定演算法:
alter table hank add column name1 varchar(16);
新增索引:
alter table 表名 add index 索引名(列名), ALGORITHM INPLACE; alter table hank add index idx_name(name1) , ALGORITHM INPLACE/COPY/DEFAULT;
不指定演算法:
alter table hank add index idx_name(name1);
註釋:COPY 是 Offline 。 預設情況下,不需要指定演算法,資料庫會自動選擇。
一、MySQL Online DDL COPY
1. alter table hank add column c varchar(122), ALGORITHM=COPY;
2.online ddl copy方式三個階段:
準備階段 -> 執行階段 -> 提交階段
(2.1) 準備階段:
1. 對元資料進行新增共享鎖(MDL-S)[Meta Lock Share],讀取原表結構(不能進行DDL,不阻塞DML,過程很短暫)2. S鎖升級為X鎖(排它鎖),此時阻塞DDL,DML 3. 建立和原表一樣的表結構,server層會執行類似crate table語句建立和原表一致的表結構,在engine層生成frm和ibd檔案
(2.2) 執行階段:
1. 修改新建立的臨時表的表結構 2. 臨時表的表結構修改完,server層copy原表資料到臨時表(阻塞DML) 3. server層替換兩個表,rename臨時表 4. 刪除原表
(2.3) 提交階段:
commit,釋放所有鎖
注:
1. 開始執行到結束,都是上鎖(MDL-X),阻塞DDL,DML,不阻塞SELECT 2. 此類操作不是online DDL,執行階段都是阻塞業務的
二、MySQL Online DDL INPLACE
1. online ddl inplace執行三個階段:
準備階段 -> 執行階段 -> 提交階段
mysql 5.6 開始支援inplace,整個過程都阻塞其它DDL,不阻塞DML
2. inplace 準備階段
(2.1) 準備階段:(準備階段阻塞DML)
1. 在進入prepare階段前,對元資料持有"可升級的S鎖"(MDL-S鎖),在此階段不允許DML,不允許部分DDL,如drop操作 2. 在預備階段MDL-S鎖升級為X鎖(排它鎖),此時會判斷操作是否需要rebuild table 3. 判斷是需要rebuild table還是no rebuild table,判斷完之後進行下一步,如果需要rebuild table,則申請row log空間 row log作用:記錄ONLINE DDL執行階段,對原表的DML操作(row log由innodb_sort_buffer_size決定) ebuild table:則需要在engine層生成原表的轉儲檔案(比如:ibd,frm檔案,DDL階段執行) no reduild table:則要在engine層則只需要生成frm檔案(比如加索引就是no rebuild table,只需要生成frm,DDL階段執行
(2.2) 執行階段:(DDL執行階段不阻塞DML)
1. 執行階段 會把X鎖降級為S鎖,該階段不阻塞dml操作 ,這個階段被稱為online階段 2. MDL-X鎖降級為MDL-S鎖,將原表儲存的資料讀取到prepare階段建立的ibd檔案中(engine層完成,直接分析資料頁,內部結構,將原表的資料記錄逐行取出後進行處理,且會執行ddl修改表結構,並應用到新的ibd檔案中)
(2.3) 提交階段:(commit階段阻塞DML)
1. 提交階段engine層應用row log中的操作到新的ibd檔案中直到最後一個,系統會自動判斷進行截斷,避免源源不斷的DML操作 2. 此時MDL-S鎖再此升級到MDL-X鎖(拒絕所的DML),然後把row log中剩餘的資料應用完 3. 刪除原表,替換新表為原表 4. 最後提交
三、Online DDL 會不會鎖表?
1. 使用者角度看online ddl,在執行ddl期間,不阻塞DML操作
2. DBA角度看:
準備階段 持有X鎖 --> 阻塞DML
執行階段 X鎖降級為S鎖 --> 不阻塞DML
提交階段 S鎖升級為X鎖 --> 阻塞DML
四、COPY 和 INPLACE 區別:
COPY是在server層,INPLACE在engine層(inplace中,不需要通過server層的create語句重建表,但是依然需要在engine層,生成ibd轉儲檔案)
五、如何判斷是offline還是online ?
mysql> alter table hank modify column c varchar(121); Query OK, 5000 rows affected (0.28 sec) # 如果不是0 rows 則是offline DDL
mysql> alter table hank modify column c varchar(122); Query OK, 0 rows affected (0.00 sec) # 如果是0 rows affected 則是online DDL Records: 0 Duplicates: 0 Warnings: 0
轉自:https://www.cnblogs.com/dtxdm/p/15828624.html