Help us understand the problem. What is going on with this article?

【MySQL】AWS Aurora上でもgh-ostオンラインマイグレーション

More than 3 years have passed since last update.

【MySQL】gh-ostでオンラインマイグレーションの応用編です。

gh-ostはMySQLのバイナリログを使ってテーブルを同期します。
一方で、AWSのAmazon Auroraは、バイナリログを使わない方法でリードレプリカを作成します。

※Auroraのリードレプリカが一体どういう仕組みなのかここでは省きますが、過去のAWS SummitのDeep DiveとかでAmazonの超技術を垣間見ることができます。
[レポート] Amazon Aurora deep dive ~性能向上の仕組みと最新アップデート~ #AWSSummit | Developers.IO

さてバイナリログを使っていないとなると、gh-ostの利用はどうなるのでしょうか。
gh-ostにもドキュメントがありますが

https://github.com/github/gh-ost/blob/master/doc/rds.md

gh-ost has been updated to work with Amazon RDS however due to GitHub not relying using AWS for databases, this documentation is community driven so if you find a bug please open an issue!

(gh-ostはAmazon RDSでも動くようになったが、我々GitHubはDBにAWSは使ってないので、このドキュメントはコミュニティに懸かっている。だからバグを見つけたら是非issueを上げて欲しい)

とあり、gh-ostの特徴のひとつである「GitHub社での実績」が欠けます。
実際に使ってみました。

準備

下記条件でAWS RDS Auroraインスタンスを作ります。
t2.smallインスタンスが解禁されたので、検証用途でもAuroraを作りやすくなりました。

  • Aurora 5.6.10a
  • db.t2.small
  • writer×1、reader×1

また、接続元のIPアドレスを調べてセキュリティグループでポートを開けておきます。

gh-ostを使うにはバイナリログが必要です。
先述のとおりAuroraのリードレプリカ作成にはバイナリログは使われませんが、Auroraと他のMySQL等とのレプリケーションのためにバイナリログの出力機能は存在しています。

Aurora と MySQL との間、または Aurora と別の Aurora DB クラスターとの間のレプリケーション - Amazon Relational Database Service

gh-ostを利用するには、DB Cluster Parameter Groupにて「binlog_format=ROW」に設定しておく必要があります。

クラスターエンドポイントに接続し、show binary logsでバイナリログファイルが確認できればOKです。

mysql> SHOW VARIABLES LIKE "binlog_format";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.01 sec)

mysql> show binary logs;
+----------------------------+-----------+
| Log_name                   | File_size |
+----------------------------+-----------+
| mysql-bin-changelog.000001 |       120 |
| mysql-bin-changelog.000002 |     16062 |
+----------------------------+-----------+
2 rows in set (0.01 sec)

今回の検証には下記のデータベース/テーブルを使います。

USE sushiya;

CREATE TABLE sushi(
  id   INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(20),
  INDEX(id)
);

gh-ostの実行

まず入手します。

$ wget https://github.com/github/gh-ost/releases/download/v1.0.36/gh-ost-binary-linux-20170403125842.tar.gz
$ tar xzvf ./gh-ost-binary-linux-20170403125842.tar.gz

gh-ostには3つのモードがありますが、Aurora上ではb. Connect to masterにて実行します。

$ ./gh-ost \
  --user="(ユーザー)" \
  --password="(パスワード)" \
  --host="(クラスターエンドポイント)" \
  --port=3306 \
  --database="sushiya" \
  --table="sushi" \
  --alter="ADD COLUMN price INT DEFAULT 100, ADD COLUMN created_at DATETIME" \
  --allow-on-master \
  --execute

確認します。

mysql> show create table sushi\G
*************************** 1. row ***************************
       Table: sushi
Create Table: CREATE TABLE `sushi` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `price` int(11) DEFAULT '100',
  `created_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.01 sec)

カラムが増えていることを確認できました。

gh-ostの特徴としてa. Connect to replica, migrate on masterモードやc. Migrate/test on replicaモードがありますが、これらを使うためにリードレプリカに接続して実行しようとしても「バイナリログが無効」というエラーで失敗してしまいます。

$ ./gh-ost \
>   --user="(ユーザー)" \
>   --password="(パスワード)" \
>   --host="(リーダーエンドポイント)" \
>   --port=3306 \
>   --database="sushiya" \
>   --table="sushi" \
>   --alter="ADD COLUMN price INT DEFAULT 100, ADD COLUMN created_at DATETIME" \
>   --test-on-replica
2017-05-02 01:11:40 FATAL (リーダーエンドポイント):3306 must have binary logs enabled

もしAuroraからバイナリログを受け取って同期しているSlaveデータベースがあれば、c. Migrate/test on replicaモードでの実行も可能なのではないかと思います。

Interactive commandsの使用

通常のgh-ost利用時と同様に、UNIXドメインソケットを使った制御もAurora経由で可能です。

gh-ost/interactive-commands.md at master · github/gh-ost

テーブル切り替えを保留にするフラグファイルを作成します。

$ touch /tmp/ghost.postpone.flag

実行します。

$ ./gh-ost \
  --user="(ユーザー)" \
  --password="(パスワード)" \
  --host="(クラスターエンドポイント)" \
  --port=3306 \
  --database="sushiya" \
  --table="sushi" \
  --alter="ADD COLUMN price INT DEFAULT 100, ADD COLUMN created_at DATETIME" \
  --allow-on-master \
  --postpone-cut-over-flag-file=/tmp/ghost.postpone.flag \
  --execute

--postpone-cut-over-flag-fileオプションで、先程作成したフラグファイルを指定するとテーブルの同期だけが進み、切り替えが保留状態になります。

ここからステータスの確認など、gh-ost実行途中での操作ができます。

$ echo status | nc -U /tmp/gh-ost.sushiya.sushi.sock

unposeponeでテーブルの切り替えが実行されます。

$ echo unpostpone | nc -U /tmp/gh-ost.sushiya.sushi.sock

確認します。

mysql> SHOW CREATE TABLE sushi\G
*************************** 1. row ***************************
       Table: sushi
Create Table: CREATE TABLE `sushi` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `price` int(11) DEFAULT '100',
  `created_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.01 sec)

カラムが追加されました。

Auroraでgh-ostの必要性がどれくらいあるかはさておき、Auroraでも一部条件下にてgh-ostを利用できることがわかりました。

参考文献

suzuki_sh
Windowsでコンピュータの世界が広がります
https://www.s2terminal.com
finergy-a-tm
大阪府大阪市北区角田町8番1号 梅田阪急ビル オフィスタワー35F
https://finergy.a-tm.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away