gh-ost 在線ddl變更工具​

2021-02-26 yangyidba
一 前言

作為MySQL DBA,相信我們大家都會對大表變更(大於10G 以上的)比較頭疼,尤其是某些DDL會鎖表,影響業務可持續性。目前通用的方案使用Percona 公司開源的pt-osc 工具解決導致鎖表的操作,還有一款github基於go語言開發的gh-ost。本文主要介紹gh-ost使用方法,其工作原理放到下一篇文章介紹。

二 使用2.1 gh-ost介紹

gh-ost 作為一個偽裝的備庫,可以從主庫/備庫上拉取 binlog,過濾之後重新應用到主庫上去,相當於主庫上的增量操作通過 binlog 又應用回主庫本身,不過是應用在幽靈表上。

其大致的工作過程:

1 gh-ost 首先連接到主庫上,根據 alter 語句創建幽靈表,

2 然後作為一個備庫連接到其中一個真正的備庫或者主庫上(根據具體的參數來定),一邊在主庫上拷貝已有的數據到幽靈表,一邊從備庫上拉取增量數據的 binlog,然後不斷的把 binlog 應用回主庫。

3 等待全部數據同步完成,進行cut-over 幽靈表和原表切換。圖中 cut-over 是最後一步,鎖住主庫的源表,等待 binlog 應用完畢,然後替換 gh-ost 表為源表。gh-ost 在執行中,會在原本的 binlog event 裡面增加以下 hint 和心跳包,用來控制整個流程的進度,檢測狀態等。

當然gh-ost 也會做很多前置的校驗檢查,比如binlog_format ,表的主鍵和唯一鍵,是否有外鍵等等

這種架構帶來諸多好處,例如:

整個流程異步執行,對於源表的增量數據操作沒有額外的開銷,高峰期變更業務對性能影響小。

降低寫壓力,觸發器操作都在一個事務內,gh-ost 應用 binlog 是另外一個連接在做。

可停止,binlog 有位點記錄,如果變更過程發現主庫性能受影響,可以立刻停止拉binlog,停止應用 binlog,穩定之後繼續應用。

可測試,gh-ost 提供了測試功能,可以連接到一個備庫上直接做 Online DDL,在備庫上觀察變更結果是否正確,再對主庫操作,心裡更有底。不過不推薦在備庫直接操作。

2.2 gh-ost 操作模式

a. 連接到從庫,在主庫做遷移這是 gh-ost 默認的工作方式。gh-ost 將會檢查從庫狀態,找到集群結構中的主庫並連接,接下來進行遷移操作:

行數據在主庫上讀寫

讀取從庫的二進位日誌,將變更應用到主庫

在從庫收集表格式,欄位&索引,行數等信息

在從庫上讀取內部的變更事件(如心跳事件)

在主庫切換表

如果你的主庫的日誌格式是 SBR,工具也可以正常工作。但從庫必須啟用二級制日誌( log_bin, log_slave_updates) 並且設置 binlog_format=ROW 。

b. 連接到主庫

直接連接到主庫構造slave,在主庫上進行copy數據和應用binlog,通過指定 --allow-on-master 參數即可。當然主庫的binlog模式必須是row模式

c. 在從庫遷移/測試該模式會在從庫執行遷移操作。gh-ost 會簡單的連接到主庫,此後所有的操作都在從庫執行,不會對主庫進行任何的改動。整個操作過程中,gh-ost 將控制速度保證從庫可以及時的進行數據同步

--migrate-on-replica 表示 gh-ost 會直接在從庫上進行遷移操作。即使在複製運行階段也可以進行表的切換操作。

--test-on-replica 表示 遷移操作只是為了測試在切換之前複製會停止,然後會進行切換操作,然後在切換回來,你的原始表最終還是原始表。兩個表都會保存下來,複製操作是停止的。你可以對這兩個表進行一致性檢查等測試操作。

三 實踐

https://github.com/github/gh-ost

3.1 參數說明:

這裡列出比較重要的參數,大家可以通過如下命令獲取比較詳細的參數以及其解釋。

gh-ost --help

-allow-master-master:是否允許gh-ost運行在雙主複製架構中,一般與-assume-master-host參數一起使用

-allow-nullable-unique-key:允許gh-ost在數據遷移依賴的唯一鍵可以為NULL,默認為不允許為NULL的唯一鍵。如果數據遷移(migrate)依賴的唯一鍵允許NULL值,則可能造成數據不正確,請謹慎使用。

-allow-on-master:允許gh-ost直接運行在主庫上。默認gh-ost連接的從庫。

-alter string:DDL語句

-assume-master-host string:為gh-ost指定一個主庫,格式為」ip:port」或者」hostname:port」。在這主主架構裡比較有用,或則在gh-ost發現不到主的時候有用。

-assume-rbr:確認gh-ost連接的資料庫實例的binlog_format=ROW的情況下,可以指定-assume-rbr,這樣可以禁止從庫上運行stop slave,start slave,執行gh-ost用戶也不需要SUPER權限。

-chunk-size int:在每次迭代中處理的行數量(允許範圍:100-100000),默認值為1000。

-concurrent-rowcount:該參數如果為True(默認值),則進行row-copy之後,估算統計行數(使用explain select count(*)方式),並調整ETA時間,否則,gh-ost首先預估統計行數,然後開始row-copy。

-conf string:gh-ost的配置文件路徑。

-critical-load string:一系列逗號分隔的status-name=values組成,當MySQL中status超過對應的values,gh-ost將會退出。-critical-load Threads_connected=20,Connections=1500,指的是當MySQL中的狀態值Threads_connected>20,Connections>1500的時候,gh-ost將會由於該資料庫嚴重負載而停止並退出。

-critical-load-hibernate-seconds int :負載達到critical-load時,gh-ost在指定的時間內進入休眠狀態。 它不會讀/寫任何來自任何伺服器的任何內容。

-critical-load-interval-millis int:當值為0時,當達到-critical-load,gh-ost立即退出。當值不為0時,當達到-critical-load,gh-ost會在-critical-load-interval-millis秒數後,再次進行檢查,再次檢查依舊達到-critical-load,gh-ost將會退出。

-cut-over string:選擇cut-over類型:atomic/two-step,atomic(默認)類型的cut-over是github的算法,two-step採用的是facebook-OSC的算法。

-cut-over-exponential-backoff

-cut-over-lock-timeout-seconds int:gh-ost在cut-over階段最大的鎖等待時間,當鎖超時時,gh-ost的cut-over將重試。(默認值:3)

-database string:資料庫名稱。

-default-retries int:各種操作在panick前重試次數。(默認為60)

-dml-batch-size int:在單個事務中應用DML事件的批量大小(範圍1-100)(默認值為10)

-exact-rowcount:準確統計表行數(使用select count(*)的方式),得到更準確的預估時間。

-execute:實際執行alter&migrate表,默認為noop,不執行,僅僅做測試並退出,如果想要ALTER TABLE語句真正落實到資料庫中去,需要明確指定-execute

-exponential-backoff-max-interval int

-force-named-cut-over:如果為true,則'unpostpone | cut-over'交互式命令必須命名遷移的表

-heartbeat-interval-millis int:gh-ost心跳頻率值,默認為500

-initially-drop-ghost-table:gh-ost操作之前,檢查並刪除已經存在的ghost表。該參數不建議使用,請手動處理原來存在的ghost表。默認不啟用該參數,gh-ost直接退出操作。

-initially-drop-old-table:gh-ost操作之前,檢查並刪除已經存在的舊錶。該參數不建議使用,請手動處理原來存在的ghost表。默認不啟用該參數,gh-ost直接退出操作。

-initially-drop-socket-file:gh-ost強制刪除已經存在的socket文件。該參數不建議使用,可能會刪除一個正在運行的gh-ost程序,導致DDL失敗。

-max-lag-millis int:主從複製最大延遲時間,當主從複製延遲時間超過該值後,gh-ost將採取節流(throttle)措施,默認值:1500s。

-max-load string:逗號分隔狀態名稱=閾值,如:'Threads_running=100,Threads_connected=500'. When status exceeds threshold, app throttles writes

-migrate-on-replica:gh-ost的數據遷移(migrate)運行在從庫上,而不是主庫上。

-nice-ratio float:每次chunk時間段的休眠時間,範圍[0.0…100.0]。0:每個chunk時間段不休眠,即一個chunk接著一個chunk執行;1:每row-copy 1毫秒,則另外休眠1毫秒;0.7:每row-copy 10毫秒,則另外休眠7毫秒。

-ok-to-drop-table:gh-ost操作結束後,刪除舊錶,默認狀態是不刪除舊錶,會存在_tablename_del表。

-panic-flag-file string:當這個文件被創建,gh-ost將會立即退出。

-password string :MySQL密碼

-port int :MySQL埠,最好用從庫

-postpone-cut-over-flag-file string:當這個文件存在的時候,gh-ost的cut-over階段將會被推遲,數據仍然在複製,直到該文件被刪除。

-skip-foreign-key-checks:確定你的表上沒有外鍵時,設置為'true',並且希望跳過gh-ost驗證的時間-skip-renamed-columns ALTER

-switch-to-rbr:讓gh-ost自動將從庫的binlog_format轉換為ROW格式。

-table string:表名

-throttle-additional-flag-file string:當該文件被創建後,gh-ost操作立即停止。該參數可以用在多個gh-ost同時操作的時候,創建一個文件,讓所有的gh-ost操作停止,或者刪除這個文件,讓所有的gh-ost操作恢復。

-throttle-control-replicas string:列出所有需要被檢查主從複製延遲的從庫。

-throttle-flag-file string:當該文件被創建後,gh-ost操作立即停止。該參數適合控制單個gh-ost操作。-throttle-additional-flag-file string適合控制多個gh-ost操作。

-throttle-query string:節流查詢。每秒鐘執行一次。當返回值=0時不需要節流,當返回值>0時,需要執行節流操作。該查詢會在數據遷移(migrated)伺服器上操作,所以請確保該查詢是輕量級的。

-timestamp-old-table:在舊錶名中使用時間戳。這會使舊錶名稱具有唯一且無衝突的交叉遷移。

-user string :MYSQL用戶

3.2 執行ddl

測試例子 對test.t1 重建表 alter table t1 engine=innodb;

/opt/gh-ost/bin/gh-ost \

--max-load=Threads_running=20 \

--critical-load=Threads_running=50 \

--critical-load-interval-millis=5000 \

--chunk-size=1000 \

--user="root" \

--password="" \

--host='127.0.0.1' \

--port=3316 \

--database="test" \

--table="b" \

--verbose \

--alter="engine=innodb" \

--assume-rbr \

--cut-over=default \

--cut-over-lock-timeout-seconds=1 \

--dml-batch-size=10 \

--allow-on-master \

--concurrent-rowcount \

--default-retries=10 \

--heartbeat-interval-millis=2000 \

--panic-flag-file=/tmp/ghost.panic.flag \

--postpone-cut-over-flag-file=/tmp/ghost.postpone.flag \

--timestamp-old-table \

--execute 2>&1 | tee /tmp/rebuild_t1.log

操作過程中會生成兩個中間狀態的表 _b_ghc, _b_gho,其中 _b_ghc 是記錄gh-ost 執行過程的表,其記錄類似如下:

_b_gho 是目標表,也即應用ddl語句的幽靈表。

特別說明,上面的命令其實是在我們的生產線上直接使用的。一般我們針對幾百G的大表做歸檔刪除數據之後要重建表,以便減少表空間大小。重建完,進行cut-over 切換幽靈表和原表時,默認不刪除幽靈表。因為直接刪除上百G 會對磁碟IO有一定的影響.

其他的請各位同行根據自己的情況去調整合適的參數,注意以下兩個參數。

--ok-to-drop-table:gh-ost操作結束後,刪除舊錶,默認狀態是不刪除舊錶,會存在_tablename_del表。

--timestamp-old-table 最終rename的時候表名會加上時間戳後綴,每次執行的時候都會生成一個新的表名。

3.3 gh-ost 的特性

gh-ost 擁有眾多特性,比如 輕量級,可暫停,可動態控制,可審計,可測試,等等 ,我們可以通過操作特定的文件對正在執行的gh-ost命令進行動態調整 。

暫停/恢復

我們可以通過創建/刪除 throttle-additional-flag-file 指定的文件 /tmp/gh-ost.throttle 控制gh-ost對binlog 應用.

限流

gh-ost 可以通過 unix socket 文件或者TCP埠(可配置)的方式來監聽請求,DBA可以在命令運行後更改相應的參數,參考下面的例子:

打開限流

echo throttle | socat - /tmp/gh-ost.test.b.sock

_b_ghc 中會多一條記錄

331 | 2019-08-31 23:23:00 | throttle at 1567264980930907070 | done throttling

關閉限流

no-throttle | socat - /tmp/gh-ost.test.b.sock

_b_ghc 中會多一條記錄

347 | 2019-08-31 23:24:09 | throttle at 1567265049830789079 | commanded by user

改變執行參數: chunk-size= 1024, max-lag-millis=100, max-load=Thread_running=23 這些參數都可以在運行時動態調整。

echo chunk-size=1024 | socat - /tmp/gh-ost.test.b.sock

echo max-lag-millis=100 | socat - /tmp/gh-ost.test.b.sock

echo max-load=Thread_running=23 | socat - /tmp/gh-ost.test.b.sock

終止運行

我們通過來過創建panic-flag-file指定的文件,立即終止正在執行的gh-ostmin

創建文件/tmp/ghost.panic.flag

gh-ost log提示

2019-08-31 22:50:52.701 FATAL Found panic-file /tmp/ghost.panic.flag. Aborting without cleanup

注意停止gh-ost操作會有遺留表 xxx_ghc, xxx_gho 還有socket文件,管理cut-over的文件,如果你需要執行兩次請務必檢查指定目錄是否存在這些文件,並且清理掉文件和表

四 與pt-osc的對比

從功能,穩定性和性能上來看,兩種工具各有千秋,雖然在高並發寫的情況下,gh-ost 應用binlog會出現性能較低不如pt-osc的情況。不過gh-ost更靈活,支持我們根據實際情況動態調整。

推薦兩個blog的文章吧,大家可以根據自己的實際場景去選擇使用哪個工具。

https://www.cnblogs.com/zping/p/8876148.html

https://blog.csdn.net/poxiaonie/article/details/75331916

五 總結

總體來講 gh-ost 是一款非常出色的開源產品,感謝github為我們MySQL DBA 提供了一種解決大表ddl的工具,歡迎還沒使用的朋友試用該工具。

參考文章

https://www.cnblogs.com/zhoujinyi/p/9187421.html

https://segmentfault.com/a/1190000006158503

-The End-

本公眾號長期關注於資料庫技術以及性能優化,故障案例分析,資料庫運維技術知識分享,個人成長和自我管理等主題,歡迎掃碼關注。

相關焦點

  • 【資料】開源情報及社交媒體情報在線工具包
    今天給的大家分享土耳其公司和研究人員整理的開源情報及社交媒體情報在線工具包。
  • onekey在線安裝系統工具
    [名稱]:onekey在線安裝系統工具[語言]:簡體中文 [安裝環境]:Win10/Win7/Win8[下載連結]
  • 9款超級好用的在線PDF工具!
    本文就來介紹 9 款超級好用的在線 PDF 工具,無需安裝,不佔用內存,開箱即用、即用即走。它們分別是:PDF ConverterPDF Converter[1]幾乎支持把 PDF 轉化成所有格式的文件,也支持把不同文件格式轉換成 PDF。
  • 9 款超級好用的在線 PDF 工具!
    另外,PDF Converter 是一款非常安全的在線工具,通過 256 位 SSL 加密,來保障上傳文件的安裝。而且,一旦完成並下載你需要的問題,它會自動刪除伺服器上文件。ExtractPDFExtractPDF[2]是一款擅長內容提取的 PDF 工具。
  • 思維導圖、流程圖、圖表在線製作工具
    今兒個,給大夥們分享一款免費的在線思維導圖、流程圖、圖表等綜合一體的繪圖工具。
  • 2021年度全國國土變更調查實施要點圖解
    ● 2022年1月31日前,縣級調查單元應完成縣級年度變更調查工作,向省級自然資源主管部門報送2021年度變更調查更新數據增量包,省級自然資源主管部門可根據地方實際,進一步細化對於縣級調查成果提交的具體時間安排。  ● 2022年2月20日前,省級自然資源主管部門組織完成省級檢查和整改工作,向部報送檢查合格的縣級國土變更調查初報數據。
  • 兩款免費的在線腦圖流程圖工具
    ProcessOn 和 draw.io 都是一個在線作圖工具的聚合平臺,它可以在線畫流程圖、思維導圖、UI 原型圖、UML、網絡拓撲圖、組織結構圖等等,你也根據你的需求自由組合圖形,這兩款工具基本都可以替代 Visio 來繪製流程圖和組織結構圖等,Visio 其實挺多電腦沒有安裝,並且安裝時版本限制也比較多
  • 《FGO》戰鬥形象怎麼變更 手把手教你Fatego從者戰鬥形象怎麼換
    《FGO》戰鬥形象怎麼變更 手把手教你Fatego從者戰鬥形象怎麼換時間:2019-11-13 15:55   來源:遊俠網   責任編輯:沫朵 川北在線核心提示:原標題:《FGO》戰鬥形象怎麼變更 手把手教你Fatego從者戰鬥形象怎麼換 在FGO中每位從者都有著初始/靈基再臨/滿破最多四種卡面以及戰鬥形象,而遊戲的默認形象則是最後達成的那一個
  • 一款專業的在線戰鬥模擬器工具
    悟飯遊戲廳是一款專業的在線戰鬥模擬器工具。它還包括GBA,FC,街機,PSP和其他大型遊戲。
  • Traccar:支持在線追蹤功能的開源GPS追蹤工具
    本文中介紹的工具、技術帶有一定的攻擊性,請合理合法使用。
  • 最簡單漂亮的免費在線生信繪圖工具
    另外還有Cytoscape和其它作圖工具以及圖形排版的介紹,是在家作圖、出門收藏的必備良品。代碼很簡單,封裝很方便,但在使用時還是有不少朋友遇到不少問題,那麼有沒有辦法不寫代碼就可以直接出圖,並且既簡單易用,又可定製,還能得到矢量圖。
  • PDF在線轉換網站工具大集合!
    今天給大家推薦幾個網頁在線處理PDF的文件的工具,以下全部為線上PDF編輯轉換工具,網站一鍵操作完成!
  • 12 個頂級 Bug 跟蹤工具
    在如今的在線世界,幾乎所有的公司都面臨它們產品中的 bugs,並且考慮如何管理這些 bugs。應該使用哪個工具?如何搭建 bug 跟蹤流程?在本文中,我們將詳細探討這些問題。它為開發和測試團隊提供了一個系統來跟蹤軟體開發、應用程式開發和部署中的 bug 修復和代碼變更。核心功能集成與原始碼管理工具有集成,例如 Github。
  • 水友挑戰賽規則變更公告
    我們特邀鬥魚平臺《戰艦世界》知名主播葉秋化身「煤老闆」進行「在線發煤」,艦長們不光會與葉秋「同(組)臺(隊)競(群)技(毆)」,還有機會贏取大量的煤炭獎勵
  • 最簡單漂亮的免費在線生信繪圖工具(收藏)
    關於該神器:生信寶典團隊開發的在線繪圖工具E Chart開始面向公測了,包括多種形式的熱圖、線圖、柱狀圖、箱線圖、泡泡圖、韋恩圖、進化樹、火山圖、生存分析等。圖形支持設計有生信分析常見的14種圖,都已實現。
  • ​電影《集結號》在線觀看
    電影視頻】曾經一票難求,這部被禁30年的紀錄片解禁3.含淚活著4.天註定5.一部過於真實,而被忽略的好電影6.活著7.電影八百壯士
  • ASRI 課程 | 2020 全新Rhino+GH參數建模全階段課程,助你做最強的參數化作品!
    命令詳解GalapagosLaunchBox ApplicationMinimum/MaxmumMath Application上課時間
  • Enterprise Architect:全球領先的UML軟體開發與建模工具!
    Enterprise Architect內置的工具可幫助您管理複雜性信息,包括:•用於建模的戰略性和業務級概念圖表•特定域文件和可重複使用的模型模式•用於跟蹤和集成變更的基準和版本管理與高端工具,開放標準的承諾,合適定價和在線可用性相結合。 NIEM國家信息交換模型(NIEM)提供了一個通用框架,用於定義如何在系統,政府機構和組織之間共享信息。