🌻

RDS for MySQL から Aurora MySQL に移行したらDatastream for BigQuery が止まった話

2024/04/16に公開

OPENLOGI SREチームの m_norii です。
先日、OPENLOGI のメインデータベースを RDS for MySQL(5.7)から
Amazon Aurora2(5.7 compatible)に移行しました。
この移行により、パフォーマンスや運用上のメリットを享受でき
移行作業自体も大きな事故もなく進められたのですが
(このこと自体はまた別の機会にまとめてアウトプットします)
1点、Datastream for BigQuery の連携でしくじったので、やらかし話として供養したいと思います。

移行前の構成

RDS for MySQLを利用していた時は以下の構成でした。

  • Source DB
  • サービスから参照するレプリカDB複数台
  • 社内用分析サービス(Redashなど)から参照するレプリカ1台

社内分析サービス用のレプリカは、Datastream for BigQueryの機能を利用して
BigQueryにデータを同期していました。

https://cloud.google.com/datastream/docs/overview?hl=ja

移行後の構想

これをAuroraへ移行するにあたり
アプリケーション側からの接続エンドポイントを切り替え無しに移行したかったのと、
何か問題が起きたときの切り戻しをしやすくするため
できるだけ現行構成を踏襲することを優先して考えていました。
具体的には以下の構成にする予定でした。

(字が小さいですが、RDSの構成図で RDSインスタンスだったところをAurora MySQLインスタンスに置き換えています)

移行後に発生したこと

ところが、Auroraに移行した後、「Datastreamのバックフィルが実行できない」という報告がありました。
Datastreamを実行するには、接続元のMySQLでバイナリログが有効になっている必要があります。
RDS for MySQLの場合は、以下の手順に従って構成すると、リードレプリカでもバイナリログが有効になります。
https://cloud.google.com/datastream/docs/configure-amazon-rds-mysql?hl=ja

# (RDS for MySQLの場合。レプリカのバージョン等を確認)
$ aws rds describe-db-instances --output json \
  --db-instance-identifier norii-replica \
  --query 'DBInstances[0].{Engine:Engine,Version:EngineVersion,SourceDB:ReadReplicaSourceDBInstanceIdentifier}'
{
    "Engine": "mysql",
    "Version": "5.7.44",
    "SourceDB": "norii"
}

# (DBに接続し、バイナリログの状態を確認)
$ mysql -uadmin -p -hnorii.xxxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
Enter password:

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

mysql> SHOW VARIABLES LIKE 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+
1 row in set (0.00 sec)

この構成でAuroraに移行したところ
Datastream for BigQuery の Aurora用設定を行っても、
リーダーインスタンスではバイナリログ(log_bin)が有効になりませんでした。

https://cloud.google.com/datastream/docs/configure-amazon-aurora-mysql?hl=ja

# (Aurora MySQLの場合。リーダーインスタンスのバージョン、識別子確認)
$ aws rds describe-db-clusters \
  --db-cluster-identifier norii-aurora \
  --query 'DBClusters[0].{
    EngineVersion:EngineVersion,
    InstanceIdentifier:DBClusterMembers[?IsClusterWriter==`false`]|[0].DBInstanceIdentifier
  }'
{
    "EngineVersion": "5.7.mysql_aurora.2.11.2",
    "InstanceIdentifier": "norii-aurora-reader"
}


# (DBに接続してバイナリログの状態を確認)
$ mysql -uadmin -p -hnorii-aurora-reader.xxxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
Enter password:

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

mysql> SHOW VARIABLES LIKE 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

Datastream for BigQueryは、その仕組み上 MySQLのバイナリログが必要なはずで
なぜバイナリログが有効にならないのがわからず、しばらくハマっていました。

そこで、もう一度(先ほど掲載した) Datastream for BigQueryの Aurora MySQLで構成する場合のドキュメントをよく読むと、以下の記述がありました。

Amazon Aurora MySQL データベース用に CDC を構成する前に、既存の Aurora クラスタがあり、マスター データベース サーバーのライター エンドポイントに接続していることを確認してください。

Aurora MySQLで Datastream for BigQueryを利用する場合は
リーダーインスタンスは利用できず、ライターインスタンスに接続することが必須だということに気づきました。

確かにライターインスタンスの方は、この設定をするとバイナリログが有効になります[1]

# (Aurora MySQL ライターインスタンスのバージョン、識別子確認)
$ aws rds describe-db-clusters \
  --db-cluster-identifier norii-aurora \
  --query 'DBClusters[0].{
    EngineVersion:EngineVersion,
    InstanceIdentifier:DBClusterMembers[?IsClusterWriter==`true`]|[0].DBInstanceIdentifier
  }'
{
    "EngineVersion": "5.7.mysql_aurora.2.11.2",
    "InstanceIdentifier": "norii-aurora"
}

# (バイナリログの状態を確認)
$ mysql -uadmin -p -hnorii-aurora.xxxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
Enter password:

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

mysql> SHOW VARIABLES LIKE 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+
1 row in set (0.00 sec)

そして、Datastream for BigQuery をライターインスタンスの方に接続したところ
無事にバックフィルを実行することができました。

反省点

簡単に言うと「ちゃんとドキュメント読め」の一言に尽きます😓

RDS for MySQLではリードレプリカから繋いでいたので
同じ感覚でAuroraリーダーインスタンスで行けるだろう
・・・という思い込みがミスを招いてしまいました。

また、Aurora移行検証の中で、Datastream for BigQueryへの接続検証も行ったのですが
その時はインスタンスを1台しか立てていませんでした。
インスタンス1台ということは、自動的にライターインスタンスになるので
それで接続できた!と判断してしまった、ということもありました。
この検証も、ちゃんと本番と同じ台数の構成にして検証すべきでした。

まとめ

Aurora MySQLからDatastream for BigQueryを接続するためには
ライターインスタンスに接続しなければいけません。
(リーダーインスタンスのバイナリログをOnにすることはできないようです)

したがって以下のような構成になりました。

脚注
  1. Aurora MySQLは、ライターインスタンスとリーダーインスタンスでストレージを共有する構成なので、デフォルトではバイナリログはOffです。 ↩︎

OPENLOGI Tech Blog

Discussion