【20180208】pt-online-schema-chage和online ddl的梳理

pt-online-schema-change開始一些設置

  1. SHOW VARIABLES LIKE 'innodb_lock_wait_timeout'
  2. SET SESSION innodb_lock_wait_timeout=1
    • 設置當前會話的ROW級別的鎖timeout,針對的是table中的數據
  3. SHOW VARIABLES LIKE 'lock_wait_timeout'
  4. SET SESSION lock_wait_timeout=60
    • 設置當前會話的metadata lock的鎖的timeout,針對的是table的DDL表結構信息
  5. SHOW VARIABLES LIKE 'wait_timeout'
  6. SET SESSION wait_timeout=10000
    • 設置當前會話的連接超時的實際

pt-online-schema-change大致工作流程

  1. 創建一個新表,表結構和舊錶結構一摸一樣
  2. 將需要執行的alter table語句在新表執行
  3. 在原表創建三個觸發器,分別時delete,insert,update的觸發器
    • 在修改期間所有舊錶的插入,修改,刪除都會在新表重放一次。
  4. 以一定的大小依次的將數據從舊錶拷貝到新表
    • 這個大小並不是以rows爲單位,而是以chunk爲單位。即是物理大小
    • 插入新表的語句是類似於insert ... new_table select ... old_table force index('primary') where ..... LOCK IN SHARE MODE 在插入新表的過程會添加共享鎖,所以這部分的數據在插入過程中是不允許寫入,修改和刪除的。
  5. 新表寫入完畢之後,Rename 原表到old表中,在把新表Rename爲原表
  6. 如果有參考該表的外鍵,根據alter-foreign-keys-method參數的值,檢測外鍵相關的表,做相應設置的處理
  7. 默認刪除舊錶

pt-online-schema-change參數介紹

  1. --host , --user , --passsword
    • DDL操作的MySQL實例連接,若是不想在命令行顯示輸入密碼的話,可以使用 --ask-pass手動輸入MySQL的實例信息。
  2. --alter
    • 後面接的是沒有alter table關鍵字的DDL的語句,多個話可以使用逗號隔開。例如modify column col1 new_datatype
    • 絕大部分的情況下表需要主鍵或者唯一索引,因爲工作的過程中爲了保證新表也是最新的,需要在舊錶上面創建DELETE,UPDATE的觸發器,同步到新表的時候存在主鍵速度會更快。個別情況是當alter操作就是在column1上面創建主鍵的時候,DELETE觸發器將基於column1列。
    • 子句不支持去rename重命名
    • 5.7之前online不支持在線給索引重命名,需要先drop再create。pt-osc也一樣
    • 子句如果是add column設置default not null必須設置默認值,否則的話會報錯
    • 如果刪除外鍵名(fk_foo),使用工具的時候外鍵名要加下劃線,比如--alter "DROP FOREIGN KEY _fk_foo"
  3. D=db_name,t=table_name
    • 制定需要修改的數據庫名和表
  4. --max-load
    • 默認的Thread_running=25。在每個chunk拷貝完成之後,都會執行show global status,檢查指標是否超過了閥值,如果超過,則先暫停。這裏可以用逗號分隔,指定多個條件,每個條件的格式:status指標=MAX_VALUE或者status指標:MAX_VALUE。如果不指定MAX_VALUE,那麼這個工具的閥值默認就是當前值的120%。
  5. --max-lag
    • 默認值是1s。在每個chunk拷貝完畢之後,都會去獲取所有slave的延遲信息(Seconds_Behind_Master),當延遲的值是大於設置的值的話,那麼會暫停複製,等待延遲的值小於這個設置的值。這個參數和--check-interval一起聯合使用,定義的是當休眠多長時間之後再去獲取所有slave的延遲信息,默認參數是1s。例如--max-lag=5 --check-interval=20
  6. --chunk-time
    • 默認值是0.5s。定義每個chunk備份使用的最長耗時。會在線自己動態調整chunk-size的大小根據服務器的性能。
    • 也可以通過另外一個選項--chunk-size禁止動態調整,即每次固定拷貝 1k 行,如果指定則默認1000行,且比 chunk-time 優先生效。
  7. --set-vars
    • 可以在線修改參數設置,例如SET SESSION innodb_lock_wait_timeout=1,SET SESSION lock_wait_timeout=60,SET SESSION wait_timeout=10000。默認設置的wait_timeout是10000s,在進行DDL操作的時候必須考慮是否在這個時間內完成DDL操作,假如不能在這個默認的時間內完成DDL操作,則需要考慮將這個參數的值調大。
  8. --dry-run
    • 創建和修改新表,但是不會嘗試創建觸發器,複製數據,替換舊錶。並不真正執行,可以看到生成的執行語句。建議和--print搭配使用。
  9. --execute
    • 真正執行DDL操作。

pt-online-schema-change工作缺點

  1. 更容易導致主從數據延遲
  2. 如果運行過程中報錯了,無法從上一個位置繼續進行,需要從頭開始
  3. 不能存在觸發器
    • MySQL中一個table中不能存在倆個類型一樣的觸發器。若原表中存在觸發器,那麼使用的過程中會報錯
  4. 外鍵約束
    • 假如存在倆個表tb1和tb2,表tb2上面存在表tb1的外鍵。在alter table tb1的過程中最後rename階段由於tb2上面的外鍵約束檢查會導致rename失敗。
    • pt-osc提供--alter-foreign-keys-method選項來決定怎麼處理這種情況:
      • rebuild_constraints,優先採用這種方式:首先在表tb2上面drop掉外鍵,然後create新的外鍵指向_new_table;然後rename交換表名;最後drop舊錶。但是在這個過程中,假如表tb2過大,導致alter操作可能耗時過長,pt-osc會強制選擇drop_swap
      • drop_swap:禁用tb2表外鍵約束檢查FOREIGN_KEY_CHECKS=0,然後drop掉原表,再rename新表。這種方式速度更快,也不會阻塞請求,但是還是存在一定的風險:drop原表的瞬間到rename過程,原表是不存在的,遇到請求會報錯;如果因爲BUG或者某些原因,舊錶已經刪除,新表rename失敗,那就太晚了。不過這種情況還是很少見的。
  5. 在使用之前需要對磁盤容量進行評估。

    • 再ddl的過程中pt-osc是會完全複製一份新的數據的,還有就是這些操作是會記錄到binlog的。
  6. pt-osc是如何避免主從數據不一致的:在創建出發器的時候update舊錶,會觸發再新表的replace操作,然後再複製數據的時候使用的是insert ... ignore ...,其目的是爲了避免還沒有複製到修改的數據時候,再進行update操作會導致數據不一致。
    • 例如時間t1和t2,並且t1是早於t2。在t1的時候update修改old_tabke的數據data,由於觸發器會觸發new_table的replace(replace操作是假如數據存在的話則替換,不存在的話則插入)操作。主要是因爲怕數據data還沒有複製到new_table,這個時候執行update操作的話肯定會報錯;還有一個原因就是在複製到data的時候,由於data是replace操作的,就是已經是插入的最新修改的值,這個時候使用select...ignore...的目的就是假如這個行數據存在的話那麼就不需要插入。
  7. table上面必須存在主鍵或者唯一索引。
  8. 不支持5.7的虛擬列功能

使用pt-osc還是online ddl的建議

  1. online ddl在必須copy table時成本較高,不宜採用
  2. pt-osc工具在存在觸發器時,不適用
  3. 修改索引、外鍵、列名時,優先採用online ddl,並指定 ALGORITHM=INPLACE
  4. 其它情況使用pt-osc,雖然存在copy data
  5. pt-osc比online ddl要慢一倍左右,因爲它是根據負載調整的
  6. 無論哪種方式都選擇的業務低峯期執行
  7. 特殊情況需要利用主從特性,先alter從庫,主備切換,再改原主庫
  8. 截圖percona
    【20180208】pt-online-schema-chage和online ddl的梳理

MySQL online DDL

online DDL

在 MySQL 5.1 (帶InnoDB Plugin)和5.5中,有個新特性叫 Fast Index Creation(下稱 FIC),就是在添加或者刪除二級索引的時候,可以不用複製原表。對於之前的版本對於索引的添加刪除這類DDL操作,MySQL數據庫的操作過程爲如下:

  1. 創建臨時表,更改表結構
  2. copy data
  3. 刪除原表
  4. rename 臨時表

在copy數據的過程中,原表全程鎖表只允許讀,如果有寫進入的話會將會無法提供服務,連接數會暴漲

Fast Index Creation (FIC)

引入FIC之後,創建二級索引,數據庫不在會重建表(rebulid table),而是在創建的過程中給表加上一個S鎖;刪除索引,只是需要更改內部視圖,並標記這個索引的空間可用,去掉數據庫該元數據上面索引的定義。這個過程也只允許讀操作,但是大大加快了索引的修改(不包含主鍵索引,因爲主索引的特性註定了它需要重建表)

但是在5.6之後,這個特性的範圍擴大了添加列,刪除列,列的重命名等。

online DDL會阻塞DDL操作

  1. 修改列的數據類型
  2. 更改表的字符集
  3. 指定字符集
  4. 創建全文索引
  5. 刪除主鍵

⚠️在刪除舊的主鍵並且添加新的主鍵的時候是不會阻塞DML的

online DDL不會阻塞DML

  • 像其餘的添加列,刪除列,更改列名等都不會阻塞當前的DML
  • 不阻塞的原理

    • 在online DDL一些操作雖然有些操作不會rebuild table,類似於索引的刪除,添加,但是有寫操作也是需要rebuild table,類似於刪除列,添加列等
    • rebuild table階段不阻塞在線DML的操作的原因是因爲在執行alter table這個事務之後的增量數據會寫倆份,一份是寫入原表,一份記錄在row_log。在copy data的時候,修改之後的數據是不會寫入臨時表中的,在copy data數據完成之後做row_log回放的時候,會和row_log裏面的版本號進行比對,假如當前版本號大於或者等於row_log記錄的版本號是不會在重做一次的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章