1. 程式人生 > 資料庫 >Mysql online DDL(GH-OST)初嘗試

Mysql online DDL(GH-OST)初嘗試

MySQL的大表DDL操作一直是比較頭疼的問題,因為DDL操作會鎖表影響業務操作,為保障業務連續性不受影響,所以線上DDL操作就很有必要。最近有幸在工作中接觸到這類需求。記錄一下。

gh-ost介紹

gh-ost(Pronunce: ghost),即 gitHub’s online schema transformer,是github使用go語言開發的,專門用於資料庫線上表定義操作(線上DDL操作),其。

原理

簡而言之,①建立滿足要求的ghost table(臨時表);②從源表複製行資料;③重演binlog日誌到ghost table;④用臨時表替換源表。

特性

  • 無觸發器

不像Percona的、 Facebook的  和   都是基於觸發器。gh-ost是基於binlog來監聽表中的資料變更。所以它是非同步的,只有源表的資料被提交後才會將變更同步到ghost table(臨時表)

  • 輕量級(無侵入)

同樣得益於沒有無觸發器的好處,無需建立觸發器,基於binlog重演,同步資料。

  • 可暫停
  • 可動態控制
  • 執行操作的過程中發現負載上升了,gh-ost可以通過Unix socket檔案或者tcp埠(可配置)的方式來監聽請求。

操作者可以在命令執行後更改相應的引數,參考下面的例子:

#限流
echo throttle | socat - /tmp/gh-ost.sock 
#開啟限速,同樣的,可以使用 no-throttle 來關閉限流。
echo no-throttle | socat - /tmp/gh-ost.test.b.sock

#修改限速引數
echo chunk-size=100 | socat - /tmp/gh-ost.t1.sock
echo max-lag-millis=200 | socat - /tmp/gh-ost.t1.sock
echo max-load=Thread_running=3 | socat - /tmp/gh-ost.t1.sock

 

  • 可審計
  • 可測試
  • 值得信賴

操作模式(三種)

1)連線到從庫,在主庫上做遷移(DDL)(預設的方式)

  • 源表歷史資料複製到ghost table在主庫進行讀寫;
  • 變更從庫的二進位制日誌(binlog),將資料的新變更應用到主庫ghost table;
  • 在從庫收集表格式、欄位、行數等資訊
  • 在從庫內部讀取變更事件(如心跳時間)
  • 在主庫切換表(ghost table rename成源表名)

2)連線到主庫,在主庫做遷移

資料複製、binlog重演、切表都是在主庫上執行。此時需要持續關注複製延遲的問題

前提:①主庫的二進位制日誌必須是RBR格式;②必須制定--allow-on-master引數;

3)在從庫遷移/測試

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

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

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

各個工具對比

常用線上DDL的工具,還有pecorna pt-osc。兩者對比主要如下:

 優點缺點
pt-osc併發DML支援較好基於觸發器,對庫的效能有一定影響
gh-ost對主機效能幾乎沒有影響,而且可控制,而且是基於binlog,不急於trigger對源表有一定要求,比如不支援外來鍵;要求binlog為row格式;

 

 

 

 

實踐

1.登入堡壘機(操作生產環境)

2.構建批量生成的gh-ost指令碼的 shell指令碼檔案

[appdeploy@********:/app/lry/onlineddl]$cat online_mcs_ords_task.sh
#!/bin/bash
echo ===partions====
>online_task.txt
ct=1000000000
cat dbmcsords | while read line
do
let ct++ 
i=`echo $line|awk '{print $1}'`
j=`echo $line|awk '{print $2}'`
echo $i $j $ct
echo "nohup /app/mysql-onlineddl-gh/gh-ost --host=$i --port=3306 --user='ghost' --password='******** --allow-on-master --database='"$j"' --table='tt_bar_record_escale_task' --alter='ADD COLUMN EXTEND_ATTACH_EXT mediumtext NULL COMMENT \"新統一擴充套件欄位\" AFTER EXTEND_ATTACH_34;' --max-load=Threads_running=30 --critical-load=Threads_running=1000 --chunk-size=1000 --initially-drop-ghost-table --initially-drop-old-table --timestamp-old-table --cut-over=default --exact-rowcount --concurrent-rowcount --replica-server-id=$ct --execute >$j.log 2>&1 &" >> online_task.txt
echo "" >> online_task.txt
done

選項註釋:

--allow-on-master

針對mater節點做操作。更好的時間是針對slave或者replica操作

-alter string

alter語句(必填)

-max-load string

Comma delimited status-name=threshold. e.g: 'Threads_running=100,Threads_connected=500'. When status exceeds threshold, app throttles writes

-critical-load string

Comma delimited status-name=threshold, same format as --max-load. When status exceeds threshold, app panics and quits

-chunk-size int

amount of rows to handle in each iteration (allowed range: 100-100,000) (default 1000)

-initially-drop-ghost-table

Drop a possibly existing Ghost table (remains from a previous run?) before beginning operation. Default is to panic and abort if such table exists

--initially-drop-old-table

Drop a possibly existing OLD table (remains from a previous run?) before beginning operation. Default is to panic and abort if such table exists

--timestamp-old-table

Use a timestamp in old table name. This makes old table names unique and non conflicting cross migrations

-cut-over string

choose cut-over type (default|atomic, two-step) (default "atomic")

-exact-rowcount

精確計算行數。actually count table rows as opposed to estimate them (results in more accurate progress estimation)

-concurrent-rowcount

(with --exact-rowcount), when true (default): count rows after row-copy begins, concurrently, and adjust row estimate later on; when false: first count rows, then start row copy (default true)

-replica-server-id uint

server id used by gh-ost process. Default: 99999 (default 99999)

-execute

actually execute the alter & migrate the table. Default is noop: do some tests and exit

3.分批執行online_task.txt的指令碼(每次儘量少點,比如40G的表,同時執行10個左右)。

4.jobs命令檢視online  DDL執行情況