オンラインスキーマ変更ツール “gh-ost” の紹介

この記事は最終更新から6年以上経過しています。内容が古くなっている可能性があります。

はじめに

Percona Liveなどのイベントでも度々話題になっている gh-ost について調べてみました。

gh-ost」(GitHub’s Online Schema Transmogrifier/Transfigurator/Transformer/Thingy)は、Githubが開発するオープンソースのスキーママイグレーションツールです。
その綴りから、「ゴースト」と呼ばれることもあります。

なお、gh-ost の詳細については以下の翻訳記事が非常に参考になります。

gh-ost:GitHubのMySQL向けオンライン・スキーマ・マイグレーションツール

目次

既存ソリューションとの違い

gh -ost と同様の特徴を持つ機能(ツール)として、「オンラインDDL」「pt-online-schema-change」がありますが、両者には以下のような欠点があると gh-ost の作者は指摘しています。

  • ALTER文に長い時間がかかる場合、その処理がスレーブに伝播した時に大幅なレプリケーション遅延が発生する
  • pt-online-schema-changeのトリガを利用したデータ同期処理が、深刻なロック競合を引き起こす場合がある
  • ALTER処理を一度実行すると完了するまで手動停止できない(pt-online-schema-changeなら自動停止の基準を設定することは可能)

gh-ost は、上記のような課題を克服するために開発されたツールです。

制限事項

gh-ost を使う上で、以下のような制限事項(必要事項)を理解しておく必要があります。

  • binlog_format=ROW / binlog_row_image=FULL が設定されている
  • 外部キー、トリガー、generated columnなどはサポートされていない
  • マイグレーション対象のカラムに NULL が含まれていてはいけない
  • PK もしくはユニークキーが設定されている
  • AWS RDSは利用制限あり / Google Cloud SQL はサポート外
  • 以下の権限を持ったMySQLユーザが存在する

(1) ALTER, CREATE, DELETE, DROP, INDEX, INSERT, LOCK TABLES, SELECT, TRIGGER, UPDATE on \<変更対象のテーブル>

もしくは

(2) SUPER, REPLICATION SLAVE on *.*

※ 詳細は以下のマニュアルを参照してください
Requirements and limitations

使い方

gh-ost はデフォルトでスレーブに接続し、そこからバイナリログを利用してマスタに変更を反映させます。
もちろん、スレーブが存在しない環境などではマスタに対して直接 gh-ost を実行することも可能です。

インストール

Githubから最新のバイナリをダウンロードし、解凍すれば準備は完了です。

[code lang=text]
[root@test-4U-1 ~]# wget https://github.com/github/gh-ost/releases/download/v1.0.42/gh-ost-binary-linux-20170914095800.tar.gz

[root@test-4U-1 ~]# tar zxvf gh-ost-binary-linux-20170914095800.tar.gz
gh-ost
[root@test-4U-1 ~]# ls -lh gh-ost
-rwxr-xr-x 1 501 games 7.9M 9月 14 15:58 gh-ost
[/code]

マスタ・スレーブの場合

スレーブに対して gh-ost を実行します。ツールを制御するための様々なオプションが用意されているため、状況に合わせて使い分けることができます。

[code lang=text]
./gh-ost –user="root" –password="MySQL5.7" –host=192.168.20.21 –port=3306 –database="d1" \
–table="t1" –alter="ADD COLUMN col_new INT, ADD INDEX idx_1(col1)" –test-on-replica –execute
[/code]

シングルマスタの場合

マスタに対して直接 gh-ost を実行します。

ベンチマーク

弊社の検証環境で ALTER TABLE(オンラインDDL) / ALTER TABLE(ALGORITHM=COPY) / pt-online-schema-change / gh-ost の4パターンを実行し、所要時間を比較してみました。なお、全てシングルマスタの環境です。

テスト環境

実メモリ62GB、CPU8コアの物理サーバです。OSは CentOS 7.4 、MySQLは現時点で最新版の MySQL 5.7.20 を使用します。my.cnfは以下の部分のみ変更しております。

テストデータは、以下のようなrubyスクリプトを利用して2000万行のランダムデータを生成しています。
なお、3つのテーブル全てに同じレコードが格納されています。

計測準備

バッファプールの影響を無くすため、各ツールのツール実行前にメモリをクリアします。

計測:ALTER TABLE(オンラインDDL)

計測:ALTER TABLE(ALGORITHM=COPY)

※ 3時間51分程度

計測:pt-online-schema-change

※ 約 3時間 51 分 程度

計測:gh-ost

※ 3時間53分程度

ベンチマーク(更新クエリ実行)

上記の例を見てわかる通り、基本的にどの方法も実行時間に大きな差はありません。
次に ALTER TABLE 実行中に、並行して更新クエリを実行した場合を見てみましょう。

方法は簡単で、ALTER TABLE実行中に別コンソールで以下のコマンドを実行し、
500万行のINSERTを行います(ツール毎に対象テーブルは変更します)。

また、innodb_online_alter_log_max_size変数の設定値を引き上げる必要があります。/etc/my.cnf に以下の設定を追記しておきましょう。

innodb_online_alter_log_max_size = 1G

計測:ALTER TABLE(オンラインDDL)

※ 2時間33分程度

計測:pt-online-schema-change

※ 5時間55分程度

計測:gh-ost

※ 7時間20分程度

計測結果まとめ

実施したベンチマークの結果をまとめると、以下のようになりました。

オンラインDDL ALGORITHM=COPY pt-online-schema-change gh-ost
ALTERのみ 14分29秒 3時間51分 3時間51分 3時間53分
ALTER + INSERT 2時間33分程度 ~~~~~ 5時間55分程度 7時間20分程度
並列実行INSERT 3時間50分 ~~~~~ 8時間33分 4時間13分

最適な選択肢はやはり標準のオンラインDDLと考えられます。
オンラインDDLが使えない場合は、pt-online-schema-change か gh-ost の二択となりますが、ALTER自体を早く終わらせたい場合は前者、並列で実行される更新クエリへの影響を最小限にしたい場合は後者が適しているように考えられます。

ただし、サーバスペックやテーブル定義・サイズなどによって変わってくる可能性は高いため、実際に利用する場合は自分の環境で入念に検証を行うことをお勧めします。


 

 

よかったらシェアしてね!
  • URLをコピーしました!
目次