天天看點

(轉)mysql原生線上ddl和pt-osc原了解析

(轉)mysql原生線上ddl和pt-osc原了解析

#Inception 對OSC的支援 Inception已經支援Percon ToolKit工具**​

​pt-online-schema-change​

​**,這樣對表大表的修改操作,就不需要跳過Inception而手動去執行了,給線上操作又帶來了非常大的友善性。

##可選的OSC參數 為了更友好的實作對OSC的內建,增加了下面的一些參數:

參數名稱 作用域 預設值 說明
inception_osc_bin_dir GLOBAL 用于指定pt-online-schema-change腳本的位置,不可修改,在配置檔案中設定
inception_osc_check_interval SESSION 5秒 對應參數--check-interval,意義是Sleep time between checks for --max-lag.
inception_osc_chunk_size 1000 對應參數--chunk-size
inception_osc_chunk_size_limit 4 對應參數--chunk-size-limit
inception_osc_chunk_time 1 對應參數--chunk-time
inception_osc_critical_thread_connected 對應參數--critical-load中的thread_connected部分
inception_osc_critical_thread_running 80 對應參數--critical-load中的thread_running部分
inception_osc_drop_new_table 對應參數--[no]drop-new-table
inception_osc_drop_old_table 對應參數--[no]drop-old-table
inception_osc_check_replication_filters 對應參數--[no]check-replication-filters
inception_osc_check_alter 對應參數--[no]check-alter
inception_osc_max_lag 3 對應參數--max-lag
inception_osc_max_thread_connected 對應參數--max-load中的thread_connected部分
inception_osc_max_thread_running 對應參數--max-load中的thread_running部分
inception_osc_recursion_method processlist 對應OSC參數recursion_method,具體意義可以參考OSC官方手冊
inception_osc_alter_foreign_keys_method none 對應OSC參數alter-foreign-keys-method,具體意義可以參考OSC官方手冊
inception_osc_min_table_size 16 這個參數實際上是一個OSC的開關,如果設定為0,則全部ALTER語句都走OSC,如果設定為非0,則當這個表占用空間大小大于這個值時才使用OSC方式。機關為M,這個表大小的計算方式是通過語句: **"select (DATA_LENGTH + INDEX_LENGTH)/1024/1024 from information_schema.tables where table_schema = 'dbname' and table_name = 'tablename'"**來實作的。
inception_osc_on 一個全局的OSC開關,預設是打開的,如果想要關閉則設定為OFF,這樣就會直接修改
inception_osc_print_sql 對應參數--print
inception_osc_print_none 用來設定在Inception傳回結果集中,對于原來OSC在執行過程的标準輸出資訊是不是要列印到結果集對應的錯誤資訊列中,如果設定為1,就不列印,如果設定為0,就列印。而如果出現錯誤了,則都會列印

|

參數名稱、作用域、預設值及意義上面都已經列出來了,針對全局的參數,比如inception_osc_on,都是用來控制所有的OSC行為的,這些參數的修改及檢視都是通過上面第六節中所介紹的一樣,當修改之後,立即生效。

而針對會話級的參數,因為這些參數是隻能影響目前要執行的語句的行為,是以不能設定全局的值,必須要在執行前設定目前線程的值,Inception可以通過語句:inception set session session_variable_name=value來修改,這樣就隻會影響目前語句的執行。因為Inception隻是一個伺服器,那麼在具體頁面實作時,可能還需要在頁面上加入對這些參數修改并且設定的視窗,針對每一個設定,在内部拼寫對應的inception set session語句來設定,然後再開始ALTER TABLE。 ##檢視OSC執行進度 對于ALTER比較大的表時,因為所用時間比較長,在修改時可能需要關注一下進度,因為OSC工具本身在執行時是列印進度資訊的,是以Inception完全 可以提供這方面的資訊,出于更友好的實作方式,Inception新加入一個語句,可以查詢目前執行的語句的進度,語句文法為:

inception get osc_percent '目前執行的SQL語句以及一些基本資訊生成的SHA1哈希值'
      

通過這個語句,可以檢視進度資訊,這個傳回的結果集包括下面5個列:

  • TABLENAME:目前被修改的表名;
  • DBNAME:目前被修改表所在的庫名;
  • SQLSHA1:目前要查詢的語句的SHA1字元串;
  • PERCENT:目前修改已經完成的百分比,這個值是0到100的值。
  • REMAINTIME:目前修改語句還需要多久才能完成,如03:55表示還需要三分55秒,01:33:44表示還需要1小時33分44秒。
  • INFOMATION:顯示目前OSC執行時的狀态資訊,内容為OSC目前所有的輸出資訊,不包括百分比資訊,百分比還是由上面的列來顯示,這個友善在使用時随時檢視執行到哪一步了,可以更加清楚的了解到執行進度。

下圖是在ALTER的時候,查到的正在做的資訊: ​​​​

上面是正在做的,而如果語句塊中有多個修改表的操作,則前面的會看到執行完成的進度資訊: ​​​​

具體在上層應用使用時,可以選擇性的使用所需要的列。

至于上面提到的SHA1值是如何獲得的,因為在應用送出語句時,都會稽核通過才能送出到流程管理資料庫中,那麼這個語句就不會被修改了,而此時在稽核通過的時候,傳回的結果集新增一個列sqlsha1,而隻有當Inception判斷到目前語句滿足使用OSC方式執行時,這個列才會有值,就會根據目前語句資訊生成一個哈希值,這個值存儲起來以友善後面執行時使用。

下面來看看ALTER語句在滿足使用OSC的情況下,稽核時傳回的結果集資訊:

['ID', 'stage', 'errlevel', 'stagestatus', 'errormessage', 'SQL', 'Affected_rows', 'sequence', 'backup_dbname', 'execute_time', 'sqlsha1']
1 | CHECKED | 0 | Audit completed | None | use sbtest | 0 | '0_0_0' | None | 0 |
2 | CHECKED | 0 | Audit completed | None | alter table sbtest1 add c2 int not null default 'a' comment 'for test' | 449234 | '0_0_1' | 127_0_0_1_3306_sbtest | 0 | *F270A6902BB3A0E2DE042A60D79F55418C8D1C00
      

其中"*98A11AC683C0D121568A51CA33A3A94674326630"就是上面ALTER語句對應的SQLSHA1值。

當進入執行階段之後,在執行目前語句時,OSC會向inception傳回進度資訊,Inception在收到之後,會根據目前語句的SHA1值更新對應的進度資訊,OSC會每百分之一傳回一次進度資訊,那Inception都會更新目前語句對應的進度資訊,OSC不會傳回100%,最大99%,而Inception做了處理,當檢查到有successfully altered的資訊之後,就将進度資訊改為100%,剩餘時間為00:00,而99%到100%之間做的事情包括清除環境的操作,是以時間可能比之前的1%的時間要長。

進度資訊緩存有生命周期的,在整個語句塊執行完成在退出前,相應的緩存資訊就會被清除出去,之後再查詢進度就查不到了。查不到的話,目前線程的阻塞也就傳回了,說明已經完成。

##中止OSC的執行 在執行OSC的過程中,有可能遇到的問題是,執行一部分了,突然發現對線上造成了MDL等待的現象,這種影響對一些業務是不可接受的,因為很多語句此時就不能執行目前表上面的任何操作了,必須要等OSC的一些輔助操作(建立/删除觸發器)完成之後才可以,而OSC的這些操作又是在等待線上的一些慢查詢語句執行完成才能繼續執行下去,這種情況下,我們一般的處理方式是,先退出OSC執行,等在壓力小的時候,或者可以多試幾次,才可以繼續執行下去,那麼此時最需要DBA操作的就是取消目前這個OSC的執行,是以考慮實作一個取消(中止)OSC執行的功能。

取消方式與查詢執行進度是一樣的,還是通過一個新的Inception指令來實作,新的指令如下:

inception stop alter '目前執行的SQL語句以及一些基本資訊生成的SHA1哈希值'
      

這裡用到的還是那個SQLSHA1,當OSC開始執行時,這個SQLSHA1對應的緩存對象會被加入到OSC緩存中,此時就可以查到執行進度了(當然一開始還是0%),同時,這個時候也就可以取消這個語句的執行了,但取消的前提是,OSC執行的程序已經建立,同時,執行進度不到100%才可以取消,否則就會報錯誤​

​"Can not find OSC executing task"​

​(2624),如果可以KILL的話,Inception就會主動KILL用來執行OSC的程序,這樣輕而易舉的就取消掉了OSC的執行了。

但是在取消之後,還是有幾點需要注意的:

  1. 在多個ALTER語句一起執行的情況下,如果取消某一個,那麼整個執行過程都中止,同時被取消的語句傳回是未執行狀态。是以在前端實作執行錯誤再次執行時,這個可以歸為未執行的語句
  2. 在取消語句的錯誤描述資訊中,報錯為​

    ​"Execute has been abort in percent: 已執行比例, remain time: 剩餘時間"​

  3. 在取消之後,目前語句之後的所有語句不會執行,當然狀态為未執行。
  4. 被取消語句,在取消之後,結果集stagestatus列的資訊會設定為​

    ​"Execute Aborted"​

    ​。

    ##檢視所有OSC執行資訊 語句如下:

inception get osc processlist;
      

這個語句的功能是列印所有目前正在使用OSC執行的操作,如果在同一個inception請求中有多個ALTER語句,那麼顯示出來的有可能存在執行進度為100%的語句,通過這個語句,可以輕松檢視目前每一個OSC執行進度,如果是卡住了(比如存在從庫複制延遲),在這裡可以看到具體資訊。

實際上看到的資訊和上面​

​inception get osc_percent '目前執行的SQL語句以及一些基本資訊生成的SHA1哈希值'​

​傳回的結果是一樣的,隻是這個傳回了所有資訊。

##後記 需要注意的是,OSC全局參數最好别頻繁修改,因為針對某一個語句的SHA1是分階段的,生成是在稽核階段的,如果在稽核時候沒有打開,或者設定的表大小沒有滿足OSC方式,則不會生成SHA1,那麼在執行時候,這個進度就不能被查詢了,這個語句的執行情況就不能擷取到,影響執行過程的體驗。當然這個影響也不大,因為在執行完成之後,如果執行成功了,并且參數​

​inception_osc_print_none​

​為OFF,則會看到列印資訊,裡面包括成功或者失敗的所有資訊,而如果為ON,則如果結果集中有資訊,則說明是執行錯誤了,如果沒有則說明成功。

技術連結