online ddl是mysql 5.6版本新增的功能,之前版本做ddl,為了避免堵塞DML一般都是選擇pt-osc工具,或者是采用主從滾動操作的方式。采用滾動的方式,操作復(fù)雜,采用pt-osc工具則有一些限制,比如表需要主鍵或者唯一鍵,否則不予執(zhí)行,而且觸發(fā)器在一定情況下會導(dǎo)致死鎖,對業(yè)務(wù)有一定的影響。mysql 5.6版本的online ddl則避免了上述限制,能夠在不堵塞DML的前提下進(jìn)行。online ddl指的是innodb表,而不是myisam表。下面是測試過程,以及online ddl的限制。
根據(jù)我們?nèi)粘3R姷膁dl操作進(jìn)行測試:
原表:
?CREATE TABLE `online_test` (
? `id` bigint(20) NOT NULL AUTO_INCREMENT,
? `c1` bigint(20) DEFAULT NULL,
? `c2` bigint(20) DEFAULT NULL,
? PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1.增加字段
alter table online_test add column?c3 int;
不堵塞讀寫,同時表會rebuild,磁盤空間增加原表大表的一倍,整個過程中,會產(chǎn)生一個臨時表。即使指定algorithm=inplace也是需要rebuild,執(zhí)行時間和表大表有關(guān)
在操作完成之前,新加的列不能使用
如果指定algorithm=copy,則會堵塞寫
2.刪除字段
alter table online_test drop c3;
不堵塞讀寫,同時表會rebuild,磁盤空間增加原表大表的一倍,整個過程中,會產(chǎn)生一個臨時表。即使指定algorithm=inplace也是需要rebuild,執(zhí)行時間和表大表有關(guān)。
在ddl完成之前,刪除列還能繼續(xù)使用。
如果指定algorithm=copy,則會堵塞寫
3.更改字段類型
alter table online_test modify c3 varchar(20);
整個過程堵塞寫,Waiting for table metadata lock .磁盤空間增加原表大表的一倍,整個過程中,會產(chǎn)生一個臨時表。執(zhí)行時間和表大表有關(guān)
不能指定algothm=inplace,報錯:ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
4.更改字段默認(rèn)值
alter table online_test modify c3 varchar(20) default 'test';
不堵塞讀寫,同時整個過程非常迅速,基本不消耗時間
5.添加secondary key
alter table online_test add key(c3)
不堵塞讀寫,同時表不會rebuild,也就是磁盤空間并不需要增加一倍,但是還是會產(chǎn)生一個臨時的frm文件。
如果指定algorithm=copy,則會堵塞讀寫,同時表需要rebuild??臻g增加
6.更改字段名字段,類型不變
alter table online_test change c7 c8 int;
不堵塞,而且很快,基本不消耗時間
7.更改字段名字段,類型改變
alter table online_test change c8 c7 varchar(20);
堵塞寫,同時表rebuild,空間增加
8.刪除secondary key
alter table online_test drop key c7;
不堵塞讀寫,同時很快完成,基本不消耗時間
9.增加主鍵
alter table online_test add primary key(id)
不堵塞讀寫,表需要rebuild,空間增加
10.刪除主鍵
alter table online_test drop primary key;
堵塞寫,Waiting for table metadata lock .磁盤空間增加原表大表的一倍,整個過程中,會產(chǎn)生一個臨時表。執(zhí)行時間和表大表有關(guān)
11.增加自增字段
堵塞寫,Waiting for table metadata lock .磁盤空間增加原表大表的一倍,整個過程中,會產(chǎn)生一個臨時表。執(zhí)行時間和表大表有關(guān)
12.將普通key調(diào)整為主鍵
不堵塞讀寫,但是表會rebuild的,因此會產(chǎn)生臨時表,磁盤空間會增加,執(zhí)行時間和表大小有關(guān)。
13.去除字段的自增屬性
堵塞寫,Waiting for table metadata lock .同時表會rebuild
14.更改表的主鍵(同一條語句刪除舊主鍵,添加新主鍵)
不堵塞讀寫,但是表會rebuild
15.變更表的字符集(ALTER TABLE online_test CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;)
不堵塞讀寫,同時很快完成,基本不消耗時間
16.optimize table
不堵塞讀寫。optimize對innodb表采用的是rebuild+analyze 方式,因此磁盤空間增加。
17.analyze table
不堵塞讀寫,而且操作很快完成,基本不消耗時間
18.修改字段屬性為自增
堵塞寫,同時表會rebuild
基本日常的DDL操作都能覆蓋了,歸納如下:
堵塞寫的操作:
? ? 指定algorithm=copy的都會導(dǎo)致堵塞寫
? ? 指定lock=exclusive都會導(dǎo)致堵塞寫
? ? 更改字段類型
? ? change更改列名同時更改了字段類型
? ? 刪除主鍵
? ? 增加自增字段
? ? 修改字段屬性為自增
? ? 刪除字段的自增屬性
其他操作均不會堵塞讀寫。相比pt-osc的需要主鍵或者唯一鍵的提前,online ddl則無需該限制。
online ddl在執(zhí)行過程中,會將增量保存innodb_online_alter_log_max_size指定大小的內(nèi)存中,如果該表較大同時DML頻率較高,
則需要擴(kuò)大該變量的值,以保證執(zhí)行過程中該大小能容納該表的所有的DML。否則會報錯:
ERROR 1799 (HY000): Creating index 'PRIMARY' required more than 'innodb_online_alter_log_max_size' bytes of modification log. Please try again.