天天看點

gh-ost原理

gh-ost原理

一、三種模式架構圖

gh-ost原理

1、連上從庫,在主庫上修改

這是gh-ost預設的工作模式,它會檢視從庫情況,找到叢集的主庫并且連接配接上去,對主庫侵入最少,大體步驟是:

在主庫上建立_xxx_gho、_xxx_ghc,并修改_xxx_gho表結構;
從slave上讀取二進制日志事件,将變更應用到主庫上的_xxx_gho表;
在主庫上讀源表的資料寫入_xxx_gho表中:insert into igore....select;
在主庫上完成表切換;
           

2、直接主庫修改

在主庫上建立_xxx_gho、_xxx_ghc,并修改_xxx_gho表結構;
從主庫上讀取二進制日志事件,将變更應用到主庫上的_xxx_gho表;
在主庫上讀源表的資料寫入_xxx_gho表中:insert into igore....select;
在主庫上完成表切換;
           

3、在從庫上修改和測試

這種模式會在從庫上做修改。gh-ost仍然會連上主庫,但所有操作都是在從庫上做的,不會對主庫産生任何影響。在操作過程中,gh-ost也會不時地暫停,以便從庫的資料可以保持最新。
--migrate-on-replica選項讓gh-ost直接在從庫上修改表。最終的切換過程也是在從庫正常複制的狀态下完成的。
--test-on-replica表明操作隻是為了測試目的。在進行最終的切換操作之前,複制會被停止。原始表和臨時表會互相切換,再切換回來,最終相當于原始表沒被動過。主從複制暫停的狀态下,你可以檢查和對比這兩張表中的資料。
           

二、原理

gh-ost原理

1、檢查校驗環境

測試db是否可連通,并且驗證database是否存在
确認連接配接執行個體是否正确
權限驗證 show grants for current_user()
binlog驗證,包括row格式驗證和修改binlog格式後的重新開機replicate
原表存儲引擎,外鍵,觸發器檢查,行數預估等
           

2、建立binlog streamer連接配接到主庫或者從庫,添加binlog的監聽

3、建立log表_xxx_ghc和ghost表_xxx_gho并修改ghost表結構到最新

4、開始遷移資料:row copy和binlog apply同時進行

1)最小值:select `id` from darren`.`t4` order by id` asc limit 1;
   2) 最大值:select `id` from darren`.`t4` order by id` desc limit 1;
   3) 計算第一個chunk: select `id` from `darren`.`t4` where `id` >= _binary'1' and `id` <= _binary'58594' order by `id` asc limit 1 offset 999
        最後一個chunk如果不足1000,那麼上面sql查詢為空,這時運作:
        select `id` from (
             select `id` from `darren`.`t4`
             where `id` > _binary'58000' and `id` <= _binary'58594' order by `id` asc limit 1000
        ) select_osc_chunk
        order by `id` desc limit 1;
   4)循環插入資料:insert ignore into `darren`.`_t4_gho` (`id`, `name`, `c1`) 
                 (select `id`, `name`, `c1` from `darren`.`t4` force index (`PRIMARY`)
                  where `id` >= _binary'1' and `id` <= _binary'1000' lock in share mode
                 )
           

4.1、rowcopy資料和應用binlog順序不同是否産生資料沖突

資料遷移過程中sql映射關系:

gh-ost原理

rowcopy和binlog應用各種排列組合:

資料遷移過程,涉及三個操作:A:對原表進行rowcopy;B:應用程式的DML;C:應用binlog到新表,因為DML操作才會記錄binglog,是以C操作一定在B操作的後面,共有如下幾種組合:

gh-ost原理
gh-ost原理
gh-ost原理

1.insert 操作

binlog是最權威的,gh-ost的原則是以binlog優先,是以無論任何順序下,資料都是和binlog保持一緻,如果rowcopy在後,會insert ignore,如果binlog apply在後會replace into掉。

2.update/delete 操作

對已經rowcopy過的資料,出現對原表的update/delete操作。這時候會全部通過binlog apply執行,注意binlog apply的update是對某一條記錄的全部列覆寫更新,是以不會有累加的問題。

對尚未遷移的資料,出現對原表的update/delete操作。這時候對新表的binlog apply會是空操作,具體資料由rowcopy遷移。

特殊情況下:

先對原表更新完以後,rowcopy在binlog apply之前把資料遷移了過去,而在binlog event過來以後,會再次應用,這裡有問題?其實結合gh-ost的binlog apply之前把資料遷移了過去,

而在binlog的sql映射規則,insert操作會被replace重新替換掉,update 會更新對應記錄全部行,delete 會是空操作。最終資料還是一緻的狀态。

4.2、binlog同步資料何時結束?

copy完資料向_xxx_ghc寫入status:AllEventsUpToLockProcessed:1533533052229905040,當binlogsyncer過濾到該值表示所有event都已應用
           

5、copy完成後進行原子性cut-over階段

gh-ost原理
5.1) C10:
                建立magic表_xxx_del,目的為了防止過快的進行rename操作和意外情況rename
                對源表和magic表_xxx_del加write鎖
5.2) C11...C19: 新的請求進來,關于原表的請求被blocked
5.3) C20:       執行:rename table `t4` to `_t4_del`,`_t4_gho` to `t4`;這時被阻塞,timeout:3s。(這一步隻有binlog event應用完成後)
5.4) 檢查是否有blocked 的RENAME請求,通過show processlist
5.5) C10:
                删除magic表(隻有show processlist裡存在被block的rename才進行)
                釋放瑣

不同階段失敗後如何處理:

如果5.1失敗,退出程式,比如建表成功,加鎖失敗,退出程式,未加鎖
rename請求來的時候,會話C10死掉,lock會自動釋放,同時因為_xxx_del的存在rename也會失敗,所有請求恢複正常
rename被blocked的時候,會話C10死掉,lock會自動釋放,同樣因為_xxx_del的存在,rename會失敗,所有請求恢複正常
C20死掉,gh-ost會捕獲不到rename,會話C10繼續運作,釋放lock,所有請求恢複正常
           

6、清理戰場

7.1) 關閉binlogsyncer連接配接
7.2) 删除源表和_t4_ghc表           

繼續閱讀