安全なAuroraアップデートを目指して多段レプリケーションを構築した話
はじめに
はじめまして。システム基盤グループでSREをやっている伊藤と申します。
今回はAWS MySQL Auroraのメジャーバージョンアップグレードに対して、弊社が行う予定の手法に関して紹介いたします。
対象読者
- Aurora MySQLのアップグレードに関して興味がある方
背景
2023年10月頃弊社でもAurora MySQL2系のサポート切れのことを把握し、2024/02月頃から影響調査などの対応を開始していきました。
ダウンタイムを可能な限り短くするなどアップグレード時に重要視する項目、またその優先度に関しては、各サービスにおいて異なることかと思います。
弊社において重要視したのは「問題が発生した場合に、問題発生段階のデータを持った上で、過去のバージョンに切り戻すことができる。」という点でした。
その観点を持った上でアップグレードの方式に関して協議をし、最終的に手動によるB/Gデプロイに加えて、レプリケーションを実施することにしました。
アーキテクチャ
本番とテスト環境のデータ量の差分を考慮した結果、移行する前に2系から3系へのレプリケーション、また移行後の事前確認や下位バージョンへのレプリケーションがサポート外ということもあり、入念な検証を行うという観点で3系から2系へのレプリケーションを実施しております。
上図における3の状態で、本番環境を1ヶ月程運用し、問題ないことを確認しております。
弊社の方針の類似事例として、GitHubにおけるオンラインアップグレード対応があります。
レプリケーションの実施に関して
レプリケーションのモードに関して
現在レプリケーション方式としては、GTID(グローバルトランザクション識別子)を用いたものと、バイナリログを用いたものがあります。バイナリログには様々な情報が含まれているため、GTIDと比較した際にI/Oなどの負荷が高いこともあり、基本的にはGTIDを用いたレプリケーションの方が良いと思います。しかしながら弊社においては、多段レプリケーション構成は検証時のみの構成であることや、スケジュールの猶予、MySQLバージョン間のGTID仕様の違いのリスクを考慮した結果、バイナリログ方式を採用しました。
環境構築に関して
大まかな流れとしては下記の通りです。
- 本番DBのスナップショットを取得し、レプリケーション用のクラスターを二つ作成します。
a. 作成した内の一つに対して、インプレースでのバージョンアップを行います。
b. またその際に、RDS > データベース > 作成したクラスター > writerインスタンス > ログとイベント を確認すると下記のようなログが出ているので、こちらをメモしておきます。
Binlog position from crash recovery is mysql-bin-changelog.xxxxx yyyyy
- 作成した各クラスターにおいて、それぞれレプリケーション用SQLの実行をします。
CALL mysql.rds_set_external_master ('レプリケーション先のエンドポイント', 接続先のポート, 'レプリケーション用ユーザー名', 'パスワード', 'mysql-bin-changelog.xxxxx', yyyyyy, 0);
CALL mysql.rds_start_replication;
※ mysql-bin-changelog.xxxxxとyyyyyのところにおいては、1-b.で取得した値をそれぞれ入力します。
1.の作業開始時点からデータ量がレプリケーション開始するまでに発生するデータ量次第ではありますが、こちらの手段によって、無停止で環境を構築することができました。
また運用面においても、バイナリログの保持期間に関して、ストレージの使用量を確認しながら、1日から3日に伸ばすことで問題が発生した際の猶予期間を増やしたり、レプリケーションの異常を検知できるように、レプリケーション用クラスターにてエラーログの出力を有効化したりするなど考慮しました。
実際に発生したエラーに関して
- 接続エラー
エラーサンプル
Error reading packet from server for channel '': Lost connection to MySQL server during query (server_errno=2013) (rpl_replica.cc:4283)
対応方法
AuroraBinlogReplicaLagなどから、その後の接続が復旧しているかどうか確認します。
復旧していない場合には、原因調査をする必要があります。弊社の事例においては、特定時間帯に発生する傾向はありましたが、全て自動で復旧しておりました。
- 重複キーエラー
エラーサンプル
Slave SQL for channel '': Worker 1 failed executing transaction 'ANONYMOUS' at master log mysql-bin-changelog.115186, end_log_pos 98543435; Could not execute Write_rows event on table WNSF.LoginLog; Duplicate entry '138371075' for key 'hogehoge.PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log FIRST, end_log_pos 98543435, Error_code: MY-001062
対応方法
unique keyの重複なので、基本的には発生しません。今回、アップグレードのテスト時に、レプリケーションを実行する順番を逆にした場合に発生しました。エラーにより手順のミスを検知し、手順のブラッシュアップをしました。
発生した場合には、データの確認、調整またはレプリケーション環境の構築からやり直す必要があります。
所感
今回はDBというサービスにおける重要な部分に関して、どのような方式でアップグレードを行うかに関してお話しいたしました。上述したように何を重視するかに関しては、各サービスによって異なってくると思います。今回紹介した例はあくまで一例でしかありませんが、ご参考になれば幸いです。
著者プロフィール
伊藤 拓矢
システム基盤グループ システム基盤チーム所属
新卒の会社でERPの基盤システム開発を経験。その後をレジャー、アクティビティ系の予約サイトでのSREを経てウェルスナビ株式会社にSREとして入社。現在は資産運用サービスや新規プロダクトのインフラ環境構築を中心にサービス運用改善、監視運用、IaC開発などを担当しています。
Discussion