MySQL 5.6 使用online DDL不鎖表增加字段和索引

創(chuàng)建索引

https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-operations.html

ALTER TABLE tbl_name ADD PRIMARY KEY (column), ALGORITHM=INPLACE, LOCK=NONE;

ALTER TABLE tbl_name ADD COLUMN column_name column_definition, ALGORITHM=INPLACE, LOCK=NONE;

ALTER TABLE `member` ADD `user_from` smallint(1) NOT NULL, ALGORITHM=INPLACE, LOCK=NONE

Performance and Space Requirements

ALTER TABLE操作有兩種算法(ALGORITHM)

  • COPY: 操作在原表的副本表上進(jìn)行没龙,表數(shù)據(jù)逐行拷貝自原表移必。不支持并發(fā)DML孩等。

  • INPLACE: 操作避免復(fù)制表數(shù)據(jù)传惠,但可能會就地rebuild表。在準(zhǔn)備和執(zhí)行階段南用,可能會短暫地獨占元數(shù)據(jù)鎖耗跛。通常口柳,支持并發(fā)DML

ALGORITHM 子句是可選項缠俺。如果沒有指定ALGORITHM 显晶,或者指定ALGORITHM=DEFAULT,MySQL則在支持的引擎和alter操作使用 ALGORITHM=INPLACE晋修;否則使用 ALGORITHM=COPY 吧碾。

注意
分區(qū)表不支持ALGORITHM=DEFAULT, ALGORITHM=INPLACE, and ALGORITHM=COPY 凰盔。
MySQL 5.6.11及以后的版本墓卦,分區(qū)表使用 ALGORITHM=1 and ALGORITHM=2 來升級/降級。
參見Section 13.1.7.1, “ALTER TABLE Partition Operations”户敬。

指定ALGORITHM子句需要使用的操作和存儲引擎支持落剪,否則會報錯。指派ALGORITHM=DEFAULT等同于忽略配置尿庐。

使用COPY算法的ALTER TABLE操作忠怖,依賴其他表修改操作來完成。在副本表更改后抄瑟,將復(fù)制數(shù)據(jù)凡泣,刪除原始表,并將副本表重命名為原始表的名稱皮假。在執(zhí)行 ALTER TABLE 操作時鞋拟,其他會話可以讀取原始表 (with the exception noted shortly)。在ALTER table操作開始后惹资,對表的更新和寫入被暫停贺纲,直到新表準(zhǔn)備就緒,然后自動重定向到新表褪测。臨時表在原始表的同目錄中創(chuàng)建猴誊,除非RENAME TO到其他目錄。

前面提到的 exception 侮措,ALTER TABLE 在準(zhǔn)備安裝新版本的表.frm文件時懈叹,會阻止讀取(不僅是寫)分扎,丟棄舊文件澄成,從表&表定義緩存中清除過期表結(jié)構(gòu)。這時,它必須獨占鎖环揽。為此略荡,要等待當(dāng)前讀結(jié)束,并阻止新的讀寫歉胶。

使用COPY算法的ALTER TABLE操作可防止并發(fā)DML汛兜,允許并發(fā)查詢。也就是說通今,table-copying操作至少限制在LOCK=SHARED(允許查詢粥谬,但不允許DML)。LOCK=EXCLUSIVE則阻止DML和查詢辫塌,進(jìn)一步限制了支持LOCK子句的操作的并發(fā)性漏策。
參見Concurrency Control

Note
MySQL 5.6,LOCK在分區(qū)表上不支持 ALTER TABLE 操作

要強(qiáng)制將COPY算法用于本來不使用其的ALTER TABLE操作臼氨,需要開啟 old_alter_table 系統(tǒng)變量掺喻,或指定ALGORITHM=COPY。如果old_alter_table和非默認(rèn)值的ALGORITHM沖突储矩,則ALGORITHM子句優(yōu)先感耙。

對于InnoDB表,對駐留在共享表空間(如 system tablespace)中的表,使用COPY算法的ALTER TABLE操作會增加表空間的使用量持隧。這些操作需要同增加索引一樣多的額外空間即硼。對于駐留在共享表空間中的表,操作使用的額外空間不會釋放回操作系統(tǒng)屡拨,as it is for a table that resides in a file-per-table tablespace只酥。
關(guān)于空間需求參見Section 14.13.3, “Online DDL Space Requirements”

使用INPLACE算法的ALTER TABLE操作:

  • InnoDB online DDL特性支持的ALTER TABLE操作。參見 Section 14.13.1, “Online DDL Operations”.

  • 重命名表呀狼。MySQL重命名與表tbl_name相關(guān)的文件裂允,無需拷貝。也可以使用RENAME TABLE來重命名表赠潦。參見 Section 13.1.32, “RENAME TABLE Statement”.) 叫胖。權(quán)限需要手動修改,原表權(quán)限不會遷移到重命名后的表她奥。

  • 只修改表元數(shù)據(jù)的操作瓮增。這些是實時操作,因為服務(wù)器僅更改表.frm 文件哩俭,不創(chuàng)建表內(nèi)容绷跑。元數(shù)據(jù)操作包含:

    • 重命名列
    • 改變列的默認(rèn)值 ,NDB表不適用凡资。參見Limitations of NDB online operations砸捏。
    • 修改枚舉ENUMor集合SET列的定義谬运,通過在有效成員值列表的末尾添加新的枚舉或集合成員,只要數(shù)據(jù)類型的存儲大小不變垦藏。比如梆暖,添加一個成員到擁有8個成員的某SET列,會將每個值所需的存儲空間從1字節(jié)更改為2字節(jié)掂骏,那么需要table copy轰驳。 在列表中間添加成員會導(dǎo)致現(xiàn)有成員重新編號,也需要table copy弟灼。
  • InnoDBNDB表级解,創(chuàng)建、刪除二級索引田绑。參見Section 14.13, “InnoDB and Online DDL”勤哗。

  • 對于NDB表,在variable-width列上增加掩驱、刪除索引的操作芒划。這些操作在線進(jìn)行,無需table copying 昙篙,并且在大部分時間內(nèi)不會阻止并發(fā)DML操作腊状。參見 Section 18.6.11, “Online Operations with ALTER TABLE in NDB Cluster”诱咏。

從MySQL 5.6.16開始苔可,對于ADD COLUMN, CHANGE COLUMN, MODIFY COLUMN, ADD INDEX, and FORCE操作,ALTER TABLE會將MySQL 5.5臨時列升級為5.6格式袋狞。無法使用 INPLACE算法完成此轉(zhuǎn)換焚辅,因為必須rebuild表,因此該情況下指定ALGORITHM=INPLACE會報錯苟鸯。如果需要同蜻,指定 ALGORITHM=COPY

NDB Cluster支持在MySQL NDB Cluster 7.3及更高版本中早处,使用 ALGORITHM=INPLACE 語法進(jìn)行在線ALTER TABLE操作湾蔓。NDB集群還支持NDB特有的舊語法的ONLINE and OFFLINE關(guān)鍵字。這些關(guān)鍵字從MySQL NDB Cluster 7.3開始就被棄用砌梆;MySQL NDB Cluster 7.4中仍然支持它們默责,但在NDB Cluster的未來版本中可能會刪除它們。參見 Section 18.6.11, “Online Operations with ALTER TABLE in NDB Cluster”咸包。

根據(jù)KEY來對表分區(qū)的多列索引桃序,如果ALTER TABLE操作作用于該多列索引上變更了列的順序,則只能使用ALGORITHM=COPY烂瘫。

MySQL NDB Cluster 7.3(及更高版本)支持使用ALGORITHM=INPLACE語法(與標(biāo)準(zhǔn)MySQL服務(wù)器相同)的在線操作媒熊。NDB Cluster 7.3和7.4還繼續(xù)支持使用ONLINE and OFFLINE關(guān)鍵字進(jìn)行在線ALTER TABLE操作,以實現(xiàn)向后兼容性,但NDB 7.3和7.4中不推薦使用這些關(guān)鍵字芦鳍,并且從NDB 7.5起不再支持這些關(guān)鍵字嚷往。NDB不支持在線變更表空間。參見Section 18.6.11, “Online Operations with ALTER TABLE in NDB Cluster”柠衅。

ADD PARTITION, DROP PARTITION, COALESCE PARTITION, REBUILD PARTITION, or REORGANIZE PARTITION這些ALTER TABLE 操作不會創(chuàng)建臨時表 (NDB表除外);然而间影, 這些操作確實可以創(chuàng)建臨時分區(qū)文件。

對于RANGE or LIST分區(qū)茄茁,ADD or DROP是實時或幾乎實時的操作魂贬。
對于HASH or KEY分區(qū),ADD or COALESCE操作從所有分區(qū)拷貝數(shù)據(jù)裙顽,除非使用了LINEAR HASH or LINEAR KEY付燥;這實際上與創(chuàng)建新表相同,盡管ADD or COALESCE操作是逐個分區(qū)執(zhí)行的愈犹。
REORGANIZE操作只復(fù)制已更改的分區(qū)键科,不接觸未更改的分區(qū)。

對于MyISAM表漩怎,通過將myisam_sort_buffer_size系統(tǒng)變量調(diào)高勋颖,可以加快索引的重建速度,這是alter過程中最慢的部分勋锤。

并發(fā)控制 Concurrency Control

對于支持Concurrency Control的ALTER TABLE操作饭玲,可以使用LOCK子句在表被alter時控制表上并發(fā)讀寫的級別。
非默認(rèn)值的指定叁执,使得在alter操作期間茄厘,您可以請求一定量的并發(fā)/獨占訪問,并可以在請求的鎖定程度不再可用時停止操作谈宛。

  1. LOCK = DEFAULT
    如果支持次哈,允許并發(fā)讀取。
    如果不支持并發(fā)讀取吆录,支持并發(fā)讀窑滞,則允許并發(fā)讀。
    如果也不支持并發(fā)讀恢筝,則強(qiáng)制排它訪問哀卫。
  2. LOCK = NONE
    允許并發(fā)讀寫。如果不支持并發(fā)讀寫滋恬,則報錯聊训。
  3. LOCK = SHARED
    允許并發(fā)讀取,不允許塊寫入恢氯。即便給定的ALGORITHM子句和 ALTER TABLE操作支持并發(fā)寫带斑,也不可以鼓寺。如果不支持并發(fā)讀,則報錯勋磕。
  4. LOCK = EXCLUSIVE
    強(qiáng)制排它訪問妈候。即便給定的ALGORITHM子句和 ALTER TABLE操作支持并發(fā)讀/寫,也要執(zhí)行此操作挂滓。

online DDL的空間要求

由于online DDL執(zhí)行期間需要創(chuàng)建臨時表空間文件用于存儲數(shù)據(jù)苦银,以及申請row log記錄DML操作,所以在執(zhí)行DDL前應(yīng)該先確認(rèn)空間上是否滿足要求赶站,否則由于空間不夠很可能導(dǎo)致操作失敗幔虏,而進(jìn)行回滾。

1贝椿、row log空間:row log空間每次申請的大小由 innodb_sort_buffer_size決定想括,最大值由innodb_online_alter_log_max_size,該值默認(rèn)為128M烙博,支持動態(tài)修改瑟蜈。對于更新頻繁的表來講,如果預(yù)計在DDL期間對表的更新操作存儲可能超過128M時渣窜,需要為本次操作增大該值铺根。當(dāng)然如果不涉及rebuild操作時,不需要考慮該值乔宿。如果提示DB_ONLINE_LOG_TOO_BIG錯誤位迂,則是由innodb_online_alter_log_max_size空間不足造成的。

2予颤、索引排序空間:如果DDL操作涉及二級索引的創(chuàng)建囤官,會在MySQL臨時目錄產(chǎn)生臨時排序文件,將中間的排序結(jié)果寫入文件蛤虐,最終將內(nèi)容合并到最終表或索引中,然后自動刪除臨時排序文件肝陪。這個路徑默認(rèn)為mysql全局參數(shù)tmpdir指定(默認(rèn)值為/tmp驳庭,如果手動指定了innodb_tmpdir參數(shù)的路徑,則tmpdir會被覆蓋)氯窍,且不會在原始表的目錄中創(chuàng)建臨時排序文件饲常。tmpdir需要保證能夠容納要創(chuàng)建的二級索引,臨時排序文件最大可能需要的空間等于表中的數(shù)據(jù)量加上索引狼讨,否則執(zhí)行將報錯贝淤。(官方文檔的說明,實際測試200萬的表加索引政供,并未生成臨時排序文件播聪,這有點奇怪)

3朽基、中間表空間:如果DDL操作涉及rebuild表,則會在原表所在目錄創(chuàng)建臨時表空間文件(以#sql開頭)离陶,臨時表空間大小需要等于原表大小稼虎,重建完成后會自動重命名臨時表空間,刪除原表空間招刨。所以執(zhí)行rebuild操作時需要保證原表所在路徑下有足夠空間

參考資料 :

https://c4ys.com/archives/1943

MySQL 5.6 Reference Manual / The InnoDB Storage Engine
InnoDB and Online DDL
Online DDL Operations
CREATE INDEX Statement
ALTER TABLE Statement

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末霎俩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沉眶,更是在濱河造成了極大的恐慌打却,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谎倔,死亡現(xiàn)場離奇詭異学密,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)传藏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進(jìn)店門腻暮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人毯侦,你說我怎么就攤上這事哭靖。” “怎么了侈离?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵试幽,是天一觀的道長。 經(jīng)常有香客問我卦碾,道長铺坞,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任洲胖,我火速辦了婚禮济榨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绿映。我一直安慰自己擒滑,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布叉弦。 她就那樣靜靜地躺著丐一,像睡著了一般。 火紅的嫁衣襯著肌膚如雪淹冰。 梳的紋絲不亂的頭發(fā)上库车,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天,我揣著相機(jī)與錄音樱拴,去河邊找鬼柠衍。 笑死洋满,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拧略。 我是一名探鬼主播芦岂,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼垫蛆!你這毒婦竟也來了禽最?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤袱饭,失蹤者是張志新(化名)和其女友劉穎川无,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虑乖,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡懦趋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了疹味。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仅叫。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖糙捺,靈堂內(nèi)的尸體忽然破棺而出诫咱,到底是詐尸還是另有隱情,我是刑警寧澤洪灯,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布坎缭,位于F島的核電站,受9級特大地震影響签钩,放射性物質(zhì)發(fā)生泄漏掏呼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一铅檩、第九天 我趴在偏房一處隱蔽的房頂上張望憎夷。 院中可真熱鬧,春花似錦柠并、人聲如沸岭接。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至啃沪,卻和暖如春粘拾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背创千。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工缰雇, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留入偷,地道東北人。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓械哟,卻偏偏與公主長得像疏之,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子暇咆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內(nèi)容