発明のための再発明

内部動作のような、プログラムを書くときの参考になることを書きます

gh-ostの動き

gh-ostとは

gh-ostは、binlogを利用したmysql用のデータベースマイグレーションツールです。
大抵のマイグレーションツールがtriggerを使いつつ移行するのに対して、gh-ostはbinlogを使うことで、負荷制御やテスト可能性を実現しています。

githubはここ。
github.com

マイグレーション方法

goroutineを使って並行に動かしているので、図が正しいわけではないですが、おおよそ下図のような動きをします。

f:id:mrasu:20180722194425p:plain

要約すると、
1. ゴーストテーブルを作成してテーブルを変更する
2. binlogを監視ししつつ、既存テーブルを順にコピーし始める。
3. binlogの中に、元テーブルの変更をするものがあれば、ゴーストテーブルにも反映する
4. 既存テーブルのコピーが終わったら、テーブル名を変更

という動きです。

テーブルコピー vs binlog反映

テーブルコピーとbinlogの反映は並行処理をしているので面倒そうですが、gh-ostでは下のように対処しています。

コピーしていない行がbinlogで反映された場合

binlogを基にクエリ実行
insertなら追加され、それ以外は無視される。

コピーした行がbinlogで反映された場合

ただ、実行する。binlogの変更が有るべき姿なので、問題なし

コピー中の行に対して、binlogが反映される場合

もし、取得と挿入の間にbinlogの変更が反映されると、binlogの反映がなかったことになる可能性が有るので、注意が必要です。
gh-ostは、既存行のコピー中にはbinlogの変更を停止することで、この問題を回避しています。 (INSERT INTO SELECTを使っています) ちなみに、既存行のコピーはデフォルトで1000行づつ行われ、1回のコピーが終わった後に、溜まっているbinlogの変更を反映するようになっています。
こうすることで、未反映のbinlogが溜まり過ぎないようになっています。

参考

gh-ostには資料が多く有ります。たとえば、