目錄git
GitHub’s online schema migration for MySQL
項目地址:gh-ostgithub
最初它被命名爲gh-osc: GitHub Online Schema Change,相似於Facebook online schema change和pt-online-schema-change。算法
但後來發生了一種罕見的基因突變,c變成了t。這讓咱們走上了尋找一個新的縮略詞的道路。gh-ost(發音:Ghost),表明GitHub的在線模式轉換器/變形器。數據庫
詳細說明都在安全
cheatsheetbash
。您可能對以各類模式調用gh-ost感興趣:服務器
gh-ost 首先鏈接到主庫上,根據 alter 語句建立幽靈表,而後做爲一個」備庫「鏈接到其中一個真正的備庫上,一邊在主庫上拷貝已有的數據到幽靈表,一邊從備庫上拉取增量數據的 binlog,而後不斷的把 binlog 應用回主庫。圖中 cut-over 是最後一步,鎖住主庫的源表,等待 binlog 應用完畢,而後替換 gh-ost 表爲源表。gh-ost 在執行中,會在本來的 binlog event 裏面增長如下 hint 和心跳包,用來控制整個流程的進度,檢測狀態等。這種架構帶來諸多好處,例如:架構
這是 gh-ost 默認的工做模式,它會查看從庫狀況,找到集羣的主庫而且鏈接上去。修改操做的具體步驟是app
事實上,即便把從庫改爲 Row 格式,這仍然是對主庫侵入最少的工做模式。less
若是沒有從庫,或者不想在從庫上操做,那直接用主庫也是能夠的。gh-ost 就會在主庫上直接作全部的操做。仍然能夠在上面查看主從複製延遲。
這種模式會在從庫上作修改。gh-ost 仍然會連上主庫,但全部操做都是在從庫上作的,不會對主庫產生任何影響。在操做過程當中,gh-ost 也會不時地暫停,以便從庫的數據能夠保持最新。
option | meaning | default value |
---|---|---|
--aliyun-rds | 是否在阿里雲數據庫上執行 | true |
--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語句 | |
--approve-renamed-columns ALTER | 若是你修改一個列的名字,gh-ost將會識別到而且須要提供重命名列名的緣由,默認狀況下gh-ost是不繼續執行的,除非提供-approve-renamed-columns ALTER | |
--ask-pass | MySQL密碼 | |
--assume-master-host
|
爲gh-ost指定一個主庫,格式爲」ip:port」或者」hostname:port」。在這主主架構裏比較有用,或則在gh-ost發現不到主的時候有用 | |
--assume-rbr | 確認gh-ost鏈接的數據庫實例的binlog_format=ROW的狀況下,能夠指定-assume-rbr,這樣能夠禁止從庫上運行stop slave,start slave,執行gh-ost用戶也不須要SUPER權限 | |
--check-flag | ||
--chunk-size
|
在每次迭代中處理的行數量(容許範圍:100-100000) | 1000 |
--concurrent-rowcount | 該參數若是爲True,則進行row-copy以後,估算統計行數(使用explain select count(*)方式),並調整ETA時間,不然,gh-ost首先預估統計行數,而後開始row-copy | true |
--conf
|
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
|
負載達到critical-load時,gh-ost在指定的時間內進入休眠狀態。 它不會讀/寫任何來自任何服務器的任何內容 | |
--critical-load-interval-millis
|
當值爲0時,當達到-critical-load,gh-ost當即退出。當值不爲0時,當達到-critical-load,gh-ost會在-critical-load-interval-millis秒數後,再次進行檢查,再次檢查依舊達到-critical-load,gh-ost將會退出 | |
--cut-over
|
選擇cut-over類型:atomic/two-step,atomic(默認)類型的cut-over是github的算法,two-step採用的是facebook-OSC的算法 | |
--cut-over-exponential-backoff | ||
--cut-over-lock-timeout-seconds
|
gh-ost在cut-over階段最大的鎖等待時間,當鎖超時時,gh-ost的cut-over將重試 | 3 |
--database string | 數據庫名 | |
--debug | debug模式 | |
--default-retries
|
各類操做在panick前重試次數 | 60 |
--discard-foreign-keys | 該參數針對一個有外鍵的表,在gh-ost建立ghost表時,並不會爲ghost表建立外鍵。該參數很適合用於刪除外鍵,除此以外,請謹慎使用 | |
--dml-batch-size
|
在單個事務中應用DML事件的批量大小(範圍1-100) | 1 |
--exact-rowcount | 準確統計表行數(使用select count(*)的方式),獲得更準確的預估時間 | |
--execute | 實際執行alter&migrate表,默認爲noop,不執行,僅僅作測試並退出,若是想要ALTER TABLE語句真正落實到數據庫中去,須要明確指定-execute | |
--exponential-backoff-max-interval
|
||
--force-named-cut-over | 若是爲true,則unpostpone / cut-over交互式命令必須命名遷移的表 | |
--force-table-names
|
在臨時表上使用的表名前綴 | |
--heartbeat-interval-millis
|
gh-ost心跳頻率值 | 500 |
--hooks-hint
|
任意消息經過 GH_OST_HOOKS_HINT 注入到 hook | |
--hooks-path
|
hook文件存放目錄(默認爲empty,即禁用hook)。hook會在這個目錄下尋找符合約定命名的hook文件來執行 | |
--host
|
MySQL IP/hostname | |
--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失敗 | |
--master-password
|
MySQL 主密碼 | |
--master-user
|
MysQL主帳號 | |
--max-lag-millis
|
主從複製最大延遲時間,當主從複製延遲時間超過該值後,gh-ost將採起節流(throttle)措施 | 1500s |
--max-load
|
逗號分隔狀態名稱=閾值,如:'Threads_running=100,Threads_connected=500'. When status exceeds threshold, app throttles writes | |
--migrate-on-replica | gh-ost的數據遷移(migrate)運行在從庫上,而不是主庫上 | |
--nice-ratio
|
每次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
|
當這個文件被建立,gh-ost將會當即退出 | |
--password
|
MySQL密碼 | |
--port
|
MySQL端口,最好用從庫 | |
--postpone-cut-over-flag-file
|
當這個文件存在的時候,gh-ost的cut-over階段將會被推遲,數據仍然在複製,直到該文件被刪除 | |
--quiet | 靜默模式 | |
--replica-server-id
|
gh-ost的server_id | |
--replication-lag-query
|
棄用 | |
--serve-socket-file
|
gh-ost的socket文件絕對路徑 | |
--serve-tcp-port
|
gh-ost使用端口,默認爲關閉端口 | |
--skip-foreign-key-checks | 肯定你的表上沒有外鍵時,設置爲'true',而且但願跳過gh-ost驗證的時間-skip-renamed-columns ALTER | |
--skip-renamed-columns ALTER | 若是你修改一個列的名字(如change column),gh-ost將會識別到而且須要提供重命名列名的緣由,默認狀況下gh-ost是不繼續執行的。該參數告訴gh-ost跳該列的數據遷移,讓gh-ost把重命名列做爲可有可無的列。該操做很危險,你會損失該列的全部值 | |
--stack | 添加錯誤堆棧追蹤 | |
--switch-to-rbr | 讓gh-ost自動將從庫的binlog_format轉換爲ROW格式 | |
--table
|
表名 | |
--test-on-replica | 在從庫上測試gh-ost,包括在從庫上數據遷移(migration),數據遷移完成後stop slave,原表和ghost表馬上交換然後馬上交換回來。繼續保持stop slave,使你能夠對比兩張表 | |
--test-on-replica-skip-replica-stop | 當-test-on-replica執行時,該參數表示該過程當中不用stop slave | |
--throttle-additional-flag-file
|
當該文件被建立後,gh-ost操做當即中止。該參數能夠用在多個gh-ost同時操做的時候,建立一個文件,讓全部的gh-ost操做中止,或者刪除這個文件,讓全部的gh-ost操做恢復 | |
--throttle-control-replicas
|
列出全部須要被檢查主從複製延遲的從庫 | |
--throttle-flag-file
|
當該文件被建立後,gh-ost操做當即中止。該參數適合控制單個gh-ost操做。-throttle-additional-flag-file string適合控制多個gh-ost操做 | |
--throttle-http
|
||
--throttle-query string | 節流查詢。每秒鐘執行一次。當返回值=0時不須要節流,當返回值>0時,須要執行節流操做。該查詢會在數據遷移(migrated)服務器上操做,因此請確保該查詢是輕量級的 | |
--timestamp-old-table | 在舊錶名中使用時間戳。 這會使舊錶名稱具備惟一且無衝突的交叉遷移 | |
--tungsten | 告訴gh-ost你正在運行的是一個tungsten-replication拓撲結構 | |
--user
|
MYSQL用戶 | |
--verbose | ||
--version |
gh-ost --user="root" --password="root" --host=192.168.1.101 --database="test" --table="t1" --alter="ADD COLUMN cc2 varchar(10),add column cc3 int not null default 0 comment 'test' " --allow-on-master --execute
gh-ost --user="root" --password="root" --host=192.168.1.102 --database="test" --table="t" --initially-drop-old-table --alter="ADD COLUMN y1 varchar(10),add column y2 int not null default 0 comment 'test' " --execute
gh-ost --user="root" --password="root" --host=192.168.1.102 --database="test" --table="t" --alter="ADD COLUMN abc1 varchar(10),add column abc2 int not null default 0 comment 'test' " --test-on-replica --switch-to-rbr --execute
gh-osc --user= --password= --host= --database= --table= --max-load=Threads_running=30, --chunk-size=1000 --serve-socket-file=/tmp/gh-ost.test.sock --exact-rowcount --allow-on-master/--test-on-replica --initially-drop-ghost-table/--initially-drop-old-table/--initially-drop-socket-file --max-lag-millis= --max-load='Threads_running=100,Threads_connected=500' --ok-to-drop-table
gh-ost --user="root" --password="root" --host=192.168.1.101 --database="test" --table="t1" --alter="ADD COLUMN o2 varchar(10),add column o1 int not null default 0 comment 'test' " --exact-rowcount --serve-socket-file=/tmp/gh-ost.t1.sock --panic-flag-file=/tmp/gh-ost.panic.t1.flag --postpone-cut-over-flag-file=/tmp/ghost.postpone.t1.flag --allow-on-master --execute
--panic-flag-file
10.1.4.1.暫停操做:
#暫停 echo throttle | socat - /tmp/gh-ost.test.t1.sock #恢復 echo no-throttle | socat - /tmp/gh-ost.test.t1.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