MySQL 5.5版本html
在MySQL 5.5版本前,全部DDL操做都使用Copy Table的方式完成,操做過程當中原表數據庫不容許寫入,只能讀取,在MySQL 5.5版本中引入FIC(Fast index creation)特性。mysql
FCI特性:sql
FCI 操做流程: (1)對錶加共享S鎖,容許其餘會話讀操做,但禁止寫操做, (2)根據當前表數據建立索引, (3)新索引建立完成,解除S鎖,容許讀寫。 FCI 優勢: (1)建立索引不須要拷貝整表數據,建立速度快, (2)建立索引過程當中,能夠快速停止。 FCI限制: (1)FCI特新僅限於非彙集索引,不試用於彙集索引, (2)索引建立期間,表只容許讀不容許寫。
在MySQL 5.6.7版本前,DDL操做主要有copy和inplace兩種方式,兩種方式全程都須要鎖表禁止寫操做,容許部分時間段的讀操做,inplace方式僅支持添加和刪除索引兩種方式。數據庫
copy方式: (1)新建帶索引的臨時表 (2)鎖原表,禁止DML,容許查詢 (3)將原表數據拷貝到臨時表(無排序,一行一行拷貝) (4)進行rename,升級字典鎖,禁止讀寫 (5)完成建立索引操做 inplace方式: (1)新建索引的數據字典 (2)鎖表,禁止DML,容許查詢 (3)讀取彙集索引,構造新的索引項,排序並插入新索引 (4)等待打開當前表的全部只讀事務提交 (5)建立索引結束
MySQL 5.6 版本緩存
在MySQL 5.6.7版本後,引入了row_log來記錄DDL期間寫操做所產生的日誌,所以除DDL操做開始和結束的兩小段時間須要對錶持EXCLUSIVE-MDL鎖禁止讀寫外,其他DDL操做階段容許其餘回話對錶進行讀寫,所以可算做ONLINE DDL。併發
對於ONLINE DDL操做,一樣包含copy和inplace方式,而對於inplace方式,又能夠細分爲rebuild方式和no-rebuild方式,rebuild方式指須要從新組織記錄的操做如添加刪除列或交換列順序等操做,而no-rebuild方式指不會致使記錄格式發生變化的操做如刪除和添加索引。app
ONLINE DDL可分爲三個階段操做:ide
Prepare階段: 1.建立新的臨時frm文件 2.持有EXCLUSIVE-MDL鎖,禁止讀寫 3.根據alter類型,肯定執行方式(copy,online-rebuild,online-norebuild) 4.更新數據字典的內存對象 5.分配row_log對象記錄增量 6.生成新的臨時ibd文件 ddl執行階段: 1.降級EXCLUSIVE-MDL鎖,容許讀寫 2.掃描old_table的彙集索引每一條記錄rec 3.遍歷新表的彙集索引和二級索引,逐一處理 4.根據rec構造對應的索引項 6.將構造索引項插入sort_buffer塊 6.將sort_buffer塊插入新的索引 7.處理ddl執行過程當中產生的增量(僅rebuild類型須要) commit階段 1.升級到EXCLUSIVE-MDL鎖,禁止讀寫 2.重作最後row_log中最後一部分增量 3.更新innodb的數據字典表 4.提交事務(刷事務的redo日誌) 5.修改統計信息 6.rename臨時idb文件,frm文件 7.變動完成
MySQL 5.6版本中各種操做:工具
僅須要修改元數據的DDL操做: (1)設置列默認值 (2)設置自增列的自增值 (3)刪除索引 能夠採用Online no-rebuild方式的DDL操做: (1)添加索引 能夠採用Online rebuild方式的DDL操做: (1)添加列 (2)刪除列 (3)交換列順序 (4)修改列NULL-NOTNULL屬性 (5)修改表ROW-FORMAT (6)添加修改主鍵 只能採用Copy方式的DDL操做: (1)修改列類型 (2)轉換字符集 (3)Optimize table (4)刪除主鍵
PS: 從MySQL 5.6.17版本後,Optimize table能夠採用Inplace方式操做。
MySQL 5.6版本Online DDL特性:性能
Online DDL期間產生Row Log會按照Block來存放和處理,回放Row Log時按照Block來處理,一個Block回放完後處理下一個Block,只有到達最後一個Block時纔會鎖表,保證最後一個Block完成後新數據和老數據保持一致,所以Online DDL期間產生大量Row Log不會致使表被長時間鎖定。 Online DDL操做相關參數: (1)innodb_sort_buffer_size:用來存放Row log的Block大小由參數innodb_sort_buffer_size控制。 (2)innodb_online_alter_log_max_size:控制整個DDL期間產生Row log的文件上限值,當產生的Row Log超過該上限值,則DDL操做失敗,並回滾該期間全部未提交的併發DML操做。 (3)innodb_sort_buffer_size:在DDL執行期間Row Log會寫入到一個日誌文件,該日誌文件每次按照innodb_sort_buffer_size來擴展。 (4)old_alter_table,當該參數被啓用後,全部Alter操做將使用COPY方式操做。 惟一索引的BUG: (未找到該BUG出處)MySQL 在處理Row Log的時候存在BUG,會致使建立的惟一索引中可能存在不惟一KEY值的狀況。
Duplicate entry問題: 在進行Online DDL操做過程當中,可能遇到Duplicate entry的報錯,但數據和修改命令都正常,該問題解釋: When running an online DDL operation, the thread that runs the ALTER TABLE statement applies an 「online log」 of DML operations that were run concurrently on the same table from other connection threads. When the DML operations are applied, it is possible to encounter a duplicate key entry error (ERROR 1062 (23000): Duplicate entry), even if the duplicate entry is only temporary and would be reverted by a later entry in the 「online log」. This is similar to the idea of a foreign key constraint check in InnoDB in which constraints must hold during a transaction. 鏈接:https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-limitations.html
MySQL 5.7版本
在MySQL 5.7版本中,增長如下新功能:
一、支持修改索引名操做
操做語法:ALTER TABLE t1 RENAME INDEX idx1 to idx2; 該操做僅須要修改元數據信息和刷新緩存,所以修改操做能快速完成。
二、支持在線增長VARCHAR列的長度
在Innodb存儲引擎中,字節長度小於255的列使用1個字節來標識列長,而對於字節長度超過255的列須要使用2個字節來標識列長。 一、若是VARCHAR列長度僅在0-255或255-65535區間發生變化時,僅須要修改元數據信息而不須要對錶進行Inplace操做,所以修改操做能快速完成。 語法:alter table tb002 ALGORITHM=INPLACE, CHANGE COLUMN c4 c4 varchar(500); 或: alter table tb002 ALGORITHM=INPLACE, modify c4 varchar(600); 二、若是VARCHAR列長度從0-255區間變化到255-65535區間,則只能使用COPY方式,不容許併發DML。 三、若是縮小VARCHAR列的長度,也只能使用COPY方式,不容許併發DML。
三、支持使用INPLACE方式增長主鍵
語法:ALTER TABLE tb002 ADD PRIMARY KEY(id),ALGORITHM=INPLACE;
MySQL DDL總結
雖然MySQL 5.6和5.7版本提供了Online DDL操做,但Online DDL仍存在如下問題: (1)主從複製延遲,只有主庫上DDL執行成功纔會寫入到binlog中,而DDL操做在從庫上不能併發執行,所以即便主庫執行DDL時容許併發DML操做,對於大表操做,仍會引起嚴重的複製延遲。 (2)主庫執行Online DDL時,不能根據負載暫停DDL操做。 (3)使用Inplace方式執行的DDL,發生錯誤或被KILL時,須要必定時間的回滾期,執行時間越長,回滾時間越長。 (4)使用Copy方式執行的DDL,須要記錄過程當中的undo和redo日誌,同時會消耗buffer pool的資源,效率較低,優勢是能夠快速中止。 (5)Online DDL並非全部時間段的Online,在特定時間段須要加元數據鎖或其餘鎖。 (6)容許併發DML的DDL,可能會致使Duplicate entry問題。
MySQL DDL建議
一、對於併發操做較高的表,不管表數據量多少,不能在業務高峯期操做, 二、對於大表和較大表,若是對複製延遲和主庫性能敏感,建議改成gh-ost或pt-osc工具, 三、對於包含惟一索引建立的DDL,不能使用gh-ost或pt-osc工具, 四、能業務低峯期操做的DDL,都儘可能安排在業務低峯期進行。