RDS B/G Deployments機能でAuroraクラスターバージョンアップした後の切り戻しを考える

メディア統括本部 サービスリライアビリティグループ(SRG)の鬼海 雄太(@fat47)です。
#SRG(Service Reliability Group)は、主に弊社メディアサービスのインフラ周りを横断的にサポートしており、既存サービスの改善や新規立ち上げ、OSS貢献などを行っているグループです。
本記事は、RDS Blue/Green DeplymentsをつかってAuroraのバージョンアップをおこなった際に、なんとか切り戻しを行えないかを検証しています。
なにかの役に立てば幸いです。
 
 

最初にまとめ


  • Blue/Green Deploymentsでバージョンアップしてもなんとか切り戻せる方法はある
    • 今回の検証では3パターン中2つはうまく切り戻せた
  • どの切り戻し方法にせよDBの書き込みを停止するサービスメンテナンスは必須
  • バージョン切り戻しより新バージョンで対応できるよう修正したほうが現実的

Blue/Green Deploymentsによるバージョンアップ


クラスタのコピーを作成してそのクラスタとレプリケーションを貼り、ボタン一つでクラスタ切替ができるようになるマネージドな機能です。
詳しくはBlue/Green Deploymentsリリース当時の下記のブログをご参照ください。
 
この機能をつかって、稼働中のクラスタ(Aurora MySQL2系)からGreenクラスタ(Aurora MySQL3系)を作成し、切替をおこなうことでバージョンアップが可能になります。
 
しかし、この機能をつかってバージョンアップを行うと、あとになってクリティカルな事象が発覚した等の理由で元のAurora Version2戻したいとなっても対応することが困難です。
 
それでもなんとか切り戻せないかを検証しました。

切り戻しパターンを3つ検証


  • Green(MySQL8.0)からBlue(MySQL5.7)への逆方向のレプリケーションする方法
  • Green(MySQL8.0)から論理バックアップを取得して、Blue(MySQL5.7)に適用する方法
  • Green(MySQL8.0)の静止点から差分をbinlogから生成して、Blue(MySQL5.7)に適用する方法
 

検証用環境の作成


  • Auora Version2系のクラスタ作成
  • 検証用のテーブル作成とレコード追加
    • データーベース&テーブル作成
      • レコード追加
      • Blue/Green Deployments機能でGreen(MySQL8.0)クラスタの作成
      • Green(MySQL8.0)とBlue(MySQL5.7)のクラスタ両方でbinlog保持期間を7日まで伸ばしておく

        Green(MySQL8.0)からBlue(MySQL5.7)への逆方向のレプリケーションする方法


        概要

        B/Gの切替を実行しても、旧Blue(MySQL5.7)のクラスタは勝手に削除されません。
        旧Blue(MySQL5.7)を切り戻し環境として活用し、
        切替後のGreen(MySQL8.0)をソースとして手動でレプリケーションを貼る方法です。

        検証手順

        • サービスメンテナンスモードなどにしてDB書き込みを停止
        • B/G切替実行
        • B/Gロールの削除
        • Green(MySQL8.0)でポジション確認
          • Green(MySQL8.0)でレプリユーザーの作成
            • 旧Blue(MySQL5.7)でGreen(MySQL8.0)に向けてレプリケーションの開始
              • 旧blue(MySQL5.7)でレプリケーションの状態確認
                • Green(MySQL8.0)で動作確認用のレコード追加
                  • 旧blue(MySQL5.7)でレプリケーションの状態確認
                    • 旧blue(MySQL5.7)でレコードをみてレプリケーションが正常に行われていることを確認
                      • サービスメンテナンスモードを解除してDBの書き込みを再開

                      Green(MySQL8.0)から論理バックアップを取得して、Blue(MySQL5.7)に適用する方法


                      概要

                      Green(MySQL8.0)で論理バックアップを取得して、それを旧Blue(MySQL5.7)クラスタに入れ直す方法です。一番時間はかかるが確実な方法ではあります。

                      検証手順

                      • B/G切替実行
                      • B/Gロールの削除
                      • 切替後、Green(MySQL8.0)にレコード追加テスト
                      • サービスメンテナンスモードなどにしてDB書き込みを停止
                      • 旧Blue(MySQL5.7)でリストア
                        • 旧Blue(MySQL5.7)のレコード内容確認。Green(MySQL8.0)に追加した内容が含まれていることが確認できました。
                          • Green(MySQL8.0)のインスタンスやクラスタを削除
                          • 旧Blue(MySQL5.7)のインスタンスやクラスタをリネームして、の表記を消す
                          • サービスメンテナンスモード解除でサービス再開

                          Green(MySQL8.0)の静止点から差分をbinlogから生成して、Blue(MySQL5.7)に適用する方法


                          ⚠️
                          ↓↓ この方法は実現可能性が低いので注意が必要です ↓↓

                          概要

                          DB書き込みを止めたメンテナンス中にB/Gの切替を行い、切替後にGreen(MySQL8.0)側のbinlogポジションを確認しておきます。
                          切り戻し時にはそのポジションから最新のポジション分までの更新差分SQLファイルを生成し、それをBlue(MySQL5.7)クラスタに適用すれば切り戻しになるのでは。という方法ですが難しそうです

                          検証手順

                          • サービスメンテナンスモードなどでDB書き込みを停止
                          • B/G切替実行
                          • B/Gロールの削除
                          • Green(MySQL8.0)の現時点のポジション確認してメモる
                            • サービスメンテナンスが解除されたと想定していくつか更新クエリを実行
                              • 切り戻し実行のために再度サービスメンテナンスモードなどでDB書き込みを停止
                              • 書き込み停止後のGreenの現在のポジションを確認
                                • Greenのbinlogを取得(MySQL ClientがインストールされているOpe用サーバなどで操作)
                                  • 上記スクリプトでope用サーバの/tmpにbinlogファイルが出力されている
                                  • mysqlbinlogコマンドで復旧用のSQLファイルを生成する
                                    • 旧Blue(MySQL5.7)のテーブルの状態確認
                                      • もちろんINSERT3件は反映されていないのを確認
                                    • 旧Blue(MySQL5.7)にrecovery.sqlを流し込むとSUPER権限が必要というエラーが発生
                                      • エラー対象のrecovery.sqlの9行目はROWでの更新部分
                                        • mysqlbinlogコマンドで復旧用のSQLファイルを生成するときにしても、クエリ部分がコメントアウトされてしまうのでリストアされない。
                                          • 件数が少ない場合は、差分SQLの編集や置換でINSERTやUPDATEなどのコメントアウトを消せばいいが、本番環境での切り戻し利用には差分件数も多く、難しそう。
                                         

                                        余談

                                        • MySQL5.7のclientでAurora MySQL3系(MySQL8.0)のクラスタのbinlogを取得しようとするとエラーになります。
                                         
                                        • MySQL8.0のClientで取得してきた、Aurora MySQL3系(MySQL8.0)のクラスタのbinlogをつかって、MySQL5.7のclientのmysqlbinlogで無理やりSQL生成しようとしてもエラーになります。
                                         
                                        • Aurora Version2(MySQL5.7)へのリストア時にSUPER権限が求められたのは、今回の更新差分SQLファイルでは3箇所です。
                                         
                                        • Aurora Version3(MySQL8.0)ではSUPER権限が非推奨となり、それぞれ必要な権限が変更になっています。
                                          • コマンド必要な権限
                                            BINLOG 'xxxxxxxxxx';SUPER, BINLOG_ADMIN or REPLICATION_APPLIER
                                            SET @@SESSION.GTID_NEXT='AUTOMATIC'SUPER, SYSTEM_VARIABLES_ADMIN, SESSION_VARIABLES_ADMIN or REPLICATION_APPLIER
                                            SET @@session.pseudo_thread_id=xxxxx/SUPER, SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN
                                          • Aurora Version3(MySQL8.0)のマスターユーザーがもっているデータベースロール が含まれているため、今回の差分修正SQLはAurora Version3(MySQL8.0)では問題なくリストアできます。
                                         

                                        参考URL


                                        終わりに


                                        サービスをメンテナンスにいれてDB書き込みを停止させることができるのならば、なんとか切り戻せる方法があることがわかりました。
                                        サービス要件などにあわせて適切なアップグレードプランを提案していきたいですね。
                                         
                                        SRG では一緒に働く仲間を募集しています。 ご興味ありましたらぜひこちらからご連絡ください。
                                         
                                        このエントリーをはてなブックマークに追加