前回、
その他オプション
ここでは、
--chunk-size int
基テーブルの既存データをゴーストテーブルへコピーするときのチャンクサイズを指定します。デフォルトは1000です。
以下は一般ログから出力したものですが、
insert /* gh-ost `sysbenchdb`.`sbtest1` */ ignore into `sysbenchdb`.`_sbtest1_gho` (`id`, `k`, `c`, `pad`) (select `id`, `k`, `c`, `pad` from `sysbenchdb`.`sbtest1` force index (`PRIMARY`) where (((`id` > _binary'1') or ((`id` = _binary'1'))) and ((`id` < _binary'1000') or ((`id` = _binary'1000')))) lock in share mode)
--allow-on-master
マイグレーションをマスター上で直接実行するようにします。つまり、--host
オプションにマスターのホスト名を指定して実行します。
gh-ost \ --host=Master.Hostname \ --port=3306 \ --user="ghost_user" \ --password="xx" \ --database="sysbenchdb" \ --alter="ALTER TABLE sbtest1 ADD col1 int;" \ --allow-on-master \ --execute
--exact-rowcount と --concurrent-rowcount
--exact-rowcount
が指定されると、SELECT COUNT(*)
を実施して実際の件数を取得します。これにより、--concurrent-rowcount
は--exact-rowcount
と連動しています。
Trueの場合、SELECT COUNT(*)
をマイグレーション作業と並列に動作します。デフォルトはTrueです。
--test-on-replica
テストのために使用されるオプションです。マイグレーションをレプリカのみで実施し、
ただし注意として、
注意点
最後に、
ユニークキーの追加
gh-ostを使用して、
以下のように、
mysql> CREATE TABLE `uniq_test` ( `id` int NOT NULL, `uniq` int DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin Query OK, 0 rows affected (0.01 sec)
mysql> SELECT * FROM uniq_test; +----+------+ | id | uniq | +----+------+ | 1 | 1 | | 2 | 100 | | 3 | 1 | +----+------+ 3 rows in set (0.00 sec)
uniqカラムに対してユニークキーを貼ってみたいと思います。id:1とid:3のレコードのuniqカラムの値がどちらも1となっているため、
まずは、
mysql> ALTER TABLE uniq_test ADD UNIQUE KEY (uniq); ERROR 1062 (23000): Duplicate entry '1' for key 'uniq_test.uniq'
では、
gh-ost \ --host=192.168.0.2 \ --port=3306 \ --user="ghost_user" \ --password="xx" \ --database="sysbenchdb" \ --alter="ALTER TABLE uniq_test ADD UNIQUE KEY (uniq);" \ --execute <snip> # Done
ログは割愛しましたが、# Done
が表示されました。
mysql>SELECT * FROM uniq_test; +----+------+ | id | uniq | +----+------+ | 1 | 1 | | 2 | 100 | +----+------+
データを見てみると、
このような動作になるので、
なぜこのようなことが起こるのでしょうか。
簡単に説明しますと、INSERT IGNORE INTO..
を使用しているためです。INSERT IGNORE INTO..
の問題点は、
マイグレーション後のデータロストを懸念する方は、--test-on-replica
オプションで先にテストすると良いでしょう。
ストレージサイズ
gh-ostはMySQLのストレージを多く使用します。ゴーストテーブルは基テーブルと同等のサイズになりますし、
スワップ
gh-ostではMySQLのバイナリログを大量に書き込むと説明しました。それは、
行ベースレプリケーションは行単位でバイナリログに書きます。そして、
バイナリログ書き込みの仕組みは、
MySQL 8.binlog_
パラメータによってバイナリログのパージを秒数で指定できるようになりました。大きなテーブルをgh-ostでマイグレーションするときはこのパラメータを調整してバイナリログを早めにパージするのが良いでしょう。これにより、ストレージサイズの問題も併せて解消されます。
スロットル
スロットルにおいても注意点があります。高負荷なMySQLであると、
また、
まとめ
gh-ostについて3回に渡って紹介しました。簡単にまとめると、
- ディスクサイズなど実行前に注意点に記載してあることを確認する
- レプリカの設定がbinlog_
format=ROW,binlog_ row_ image=FULL,log_ slave_ updates=ONになっていることを確認します。 - gh-ostは最小限のオプションでも割と安全に動作します。
- スロットルを
--max-lag-millis
や--max-load
オプションで調整する - カットオーバーをハンドリングするには
--postpone-cut-over-flag-file
オプションを使用する。 --test-on-replica
オプションで確実にマイグレーションを行うためにテストする
そして、