您好,登錄后才能下訂單哦!
如何理解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ù)模式介紹:
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操作。
執(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文件位置
#首先要安裝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的幾個(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ì)億速云的支持。
免責(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)容。