ANDPADでのAurora MySQL Ver.2へのバージョンアップ

こんにちは、最近ランニングをサボって体重が増えたANDPADのDBRE植木です。 秋にはフルマラソンに再チャレンジする予定なので改めて頑張ります。

今回はGW前にANDPADでAurora MySQL(以下、Aurora)をVer.1(MySQL5.6互換)からVer.2(5.7互換)にバージョンアップした件について書かせていただきます。DBMSのバージョンアップで重要なのは9割以上準備作業ですが、スタートアップ企業などでは必要な準備ややっておいた方が良い事などがわからないことも多いかと思います。ANDPADに入社して約一年になりますが、その一年の間に実施した準備の話などにも重みを置いて記事を書いてみました。

ANDPAD及びそのシステムについて

ANDPADはクラウド型の建築・建設プロジェクト管理サービスです。建設系の様々なニーズに応えるための統合型サービスですので、機能を追加しやすいようにマイクロサービスの形を取ったシステム構成となっております。今回のDBバージョンアップはメイン部分のDBが対象であり、各マイクロサービスへの影響までを考えてテストや調整をする必要がありました。

AuroraバージョンアップのEOLについて

Aurora Ver.1はEOLが発表されました。 docs.aws.amazon.com 2023年2月までにバージョンアップを完了させる必要があります。また、2022年9月時点からは新規作成ができないなど制限が入り始めます。弊社では発表前から準備を始めていたので焦りはしませんでしたが、AuroraメジャーバージョンのEOLは今回が初めてであり、DBのバージョンアップ経験が少ないAurora利用企業も多いと思います。今回の情報が参考になれば幸いです。

バージョンアップ前にやるべきおすすめ

DBのバージョンアップが難しいのは、DB単体で実施すれば完了するわけではなくDBを使う側を整備する必要があるからです。バージョンアップ後に問題を起こさないためにも事前にできる部分の改善をいたしました。

1. DBのエンドポイント指定をCNAMEにする

コード上に直接クラスターエンドポイントを書いているとDBの向き先を変えるにはデプロイが必要で便利が良くありません。そのためリーダー用とライター用の二つのCNAMEを作ってもらい、コード上にはCNAMEを書くように修正しました。 これにより、DBの向き先切り替えはCNAMEの値を書き換えれば良いだけとなり、テスト時のDB切り替えや本番切り替え作業が楽になりました。

2. インスタンスタイプの統一やリザーブドインスタンスの整理

バージョンアップのように大きな変更の際には改めてインスタンスタイプやRI支払い方法の見直しをかけることをお勧めします。 今回は特にAurora Ver.2(2.09.1以降)でgraviton2インスタンスが利用可能になりました。 graviton2インスタンスはAWSの発表上ではパフォーマンスは向上し、その上金額的に約1割のコスト削減メリットがあります。 弊社ではマイクロサービス構成で増えたDBクラスタを整理しつつ、それらの対応をすることで2割以上のコスト削減を実現いたしました。

3. ROW_FORMATや文字コード対応

MySQL5.6からMySQL 5.7ではinnodb_file_formatのデフォルトがBarracudaに変わり、テーブルのROW_FORMATもデフォルトがDYNAMICに変わっています。また、MySQL8からは文字コードのデフォルトがutf8からutf8mb4になります。 弊社では文字コードは対応済みですがROW_FORMATの変更は一部未対応だったので、今回のタイミングで全てDYNAMICに変更いたしました。 DYNAMICにしないとインデックスをつけられる最大キー長が短めに制限されたり文字列カラムのパフォーマンスなどにも影響するため、デフォルトに合わせておく事をお勧めいたします。

4. SQLやテーブル定義のチューニング

弊社サービスでは企業様、施主様、職人様など様々な方々がコミュニケーションをとるためのメッセージングや通知の機能がございます。コミュニケーション系データはデータ量が多くなりやすく、パフォーマンス問題を引き起こしやすいです。そのためバージョンアップ前にパーティション化やチューニング、古いデータの削除機能の実装などを実施いたしました。DBのメジャーバージョン変更は多かれ少なかれクエリの実行計画が変わります。あまり良くない書き方をしているクエリほど影響を受けやすいので、普段からのチューニングが大切です。

バージョンアップ構成

1. 前提条件

弊社サービスはBtoBのサービスであり、日中帯に及んでサービスを止めるメンテナンスは難しく、夜間にサービス停止を伴うメンテナンスを行なっております。普段の夜間メンテは0時〜5時ですが今回は影響度の大きい変更のため7時まで延長させていただきました。 ほぼノンストップでのバージョンアップをする企業もありますが、弊社では安全を期してサービス停止中に最終動作確認テストをしてから解放する流れにいたしました。

2. バージョンの選定(Aurora Ver.3は?)

Aurora Ver.3が昨年末にリリースされましたが、そちらはまだこなれていないと考えて採用しませんでした。Performance Insightsが実装されないなどVer.2もVer.1相当の機能になるまでかなり長くかかりましたので、一足飛びにせず今回はVer.2へのアップグレードとしました。

aws.amazon.com

3. バージョンアップ方法の選定

バージョンアップの方法として2021年にインプレースアップグレードが可能となりました。この方法はAWSコンソール上の操作だけで終わるためMySQL知識がなくても簡単ですが、その反面で万一問題が発生した場合にスナップショットからのリストアが必要になり、時間の読みが難しいものになっています。 aws.amazon.com

他にバージョンアップの選択肢としては下記のような方法があります。

番号 バージョンアップ方法 作業時間 万一のリストア時間 その他
1 インプレースアップグレード AWSコンソールの操作のみのためMySQLを知らなくても実施可能。既存DBをそのままバージョン上げするため、万一の戻しではリストアをして新しいDBを作る必要があり時間がかかる。
2 スナップショットリストア 既存DBを残したまま新しい環境を作るため戻し時間が短い。インプレースアップグレードとリストアでの環境作成は状況によるが時間はそんなに変わらない。
3 ダンプからのインポート 古くからあるやり方だが、数百GbyteのDBで限られた時間内にやるのは難しい。
4 binlogレプリケーション MySQLの知識が必要なため少し難度が高いが、メンテ当日はDBの向き先変更のみでできる。環境を事前に用意可能なので長いDDLを事前実施できる。
5 DMS等の移行ツール DMSの準備が面倒。4と同様に環境を事前に用意可能。ただし、DMSはbinlogを利用しているので4に対してメリットが無い。

1,2,3についてはリストア時間などどれも時間がかかります。5については裏側でbinlogを利用しているので4以上のメリットがありません。 そのため、弊社では4のbinlogレプリケーションを利用した方法を選択しました。現行のAurora Ver.1にVer.2クラスターをぶら下げる形でコピークラスターを作っておき、メンテ当日にスイッチオーバーします。オンプレミスでのMySQL運用をした事がある方ならよくやる方法かと思います。

docs.aws.amazon.com

バージョンアップ動作確認テスト

1. 検証環境について

他の開発も動いていて頻繁にVer.1とVer.2の切り替えをする必要があったため、staging環境の向き先DBを切り替えつつバージョンアップの動作確認を実施しました。前述したようにCNAMEの値を書き換えるだけでDBの向き先を変える事ができるようにしておいたため、時間単位での切り替えなどをDBRE操作だけで容易に実施できました。

2. ANDPADでの検証時に見つかった問題

UPDATEの範囲指定が大きい処理に問題が発生しやすい状況でした。特に弊社ではUPDATE JOINでの処理に問題が起き、UPDATE対象だけではなくSELECTする側のテーブルまでロックをかけてデッドロックが発生していたのでSELECTとUPDATEの処理を分割いたしました。

実作業

1. 事前作業

binlogレプリカを利用しての環境作成

binlogレプリカを利用した方法では、実際には下記のような構成を作ります。後述するROW_FORMAT対応のためにメンテの1か月ほど前から準備していましたが、直前までは経費削減のために低めのインスタンスにしておくと良いです。

ROW_FORMATの事前変更

binlogレプリケーションの良いところはmasterとなるクラスタに影響せずに、レプリカのみに変更を事前実施できるところです。今回はレプリカであるVer.2サーバーのみにalter文を実施して全テーブルのROW_FORMATを変更いたしました。

2. 当日作業

当日は下記のようにCNAMEの値変更でレプリカに向き先を切り替えるだけです。メンテイン作業やメンテ後の動作確認などはもちろん必要ですが、主要作業であるDB切り替えは1、2分で完了です。

バージョンアップ後の問題

パフォーマンス影響した部分

INの件数が多い処理は大きく影響を受けたようです。range_optimizer_max_mem_sizeの変更がありINの指定が4万件程度からフルスキャンになる事はあるのですが、それだけでなくUPDATEの際のINは5千件くらいでも影響を受けました。Active Recordではpreloadを使ってINが大量発生しがちなので、テストの際に気をつけた方が良いです。弊社では2処理ほど緊急で1000件ずつに処理を分割してもらいました。

まとめ

入社直後からDBのバージョンアップはやるよと言ってきましたが、4月に終わらせてこのブログも書いてようやく一区切りがつきました。 よく言われる言葉ですが、DBの寿命はアプリケーションの寿命より長いです。サービスが成長して長く続けばバージョンアップなどは必ず必要になる作業です。本文中にも書いたように既にAuroraはVer.3がリリースされていますし、今回バージョンアップしたVer.2のベースとなるMySQL5.7 Community版は2023年10月がEOLと既にすぐそばまで来ています。DBもランニングもケアしながら走り続けることが大事です。頑張りましょう!


ANDPADでは現在DBREの採用も行っています。 興味が湧いた方は下記サイトよりカジュアル面談などお気軽にお申し込みください!

engineer.andpad.co.jp