在mysql 5.5版本前,所有ddl操作都使用copy table的方式完成,操作過程中原表資料庫不允許寫入,只能讀取,在mysql 5.5版本中引入fic(fast index creation)特性。
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.7版本後,引入了row_log來記錄ddl期間寫操作所產生的日誌,因此除ddl操作開始和結束的兩小段時間需要對錶持exclusive-mdl鎖禁止讀寫外,其餘ddl操作階段允許其他回話對錶進行讀寫,因此可算作online ddl。
對於online ddl操作,同樣包含copy和inplace方式,而對於inplace方式,又可以細分為rebuild方式和no-rebuild方式,rebuild方式指需要重新組織記錄的操作如新增刪除列或交換列順序等操作,而no-rebuild方式指不會導致記錄格式發生變化的操作如刪除和新增索引。
online ddl可分為三個階段操作:
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.變更完成
online ddl期間產生row log會按照block來存放和處理,回放row log時按照block來處理,乙個block回放完後處理下乙個block,只有到達最後乙個block時才會鎖表,保證最後乙個block完成後新資料和老資料保持一致,因此online ddl期間產生大量row log不會導致表被長時間鎖定。
僅需要修改元資料的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方式操作。
(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的報錯,但資料和修改命令都正常,該問題解釋:
連線:
在mysql 5.7版本中,增加以下新功能:
雖然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問題。
ddl 建議:
1、對於併發操作較高的表,無論表資料量多少,不能在業務高峰期操作,
2、對於大表和較大表,如果對複製延遲和主庫效能敏感,建議改為gh-ost或pt-osc工具,
3、對於包含唯一索引建立的ddl,不能使用gh-ost或pt-osc工具,
4、能業務低峰期操作的ddl,都盡量安排在業務低峰期進行。
MySql各版本介紹
mysql 各個版本區別 1 mysql community server 社群版本,開源免費,但不提供官方技術支援。2 mysql enterprise edition 企業版本,需付費,可以試用30天。3 mysql cluster 集群版,開源免費。可將幾個mysql server封裝成乙個s...
mysql各版本特點
mysql 發音 ma s kju l 但也經常讀作my sequel 是乙個開放原始碼的關聯式資料庫管理系統,開發者為瑞典mysql ab公司,現為sun公司的一部分。2009年oracle宣布收購sun公司,因此mysql可能成為oracle旗下產品。mysql由於效能高 成 本低 可靠性好,已...
MySQL各版本的區別
1.mysql community server 社群版本,開源免費,但不提供官方技術支援。2.mysql enterprise edition 企業版本,需付費,可以試用30天。3.mysql cluster 集群版,開源免費。可將幾個mysql server封裝成乙個server。4.mysql...