手藝分享 | gh-ost 在線 ddl 變動東西​

作者簡介:

楊奇龍,網名“北在南邊”,7年DBA老兵,現在任職於杭州有贊科技DBA,主要擔任數據庫架構設想和運維平台開闢事情,善於數據庫機能調優、故障診斷。

一、媒介

作為 MySQL DBA,置信我們人人都邑對大表變動(大於10G 以上的)比較頭疼,尤其是某些 DDL 會鎖表,影響營業可持續性。現在通用的計劃運用 Percona 公司開源的 pt-osc 東西處置懲罰致使鎖表的操縱,另有一款 github 基於 go 言語開闢的 gh-ost。本文主要引見 gh-ost 運用方法,其事情道理放到下一篇文章引見。

二、運用

2.1 gh-ost 引見

gh-ost 作為一個假裝的備庫,能夠從主庫/備庫上拉取 binlog,過濾以後從新運用到主庫上去,相當於主庫上的增量操縱經由歷程 binlog 又運用回主庫自身,不過是運用在幽魂表上。
《手藝分享 | gh-ost 在線 ddl 變動東西​》

其大抵的事情歷程:

  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 操縱形式

《手藝分享 | gh-ost 在線 ddl 變動東西​》

a. 銜接到從庫,在主庫做遷徙
這是 gh-ost 默許的事情體式格局。gh-ost 將會搜檢從庫狀況,找到集群組織中的主庫並銜接,接下來舉行遷徙操縱:

  1. 行數據在主庫上讀寫
  2. 讀取從庫的二進制日記,將變動運用到主庫
  3. 在從庫網絡表花樣,字段&索引,行數等信息
  4. 在從庫上讀取內部的變動事宜(如心跳事宜)
  5. 在主庫切換表

假如你的主庫的日記花樣是 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.b 重修表 alter table b 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 實行歷程的表,其紀錄相似以下:
《手藝分享 | gh-ost 在線 ddl 變動東西​》

_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 在線 ddl 變動東西​》

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…
https://blog.csdn.net/poxiaon…

五、總結

整體來說 gh-ost 是一款異常精彩的開源產物,謝謝 github 為我們 MySQL DBA 供應了一種處置懲罰大表 ddl 的東西,迎接還沒運用的朋儕試用該東西。

參考文章
https://www.cnblogs.com/zhouj…
https://segmentfault.com/a/11…

    原文作者:愛可生雲數據庫
    原文地址: https://segmentfault.com/a/1190000020409138
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞