MySQL Online DDL 梳理
資料庫需要每天進行很多的DDL,例如新增索引、新增欄位等。對於MySQL資料庫DDL支援的並不是很友好,一不小心就全表鎖。從MySQL 5.6開始支援部分DDL Online操作,不是全部DDL。
一、MySQL DDL 執行原理
不同版本的MySQL,對於DDL的處理方式是不同的,主要有三種:
1、Copy Table方式:這是innodb最早的支援方式。通過臨時表拷貝的方式實現。
原理:新建一個相同表結構的臨時表,將原來的資料全部拷貝到臨時表,然後進行rename,完成建立操作。這個過程中,原表"可讀","不可寫",消耗一倍的儲存空間。
2、Inplace方式:這是原生MySQL 5.5,以及innodb_plugin中提供的方式。
原理:在原表上直接進行,不會拷貝臨時表。原表同樣"可讀
3、Online方式:MySQL5.6以上版本中提供的方式,無論是copy table,還是inplace,原表都是"可讀","不可寫",對應用有很大的限制。MySQL5.6開始innodb開始支援Online DDL,"可讀","可寫"
MySQL DDL 總結:
操作 | 支援方式 | Allow R/W | 說明 |
add/create index | online | 允許讀寫 | 當表上有FULLTEXT索引除外,需要鎖表,阻塞寫 |
add fulltext index |
in-place(5.6以上版本) | 僅支援讀,阻塞寫 |
建立表上第一個fulltext index用copy table方式,除非表上 FTS_DOC_ID 列。
之後建立fulltext index用in-place方式,經過測試驗證,第一次時5.6 innodb 會隱含自動新增 |
drop index |
online | 允許讀寫 | 操作元資料,不涉及表資料。所以很快,可以放心操作 |
optimize table | online | 允許讀寫 |
當帶有fulltext index的表用copy table方式並且阻塞寫 |
alter table...engine=innodb | online | 允許讀寫 |
當帶有fulltext index的表用copy table方式並且阻塞寫 |
add column | online | 允許讀寫,(增加自增列除外) |
1、新增auto_increment列或者修改當前列為自增列都要鎖表,阻塞寫;2、雖採用online方式,但是表資料需要重新組織,所以增加列依然是昂貴的操作,小夥伴尤其注意啦 |
drop column | online | 允許讀寫(增加自增列除外) | 同add column,重新組織表資料,,昂貴的操作 |
Rename a column | online | 允許讀寫 | 操作元資料;不能改列的型別,否則就鎖表(已驗證) |
Reorder columns | online | 允許讀寫 | 重新組織表資料,昂貴的操作 |
Make column NOT NULL
|
online | 允許讀寫 | 重新組織表資料,昂貴的操作 |
Change data type of column | copy table | 僅支援讀,阻塞寫 | 建立臨時表,複製表資料,昂貴的操作(已驗證) |
Set default value for a column | online | 允許讀寫 |
操作元資料,因為default value儲存在frm檔案中,不涉及表資料。所以很快, 可以放心操作 |
alter table xxx auto_increment=xx | online | 允許讀寫 | 操作元資料,不涉及表資料。所以很快,可以放心操作 |
Add primary key | online | 允許讀寫 | 昂貴的操作(已驗證) |
Convert character set | copy table | 僅支援讀,阻塞寫 | 如果新字符集不同,需要重建表,昂貴的操作 |