Aurora MySQLのバージョンアップでハマった話

2022/12/13に公開

はじめに

この記事はteam DELTA Advent Calendar 2022 13日目の記事です。

自己紹介

山田 尚人(やまだ なおと)といいます。
SEVENRICH GROUP のグループ でCTO Boosterをメインで行っています。
SEVENRICH GROUPとは?
https://costcut.cloud/

概要

CTO Boosterではスタートアップの企業に対して、パブリッククラウドのコストの見直しをメインで行っています。
スタートアップのお客さまが多く、人員が常に足りていないことから、コスト削減以外にも幅広い相談を頂きます。
その中で、何度かAuroraのバージョンアップを実行させていただくことがありました。
その時に発生したパターンについて紹介していきます。

バージョンアップの手順について

バージョンアップの手順について簡単に整理しておきます。
環境によって詳細は異なりますが、おおよそ以下のような手順になると思います。
一般的には、バージョンアップ中にある程度の停止時間が発生するので、サービスを停止することが多いと思います。

  • サービスを停止する
  • アプリケーションからRDBへの接続を停止する
  • RDBのバージョンアップをする
    • Auroraの場合は、以下の2つのパターンになります
      • クラスターの変更から、バージョンを変更する(インプレース)
      • スナップショットを作成して、スナップショットから起動するRDBのバージョンを新しくする[1]
  • 正しく移行できているかの確認を行う
  • サービスを再開する

ほとんどの場合、サービスを一時的に停止するため、失敗やトラブル発生時にはサービスの再開時間が遅れ、事業への影響が発生します。
そのため、失敗しないように、あらかじめテスト環境や本番環境のコピーを作成して検証を行うことが一般的かと思います。

バージョンアップ時に発生した現象

私が遭遇した状況について1つずつ紹介します。

  • キャパシティ不足で起動していないインスタンスがあるために失敗する
  • PreUpgradeの処理で失敗する
  • ユーザが持っている権限がバージョンアップに伴って、消える
  • スナップショットからインスタンスを起動したら、データがほとんど入っていないインスタンスが作成される

キャパシティ不足で起動していないインスタンスがあるために失敗する

実施した作業

MySQL 5.6 → 5.7のバージョンアップの時に発生しました。
オートスケールを設定しており、複数のリーダーインスタンスが起動していました。
そのうちの1つのインスタンスがAWS側のキャパシティ不足のために起動していませんでしたが、不足しているインスタンスを停止等すると、別のインスタンスが起動し始める恐れがあると判断して、そのままインプレースでのバージョンアップを行いました。

発生した現象

バージョンアップ中ですという表記のまま、何時間たっても終了しませんでした。
「最近のイベント」の部分を確認すると、バージョンアップの処理を何度も実行しようとして、失敗しているらしいのが確認できました。

対策方法

キャパシティ不足で起動していないインスタンスを削除することで、バージョンアップが進みました。
ただ、作業時はこの前提を知らなかったので、別のスナップショットを作成して、そのスナップショットから別のクラスターを作成して処理を継続しました。

PreUpgradeの処理で失敗する

実施した作業

MySQL 5.7 → 8.0のバージョンアップの時に発生しました。
当時はインプレース(クラスターの変更でバージョンアップ)での変更ができなかったので、スナップショットを作成して、別のクラスターを作成しています。

https://aws.amazon.com/jp/about-aws/whats-new/2022/09/amazon-aurora-supports-in-place-upgrades-mysql-5-7-8-0/

スナップショットからクラスターを作成する際に、MySQLのバージョンを8.0に変更して起動しました。

発生した現象

一定時間経過後、MySQL 5.7のクラスターが起動しました。

原因

MySQLのバージョンを変更すると、内部的にバージョンアップできるかどうかのチェックを実行(PreUpgrade)して、OKだった場合にバージョンアップの処理を実行しているようです。
このバージョンアップのチェックが失敗すると、MySQL 5.7のスナップショットから作成した場合、MySQL 8.0のバージョンを指定しているにも関わらず、MySQL 5.7のクラスターが作成されます。
この点に気が付かず、バージョンの指定をミスしたと勘違いして何度か作業を繰り返し行ってしまいました。

対策方法

エラーが発生しているときに、ログに詳細がでているので、その部分を修正することでPreUpgradeの処理が通るように修正できます。
ログに出ている部分を修正 → スナップショットからバージョンアップ → 修正を何度か繰り返して、原因を修正していきました。
※ テスト環境や数週間前に実施した本番環境では問題なくバージョンアップが出来ていたため、検知に時間がかかってしまいました。

MySQLのユーザが持っている権限がバージョンアップに伴って、消える

実施した作業

MySQL 5.7 → 8.0のバージョンアップの時に発生しました。
複数のデータベースを利用しているMySQLのバージョンアップを別のクラスターとして作成しました。

発生した現象

バージョンアップ完了後に検証をしたところ、一部のサービスが正しく動いていないことがわかりました。

原因

アプリケーションのログから、MySQLにで対象のデータベースが参照出来ていないことがわかりました。
MySQLの権限を確認したところ、特定のユーザの特定の権限のみが意図しない形で変わっていました。
権限のイメージとしては以下のような形です。

バージョンアップ前の権限: データベース xxx_api
バージョンアップ後の権限: データベース xxx\_api

アンダーバーがエスケープされたままで権限付与されていたために、対象のデータベースが見れなくなっていました。

対策方法

権限付与のSQLを実行して、ユーザの権限を基に戻しました。
色々試したので確かではありませんが、おそらく以下のようなSQLを実行しています。

REVOKE ALL PRIVILEGES ON  `xxx\_api-prod`.* FROM 'xxx_api'@'%';

※ テスト環境では構成が異なるため、検証しようのない部分だったのが原因でした。

スナップショットからインスタンスを起動したら、データがほとんど入っていないインスタンスが作成される

MySQL 5.6 → 5.7 → 8.0のバージョンアップの時に発生しました。
まずMySQL 5.6 → 5.7をインプレースで行い、スナップショットを取得した後にMySQL 8.0のクラスターを作成しました。

発生した現象

MySQL 8.0のクラスターが起動したので、利用しようとしたところ、あるはずのデータベースがそもそも存在していませんでした。

対策方法

AWSに問い合わせしたのですが、対象のクラスターを既に削除していたため、明確な回答を得ることが出来ませんでした。
勝手な予想ですが、クラスターが利用可能になった後にも、バージョンアップの処理等は継続しているように見えます。
そのため、完了した後も少し待ってからスナップショットを取得するのが確実な気がします。
インプレースでMySQL 5.7にした後に、中身がちゃんと入っていることを確認してからスナップショットを取得することで対応しました。

最後に

まだパブリックベータ版ではありますが、RDSのBlue/Greenでデプロイメントが発表されています。
https://www.publickey1.jp/blog/22/amazon_rds_bluegreen_deployments.html

試したことはないのですが、現状のインスタンスが動作したままバージョンアップができるのは今までのエラーを回避できる手段ではないかと考えており、とても期待しています。
利用できるバージョン等、いくつかの制限はありますが、失敗したとしても前のインスタンスは残り続けることができると思うので、安全に停止時間を短くすることができる画期的なサービスではないかと思います。

Auroraのバージョンアップを検討している時には是非、利用を検討してみてください。

Team Deltaについて

DELTAでは、RDBやミドルウェアのバージョンアップ等、スタートアップの困りごと全般について、幅広く対応しています。
RDBやミドルウェアの作業ノウハウを活かしたい方や、色々なスタートアップの内側を見てみたい方は、ぜひ、 こちらまでお問い合わせください!

脚注
  1. バージョンによってはインプレースでの変更のが提供されておらず、その場合に利用します ↩︎

Discussion