溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何理解gh-ost

發(fā)布時(shí)間:2021-10-09 14:24:04 來源:億速云 閱讀:286 作者:柒染 欄目:MySQL數(shù)據(jù)庫(kù)

如何理解gh-ost,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

    公司內(nèi)部一直使用的online ddl工具是pt-online-schema-change,今天準(zhǔn)備嘗試一下另外一個(gè)工具gh-ost。

    gh-ost 是 gitHub,s Online Schema Transmogrifier/Transfigurator/Transformer/Thingy 的縮寫,意思是 GitHub 的在線表定義轉(zhuǎn)換器。

    我對(duì)gh-ost的感興趣的原因是gh-ost可隨時(shí)暫停。如果變更過程發(fā)現(xiàn)主庫(kù)性能受影響,可以立刻停止拉binlog,停止應(yīng)用 binlog,停止移動(dòng)行數(shù)據(jù),等性能穩(wěn)定之后再繼續(xù);另外,gh-ost不依賴觸發(fā)器,這是和pt-osc的最大區(qū)別。

大致的工作原理:

只以主庫(kù)模式介紹:

如何理解gh-ost

1、 gh-ost 首先連接到主庫(kù)上,根據(jù) alter 語句創(chuàng)建幽靈表_tablename_gho;
  
2、 然后gh-ost作為一個(gè)備庫(kù)連接到主庫(kù)上,一邊在主庫(kù)上拷貝已有的數(shù)據(jù)到幽靈表,
一邊從主庫(kù)上拉取增量數(shù)據(jù)的 binlog,然后不斷的把 binlog 應(yīng)用回主庫(kù)幽靈表;
  
3、 等待全部數(shù)據(jù)同步完成,進(jìn)行cut-over,即進(jìn)行幽靈表和原表切換。cut-over是最后一步,
鎖住主庫(kù)的源表,等待binlog應(yīng)用完畢,然后替換gh-ost幽靈表為源表。gh-ost在執(zhí)行中,
會(huì)在原本的binlog event里面增加hint和心跳包,用來控制整個(gè)流程的進(jìn)度,檢測(cè)狀態(tài)等。

下載安裝

    從 github 發(fā)布地址下載最新的 binary 包:https://github.com/github/gh-ost/releases

    解壓后就一個(gè) gh-ost 二進(jìn)制文件。

 tar -xvf  gh-ost-binary-linux-20190214020851.tar.gz
 cp gh-ost /usr/bin

常用命令組合

只以主庫(kù)模式介紹,上生產(chǎn)可以直接用:

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
 
 ##########  特別提醒?。。。。。?###########################
 下面這個(gè)參數(shù)有需要再加,加了它就不會(huì)自動(dòng)切換源表和幽靈表,需要手工刪除/tmp/ghost.postpone.flag
 文件后,才會(huì)發(fā)生自動(dòng)切換,請(qǐng)理解該參數(shù)含義。
 --postpone-cut-over-flag-file=/tmp/ghost.postpone.flag

    操作過程中會(huì)生成兩個(gè)中間狀態(tài)的表 _tablename_ghc和_tablename_gho,其中 _tablename_ghc 是記錄gh-ost 執(zhí)行過程的表,_tablename_gho 是目標(biāo)表,也即應(yīng)用ddl語句的幽靈表_tablename_gho。

    執(zhí)行上述的gh-ost命令過程中,會(huì)看到如下的_user100w_ghc的執(zhí)行過程表,和_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 
  表面如果在執(zhí)行g(shù)h-ost的過程中出現(xiàn)Threads_running=50則暫停gh-ost的執(zhí)行
--critical-load=Threads_running=80 
 表明執(zhí)行過程中出現(xiàn)Threads_running達(dá)到80則終止gh-ost的執(zhí)行
--critical-load-interval-millis 當(dāng)值為0時(shí),當(dāng)達(dá)到-critical-load,gh-ost立即退出。當(dāng)值不為0時(shí),當(dāng)達(dá)到-critical-load,gh-ost會(huì)在-critical-load-interval-millis秒數(shù)后,再次進(jìn)行檢查,再次檢查依舊達(dá)到-critical-load,gh-ost將會(huì)退出
--max-lag-millis
  會(huì)監(jiān)控從庫(kù)的主從延遲情況,如果延遲秒數(shù)超過這個(gè)閥值,row copy不會(huì)退出,等待延遲秒數(shù)低于這個(gè)閥值繼續(xù)遷移。
--ok-to-drop-table
 go-ost 執(zhí)行完以后是否刪除老表,加上此參數(shù)會(huì)自動(dòng)刪除老表。默認(rèn)不刪除老表,會(huì)存在_tablename_del表
--initially-drop-ghost-table
 gh-ost 執(zhí)行前會(huì)創(chuàng)建兩張 xx_ghc 和 xx_gho 表,如果這兩張表存在,且加上了這個(gè)參數(shù),那么會(huì)自動(dòng)刪除原 gh 表,從新創(chuàng)建,否則退出。xx_gho 表相當(dāng)于老表的全量備份,xx_ghc 表數(shù)據(jù)是數(shù)據(jù)更改日志,理解成增量備份。
--initially-drop-socket-file
 gh-ost 執(zhí)行時(shí)會(huì)創(chuàng)建 socket 文件,退出時(shí)不會(huì)刪除,下次執(zhí)行 gh-ost 時(shí)會(huì)報(bào)錯(cuò),加上這個(gè)參數(shù)會(huì)刪除老的 socket 文件,重新創(chuàng)建。
--throttle-flag-file
 此文件存在時(shí)操作暫停,刪除文件操作會(huì)繼續(xù)。
--verbose
 執(zhí)行過程輸出日志
--chunk-size
 遷移過程是一步步分批次完成的,這個(gè)參數(shù)是指事務(wù)每次提交的行數(shù),默認(rèn)是 1000。
--max-lag-millis
 會(huì)監(jiān)控從庫(kù)的主從延遲情況,如果延遲秒數(shù)超過這個(gè)閥值,遷移不會(huì)退出,等待延遲秒數(shù)低于這個(gè)閥值繼續(xù)遷移。
--max-lag-millis
 會(huì)監(jiān)控從庫(kù)的主從延遲情況,如果延遲秒數(shù)超過這個(gè)閥值,遷移不會(huì)退出,等待延遲秒數(shù)低于這個(gè)閥值繼續(xù)遷移
--throttle-control-replica
  和--max-lag-millis 參數(shù)相結(jié)合,這個(gè)參數(shù)指定主從延遲的數(shù)據(jù)庫(kù)實(shí)例。
--cut-over-lock-timeout-seconds      
  gh-ost在cut-over階段最大的鎖等待時(shí)間,當(dāng)鎖超時(shí)時(shí),gh-ost的cut-over將重試。(默認(rèn)值:3)
--allow-on-master
 整個(gè)遷移所有操作在主庫(kù)上執(zhí)行
--dml-batch-size   
  在單個(gè)事務(wù)中應(yīng)用DML事件的批量大?。ǚ秶?-100)(默認(rèn)值為10)
--exact-rowcount 
  準(zhǔn)確統(tǒng)計(jì)表行數(shù)(使用select count(*)的方式),得到更準(zhǔn)確的預(yù)估時(shí)間。
--postpone-cut-over-flag-file 
  當(dāng)這個(gè)文件存在的時(shí)候,gh-ost的cut-over階段將會(huì)被推遲,數(shù)據(jù)仍然在復(fù)制,直到該文件被刪除。
--throttle-flag-file string
  當(dāng)該文件被創(chuàng)建后,gh-ost操作立即停止。該參數(shù)適合控制單個(gè)gh-ost操作。-throttle-additional-flag-file string適合控制多個(gè)gh-ost操作。

進(jìn)度提示

    執(zhí)行g(shù)h-ost中,會(huì)有輸出信息,具體解釋如下:

Copy: 27000/58707 46.0%;58707指需要遷移總行數(shù),27000指已經(jīng)遷移的行數(shù),46%指遷移完成的百分比。
Applied: 0,指在二進(jìn)制日志中處理的event數(shù)量。在上面的例子中,遷移表沒有流量,因此沒有被處理日志event。
Backlog: 0/1000,表示我們?cè)谧x取二進(jìn)制日志方面表現(xiàn)良好,在二進(jìn)制日志隊(duì)列中沒有任何積壓(Backlog)事件。
Backlog: 7/1000,當(dāng)復(fù)制行時(shí),在二進(jìn)制日志中積壓了一些事件,并且需要應(yīng)用。
Backlog: 1000/1000,表示我們的1000個(gè)事件的緩沖區(qū)已滿(程序?qū)懰赖?000個(gè)事件緩沖區(qū),低版本是100個(gè)),此時(shí)就注意binlog寫入量非常大,gh-ost處理不過來event了,可能需要暫停binlog讀取,需要優(yōu)先應(yīng)用緩沖區(qū)的事件。
streamer: shvm-5-39.000040:338912890;表示當(dāng)前已經(jīng)應(yīng)用到binlog文件位置

控制gh-ost的過程

#首先要安裝socat工具

yum install socat -y

    注意:上面gh-ost里面配置的--serve-socket-file=/tmp/ghost.sock,下面就用到了。

    gh-ost 可以通過 unix socket 文件的方式來監(jiān)聽請(qǐng)求,DBA 可以在gh-ost命令運(yùn)行后更改相應(yīng)的參數(shù)進(jìn)行限流操作等。

#暫停

echo throttle | socat - /tmp/ghost.sock

#恢復(fù)

echo no-throttle | socat - /tmp/ghost.sock

#終止

對(duì)應(yīng)panic-flag-file參數(shù)文件,當(dāng)tmp目錄存在該文件立即停止
touch /tmp/ghost.panic.flag

#延遲切換(cut-over階段)

--postpone-cut-over-flag-file=/tmp/ghost.postpone.flag
當(dāng)設(shè)置該參數(shù)時(shí)cut-over一直延遲源表和幽靈表的切換,直到你刪除該文件才進(jìn)行切換。

適用場(chǎng)景:

你發(fā)起了一次修改操作,然后估計(jì)完成時(shí)間是凌晨 2 點(diǎn)鐘,可是你又非常關(guān)心最后的切換操作,
非常想看著它切換,這可怎么辦?只需要一個(gè)標(biāo)志位文件就可以告訴 gh-ost 推遲切換了,
這樣 gh-ost 會(huì)只做完拷貝數(shù)據(jù)的操作,但不會(huì)切換表。它還會(huì)仍然繼續(xù)同步數(shù)據(jù),
保持幽靈表的數(shù)據(jù)處于同步狀態(tài)。等第二天早上你回到辦公室之后,
刪除標(biāo)志位文件或者向gh-ost發(fā)送命令echo unpostpone,它就會(huì)做切換了。
我們不希望軟件強(qiáng)迫我們看著它做事情,它應(yīng)該把我們解放出來,讓人去做人該做的事。

#在線修改限速參數(shù)

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

適用場(chǎng)景:

當(dāng)你執(zhí)行了 gh-ost 之后,也許你會(huì)看見主庫(kù)的負(fù)載變高了,那你可以發(fā)出暫停命令。
用 echo throttle 命令生成一個(gè)文件,看看主庫(kù)的負(fù)載會(huì)不會(huì)又變得正常。試一下這些命令,
你就可以知道你可以怎樣控制它的行為,你的心里就會(huì)安定許多。

gh-ost的限制

    凡事有利必有弊,人不可能把所有好事都占有,下面是gh-ost的幾個(gè)限制:

    1、不支持沒有主鍵或者唯一索引的表

    2、不支持有外鍵約束的表(主表和子表都不支持)

    3、不支持表上有觸發(fā)器

    5、表上存在大量寫入的時(shí)候,gh-ost可能永遠(yuǎn)也完成不了

    經(jīng)過測(cè)試:當(dāng)寫入QPS 5000以上,gh-ost無法完成任務(wù),其原因是apply binlog是單線程,可以理解為slave,當(dāng)原表寫入量巨大時(shí)(QPS=5000以上),一直在應(yīng)用日志,而gh-ost設(shè)計(jì)是binlog應(yīng)用優(yōu)先級(jí)高于row copy,所以我們看到row copy進(jìn)度一直沒變,這樣如果原表一直壓力這么大,那么gh-ost DDL將無法完成。經(jīng)過在s3710機(jī)器上測(cè)試如果原表寫入的QPS大于5000將大概率出現(xiàn)此情況,小于5000的話沒問題。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI