您好,登錄后才能下訂單哦!
如何理解gh-ost,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
公司內部一直使用的online ddl工具是pt-online-schema-change,今天準備嘗試一下另外一個工具gh-ost。
gh-ost 是 gitHub,s Online Schema Transmogrifier/Transfigurator/Transformer/Thingy 的縮寫,意思是 GitHub 的在線表定義轉換器。
我對gh-ost的感興趣的原因是gh-ost可隨時暫停。如果變更過程發現主庫性能受影響,可以立刻停止拉binlog,停止應用 binlog,停止移動行數據,等性能穩定之后再繼續;另外,gh-ost不依賴觸發器,這是和pt-osc的最大區別。
只以主庫模式介紹:
1、 gh-ost 首先連接到主庫上,根據 alter 語句創建幽靈表_tablename_gho; 2、 然后gh-ost作為一個備庫連接到主庫上,一邊在主庫上拷貝已有的數據到幽靈表, 一邊從主庫上拉取增量數據的 binlog,然后不斷的把 binlog 應用回主庫幽靈表; 3、 等待全部數據同步完成,進行cut-over,即進行幽靈表和原表切換。cut-over是最后一步, 鎖住主庫的源表,等待binlog應用完畢,然后替換gh-ost幽靈表為源表。gh-ost在執行中, 會在原本的binlog event里面增加hint和心跳包,用來控制整個流程的進度,檢測狀態等。
從 github 發布地址下載最新的 binary 包:https://github.com/github/gh-ost/releases
解壓后就一個 gh-ost 二進制文件。
tar -xvf gh-ost-binary-linux-20190214020851.tar.gz cp gh-ost /usr/bin
只以主庫模式介紹,上生產可以直接用:
gh-ost \ --max-load=Threads_running=50 \ --critical-load=Threads_running=80 \ --critical-load-interval-millis=5000 \ --max-lag-millis=1500 \ --chunk-size=1000 \ --ok-to-drop-table \ --initially-drop-ghost-table \ --initially-drop-socket-file \ --host=172.18.6.2 \ --port=3306 \ --user="chenzhixin" \ --password="123456"\ --database="test" \ --table="user100w" \ --verbose \ --alter="add column test_field6 varchar(256) default '';" \ --cut-over-lock-timeout-seconds=1 \ --dml-batch-size=10 \ --exact-rowcount \ --serve-socket-file=/tmp/ghost.sock \ --panic-flag-file=/tmp/ghost.panic.flag \ --allow-on-master \ --execute ########## 特別提醒!!!!!!############################ 下面這個參數有需要再加,加了它就不會自動切換源表和幽靈表,需要手工刪除/tmp/ghost.postpone.flag 文件后,才會發生自動切換,請理解該參數含義。 --postpone-cut-over-flag-file=/tmp/ghost.postpone.flag
操作過程中會生成兩個中間狀態的表 _tablename_ghc和_tablename_gho,其中 _tablename_ghc 是記錄gh-ost 執行過程的表,_tablename_gho 是目標表,也即應用ddl語句的幽靈表_tablename_gho。
執行上述的gh-ost命令過程中,會看到如下的_user100w_ghc的執行過程表,和_user100w_gho幽靈表、
mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | _user100w_ghc | | _user100w_gho | | fruits | | test_timestamp | | user100w | +----------------+ 5 rows in set (0.00 sec)
解釋:
--max-load=Threads_running=50 表面如果在執行gh-ost的過程中出現Threads_running=50則暫停gh-ost的執行 --critical-load=Threads_running=80 表明執行過程中出現Threads_running達到80則終止gh-ost的執行 --critical-load-interval-millis 當值為0時,當達到-critical-load,gh-ost立即退出。當值不為0時,當達到-critical-load,gh-ost會在-critical-load-interval-millis秒數后,再次進行檢查,再次檢查依舊達到-critical-load,gh-ost將會退出 --max-lag-millis 會監控從庫的主從延遲情況,如果延遲秒數超過這個閥值,row copy不會退出,等待延遲秒數低于這個閥值繼續遷移。 --ok-to-drop-table go-ost 執行完以后是否刪除老表,加上此參數會自動刪除老表。默認不刪除老表,會存在_tablename_del表 --initially-drop-ghost-table gh-ost 執行前會創建兩張 xx_ghc 和 xx_gho 表,如果這兩張表存在,且加上了這個參數,那么會自動刪除原 gh 表,從新創建,否則退出。xx_gho 表相當于老表的全量備份,xx_ghc 表數據是數據更改日志,理解成增量備份。 --initially-drop-socket-file gh-ost 執行時會創建 socket 文件,退出時不會刪除,下次執行 gh-ost 時會報錯,加上這個參數會刪除老的 socket 文件,重新創建。 --throttle-flag-file 此文件存在時操作暫停,刪除文件操作會繼續。 --verbose 執行過程輸出日志 --chunk-size 遷移過程是一步步分批次完成的,這個參數是指事務每次提交的行數,默認是 1000。 --max-lag-millis 會監控從庫的主從延遲情況,如果延遲秒數超過這個閥值,遷移不會退出,等待延遲秒數低于這個閥值繼續遷移。 --max-lag-millis 會監控從庫的主從延遲情況,如果延遲秒數超過這個閥值,遷移不會退出,等待延遲秒數低于這個閥值繼續遷移 --throttle-control-replica 和--max-lag-millis 參數相結合,這個參數指定主從延遲的數據庫實例。 --cut-over-lock-timeout-seconds gh-ost在cut-over階段最大的鎖等待時間,當鎖超時時,gh-ost的cut-over將重試。(默認值:3) --allow-on-master 整個遷移所有操作在主庫上執行 --dml-batch-size 在單個事務中應用DML事件的批量大小(范圍1-100)(默認值為10) --exact-rowcount 準確統計表行數(使用select count(*)的方式),得到更準確的預估時間。 --postpone-cut-over-flag-file 當這個文件存在的時候,gh-ost的cut-over階段將會被推遲,數據仍然在復制,直到該文件被刪除。 --throttle-flag-file string 當該文件被創建后,gh-ost操作立即停止。該參數適合控制單個gh-ost操作。-throttle-additional-flag-file string適合控制多個gh-ost操作。
執行gh-ost中,會有輸出信息,具體解釋如下:
Copy: 27000/58707 46.0%;58707指需要遷移總行數,27000指已經遷移的行數,46%指遷移完成的百分比。 Applied: 0,指在二進制日志中處理的event數量。在上面的例子中,遷移表沒有流量,因此沒有被處理日志event。 Backlog: 0/1000,表示我們在讀取二進制日志方面表現良好,在二進制日志隊列中沒有任何積壓(Backlog)事件。 Backlog: 7/1000,當復制行時,在二進制日志中積壓了一些事件,并且需要應用。 Backlog: 1000/1000,表示我們的1000個事件的緩沖區已滿(程序寫死的1000個事件緩沖區,低版本是100個),此時就注意binlog寫入量非常大,gh-ost處理不過來event了,可能需要暫停binlog讀取,需要優先應用緩沖區的事件。 streamer: shvm-5-39.000040:338912890;表示當前已經應用到binlog文件位置
#首先要安裝socat工具
yum install socat -y
注意:上面gh-ost里面配置的--serve-socket-file=/tmp/ghost.sock,下面就用到了。
gh-ost 可以通過 unix socket 文件的方式來監聽請求,DBA 可以在gh-ost命令運行后更改相應的參數進行限流操作等。
#暫停
echo throttle | socat - /tmp/ghost.sock
#恢復
echo no-throttle | socat - /tmp/ghost.sock
#終止
對應panic-flag-file參數文件,當tmp目錄存在該文件立即停止 touch /tmp/ghost.panic.flag
#延遲切換(cut-over階段)
--postpone-cut-over-flag-file=/tmp/ghost.postpone.flag 當設置該參數時cut-over一直延遲源表和幽靈表的切換,直到你刪除該文件才進行切換。
適用場景:
你發起了一次修改操作,然后估計完成時間是凌晨 2 點鐘,可是你又非常關心最后的切換操作, 非常想看著它切換,這可怎么辦?只需要一個標志位文件就可以告訴 gh-ost 推遲切換了, 這樣 gh-ost 會只做完拷貝數據的操作,但不會切換表。它還會仍然繼續同步數據, 保持幽靈表的數據處于同步狀態。等第二天早上你回到辦公室之后, 刪除標志位文件或者向gh-ost發送命令echo unpostpone,它就會做切換了。 我們不希望軟件強迫我們看著它做事情,它應該把我們解放出來,讓人去做人該做的事。
#在線修改限速參數
echo max-load=Threads_connected=200 | socat - /tmp/ghost.sock echo max-load=Thread_running=3 | socat - /tmp/ghost.sock echo chunk-size=100 | socat - /tmp/ghost.sock echo max-lag-millis=200 | socat - /tmp/ghost.sock
適用場景:
當你執行了 gh-ost 之后,也許你會看見主庫的負載變高了,那你可以發出暫停命令。 用 echo throttle 命令生成一個文件,看看主庫的負載會不會又變得正常。試一下這些命令, 你就可以知道你可以怎樣控制它的行為,你的心里就會安定許多。
凡事有利必有弊,人不可能把所有好事都占有,下面是gh-ost的幾個限制:
1、不支持沒有主鍵或者唯一索引的表
2、不支持有外鍵約束的表(主表和子表都不支持)
3、不支持表上有觸發器
5、表上存在大量寫入的時候,gh-ost可能永遠也完成不了
經過測試:當寫入QPS 5000以上,gh-ost無法完成任務,其原因是apply binlog是單線程,可以理解為slave,當原表寫入量巨大時(QPS=5000以上),一直在應用日志,而gh-ost設計是binlog應用優先級高于row copy,所以我們看到row copy進度一直沒變,這樣如果原表一直壓力這么大,那么gh-ost DDL將無法完成。經過在s3710機器上測試如果原表寫入的QPS大于5000將大概率出現此情況,小于5000的話沒問題。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。