初試GH-OST

最近老闆讓作一個gh-ost和pt-osc 的對比測試,本文將對二者作對比。mysql

一。原理和所用說明git

  PT-OSC GH-OST
原理

1.建立一個和要執行 alter 操做的表同樣的新的空表結構(是alter以前的結構)
2.在新表執行alter table 語句
3.在原表中建立觸發器3個觸發器分別對應insert,update,delete操做
4.以必定塊大小從原表拷貝數據到臨時表,拷貝過程當中經過原表上的觸發器在原表進行的寫操做都會更新到新建的臨時表
5.Rename 原表到old表中,在把臨時表Rename爲原表
6.若是有參考該表的外鍵,根據alter-foreign-keys-method參數的值,檢測外鍵相關的表,作相應設置的處理
7.默認最後將舊原表刪除github

1.在變動的服務器上 建立 ghost table( _tbname_gho like tbname)
2.更改 _tbname_gho 結構爲新表結構
3.做爲mysql的slave鏈接mysql server,並記錄新增binlog event
4.交替執行: 應用新增events到 ghost table 和 複製老表的記錄到 ghost table
5.table重命名(ghost table 替代 老表)sql

其中有2種經常使用用法:
1.鏈接從庫,變動主庫 - 默認方式,slave須要開啓log-slave-update
2.鏈接主庫,變動主庫 - 必須ROW格式,帶上參數--allow-on-master"服務器

使用限制

1.原表必需要有主鍵或者惟一索引(不含NULL)
2.原表上不能有觸發器存在
3.使用前需保證有足夠的磁盤容量,由於複製原表須要一倍的空間
4.在阿里RDS 上使用須要增長參數no-version-check異步

1.原表必需要有主鍵或者惟一索引(不含NULL)
2.不支持外鍵
3.不支持觸發器
4.不支持虛擬列
5.不支持 5.7 point類型的列
6. 5.7 JSON列不能是主鍵
7.不能存在另一個table名字同樣,只是大小寫有區別
8.不支持多源複製
9.不支持M-M 雙寫
10.不支持FEDERATED enginesocket

重要參數說明

--max-load,默認threads_running=25,能夠指定多個指標來限速,每一個chunk拷貝完會檢查,超過閥值會暫停複製。若是不指定該參數,工具會檢查當前運行值並增長20%
--critical-load,默認爲threads_running=50,若是不指定,則工具檢查當前運行值並當運行到200%是退出工具運行
--max-lag,默認1s,若是發現延遲大於該值,則暫停複製數據。
--check-interval,配合max-lag使用,檢查從庫超過延時後,該工具睡眠多久
--recursion-method,指定從庫的發現機制,processlist,dsn,none 等
--chunk-time,默認0.5秒,拷貝數據行的時候爲了保證0.5秒內拷貝完一個chunk,動態調整下一次chunk-size的大小
--[no]check-replication-filters,若是工具檢查到服務器選項中有任何複製相關的篩選,工具會報錯退出,默認爲yes
--chunk-size,指定塊大小,默認1000行。工具

--max-load=Threads_running=25 表面若是在執行gh-ost的過程當中出現Threads_running=25則暫停gh-ost的執行
--critical-load=Threads_running=60 代表執行過程當中出現Threads_running達到60則終止gh-ost的執行
--chunk-size=1000 設置每次從原表copy到 ghost table的行數
--ok-to-drop-table 執行完以後刪除原表
--allow-on-master 直連主庫執行性能

優勢  1.執行速度快,業界使用比較普遍,較穩定

1.讀binlog能夠放在從庫執行,減小主庫的壓力
2.不須要建立觸發器,對原表沒有改動測試

風險點  

1.須要建立觸發器,對原表有改動
2.涉及主鍵的更改須要review

1.當系統負載極高時,gh-ost有可能沒法跟上binlog日誌的處理(未測試過該場景)
2.限制比較多,見上文
3.涉及主鍵的更改須要review

運行命令實例 pt-online-schema-change --user=db_monitor --password=xxx --host=127.0.0.1 --port=xxx --alter "add COLUMN c2 varchar (120) not null default ''" D=sbtest,t=sbtest1 --no-check-replication-filters --alter-foreign-keys-method=auto --recursion-method=none --print --execute ./gh-ost --assume-master-host=ip:port --master-user=db_monitor --master-password=xxx --user=db_monitor --password=yyy --host=10.xxx --port=port  --alter="ADD COLUMN c2 varchar(120)"   --database=sbtest --table="sbtest1" -execute --initially-drop-old-table --initially-drop-socket-file --initially-drop-ghost-table

 

二,性能測試對比

1. 測試場景

       16core CPU,2G buffer pool的測試實例,5.5的MySQL版本異步主從,2kw行記錄,4.8GB 測試表大小

2. 測試結果(不限速),複製延時用zabbix 監控seconds behind master 的值

        

3. 結果展現

 

三, 最後說一下GH-OST的 cut over

gh-ost利用了MySQL的一個特性,就是原子性的rename請求,在全部被blocked的請求中,優先級永遠是最高的。
gh-ost基於此設計了該方案:一個鏈接對原表加鎖,另啓一個鏈接嘗試rename操做,此時會被阻塞住,當釋放lock的時候,rename會首先被執行,其餘被阻塞的請求會繼續應用到新表。

 

參考資料:

https://github.com/github/gh-ost

https://m.aliyun.com/yunqi/articles/62928

http://www.tabdba.com/?p=175

相關文章
相關標籤/搜索