こんにちは。技術部プラットフォームグループのyuchiです。
2024年2月末にカラーミーショップのマスターデータベースをMySQL 5.7.44から8.0.35へアップグレードを行い、無事にアップグレード作業が終了したため、実際にどのようなことをやっていたのかを記した記事です。
また、メンテナンスを行うにあたり、ご理解ご協力いただいたショップオーナー様には感謝申し上げます。
このMySQL8.0アップグレードプロジェクトは開始から約4ヶ月で完了しました。途中1ヶ月は別のプロジェクトで中断があったため、実働は約3ヶ月のプロジェクトでした。
この記事では以下の要点に絞って書いています。
- Amazon RDS+プライベートクラウドのマルチクラウド構成でのMySQLアップグレードを行った話
この記事で話さないこと
- MySQL8の変更に関する詳細な話
- アプリケーションの修正の話
カラーミーショップとは
カラーミーショップとはネットショップ作成サービスで、2005年にサービスを開始をして今年で19年目のサービスになります。
ご利用いただいているショップさんは約45000店舗、カラーミーショップで発生する流通額は年間約2070億円です。(どちらも2021年末時点)
アップグレードの背景
カラーミーショップのマスターDBはAmazon RDS for MySQLを使用しており、MySQLバージョン5.7の標準サポートは2024年2月29日まででした。
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/MySQL.Concepts.VersionMgmt.html
2024年3月1日以降にAmazon RDS for MySQLでMySQL 5.7を使用すると自動延長サポート対象となり、2年目まではvCPUあたり0.120USD/時(東京リージョン)が追加で請求されます。
例としてvCPUが16のインスタンスを使用していた場合は以下の計算となり、MySQL5.7が稼働するRDSの台数やvCPU数によっては月に数十万円規模の追加コストがかかってしまいます。
0.12(USD) × 16(vCPU) = 1.92USD/h
1.92USD × 720(時間) × 150(円) = 207,360円/月
カラーミーショップの使用しているRDSの規模ではかなりの追加コストとなってしまうために、標準サポート期限内のMySQL8.0へのアップグレード作業は必須でした。
カラーミーショップDB構成
カラーミーショップでは、OpenStackを利用したプライベートクラウド「Nyah」があり、その上にアプリケーションを動作させるVMやKubernetes Nodeを構築しています。これによってパブリッククラウドよりも運用コストを大幅に抑えることができています。
一方で、データベースなど高い信頼性やパフォーマンスを求められる箇所はAWSなどのパブリッククラウドを使用することで高い可用性を確保できるハイブリッドクラウド構成でサービスを提供しています。 AWSとプライベートクラウドNyahはAWS Direct Connect(以下 DX)を使用して接続をしています。
カラーミーショップのマスターDBはAmazon RDS(以下 RDS)にあり、RDSのリードレプリカが4台とプライベートクラウドNyah上に構築しているDB(以下 NyahDB) 3台の合計7台の構成となっています。 (アプリケーションからDBへのReadのみを表した図です。書き込みはすべてMasterへ行っています。)
RDSはTerraform、NyahDBはPuppetで構成管理を行っています。
構成図を見ていただくとアプリケーションから参照されるリクエストはNyahDBへ向いていることが分かるかと思います。
これはDXを使用してRDSからプライベートクラウドNyahへのクエリ結果に対する通信で料金が発生するため、それを最小限に抑えるために平常時はアプリケーションからのReadクエリに関しては基本プライベートクラウドのネットワーク内で完結するようにしています。
障害などでNyahDBが使用できなくなった場合に備えて、RDS側に予備DBも用意をしています。
アップグレード準備
問題点の洗い出し
まずはMySQL公式のリリースノートを読み込みましょう。変更差分やアップグレードで注意するべき箇所がすべて掲載されています。
MySQL :: MySQL 8.0 Release Notes
しかし、変更箇所が膨大で1個ずつ現状の構成と比べて確認していると時間がかかってしまうため、今回はMySQL ShellにあるUpgrade Checker Utility
を使用して今のDBをMySQL8.0にした際に発生する問題をチェックしました。
MySQL :: MySQL Shell 8.0 :: 11.1 Upgrade Checker Utility
mysql > util.checkForServerUpgrade()
The MySQL server at /var%2Flib%2Fmysql%2Fmysql.sock, version 5.7.44-log - MySQL
Community Server (GPL), will now be checked for compatibility issues for
upgrade to MySQL 8.0.36...
1) Usage of old temporal type
No issues found
2) MySQL 8.0 syntax check for routine-like objects
No issues found
3) Usage of db objects with names conflicting with new reserved keywords
Warning: The following objects have names that conflict with new reserved
keywords. Ensure queries sent by your applications use `quotes` when
referring to them or they will result in errors.
More information:
https://dev.mysql.com/doc/refman/en/keywords.html
xxxxxxx.xxxxxx(テーブル名) - Column name
(省略)
29) Check for columns that have foreign keys pointing to tables from a diffrent
database engine.
No issues found
Errors: 0
Warnings: xx
Notices: 0
NOTE: No fatal errors were found that would prevent an upgrade, but some potential issues were detected. Please ensure that the reported issues are not significant before upgrading.
このチェックでエラーは確認されませんでしたが、Warningはいくつかありました。そのため、その箇所を中心に確認を行い、問題がありそうであれば修正を行いました。
リードレプリカDBアップグレード
レプリカDBのアップグレードは営業日中に1日1台ペースで合計7台行いました。 アプリケーションからはProxySQLを介してDBに接続しているため、予備のDBに接続先を切り替えてサービス提供に影響が無いように進めました。
NyahDB-1
をアップグレード中はRDSのreplica2
とNyahDB-2でリクエストを処理している図になります。
RDSはTerraform、NyahDBはPuppetで構成管理ツールが異なるため、それぞれで5.7と8.0が同時に稼働できるように記述する必要がありました。
予備DBからアップグレードを始め、アップグレード後は本番アプリケーションから少量のリクエストを流し、問題が発生していないかなどを確認しました。
プライマリDBのアップグレード手法
今回のプライマリDBのアップグレード方法はインプレースアップグレードで作業を行いました。
プライマリDBはRDSを使用しているため、Blue/Greenデプロイ(以下 B/Gデプロイ)を使用することでサービス停止時間を最小化できますが、今回はコストと技術的理由でインプレースアップグレードを選択しました。
Amazon RDS ブルー/グリーンデプロイの概要 - Amazon Relational Database Service
まずはコスト面です。
DBをハイブリッドクラウドで運用していることは先述しましたが、B/Gデプロイを行った際にRDS→NyahDBのレプリケーションが正しく動作し続けるかが不明なため、一時的にNyahDBのレプリケーションを止め、RDSのみでアプリケーションのリクエストを処理する期間が必要となります。
それに加え、プライマリDBと同等のスペックのDBインスタンスを準備のために最低数日運用する必要があり、Green環境を1週間程度運用するとカラーミーショップでは数十万円のコスト増となる計算となりました。
次に技術的面です。
今までカラーミーショップのDBのアップグレードメンテナンスはインプレースでのアップグレードを行ってきた経緯があり、手順や知見がチーム内で確立していることが大きいです。
また、5.7→8.0というメジャーバージョンが変更になる大規模なアップグレードで、今まで行ったことのないアップグレード手法を取るリスクなどがありました。
デメリットとしては、主に作業量が多くメンテナンス時間がB/Gデプロイを比べて2~3時間伸びるなどありますが、インプレースアップグレードが適切だろうという判断になりました。
アップグレード作業
サービス停止の予定時間は午前0時~午前6時だったため、30分ほど前にインフラチームとアプリケーションチームのエンジニアが集まり、メンテナンス準備を行いました。
0時になったタイミングで全てのサービスを停止し、メンテナンス画面に切り替わったこと、ログを確認してアクセスが来てないことを確認し作業を開始しました。
作業自体はRDSのリードレプリカDBとほぼ同じ手順な上、事前に作成した手順書もありスムーズに行うことができました。
プライマリDBのみマルチAZ構成のため、アップグレードに時間が多少かかりましたが、1時間程度でアップグレードは完了しました。
アップグレード直後はInnoDBのBufferPoolが空になってしまうため、全テーブルをSELECTするいわゆる暖機を行います。キャッシュをメモリに乗せることでパフォーマンスの向上やスロークエリ防止などのために必要な作業です。
サービス再開
必要な作業とメンテ明け前の開発環境での確認を終えたらサービスを再開します。実際にテスト購入や、アプリケーションのアクセスログ、データベースのエラーログ、監視ツールを確認し、問題が起こっていないことを確認していました。
私は動作確認とメンテ完了記念を兼ねてVERTEREのクラフトビールを買いました。美味しいクラフトビールなのでおすすめです。
アップグレード後に出た問題点
mysql_native_password
の認証プラグインが非推奨になったことにより、接続毎にWARNINGログが出る
リードレプリカDBのアップグレード後、RDSとNyahDBどちらも以下のログが途切れなく出るようになってしまいました。
[Warning] [MY-013360] [Server] Plugin mysql_native_password reported: ''mysql_native_password' is deprecated and will be removed in a future release. Please use caching_sha2_password instead'
MySQL8.0からデフォルトの認証プラグインがcaching_sha2_password
となりましたが、MySQL 8.0.34のバージョンアップからmysql_native_password
の認証プラグインが非推奨になったことによりWARNINGのログが出るようになったようです。
The mysql_native_password authentication plugin now is deprecated and subject to removal in a future version of MySQL. CREATE USER, ALTER USER, and SET PASSWORD operations now insert a deprecation warning into the server error log if an account attempts to authenticate using mysql_native_password as an authentication method. (Bug #35336317)
MySQL :: MySQL 8.0 Release Notes :: Changes in MySQL 8.0.34 (2023-07-18, General Availability)
NyahDBではエラーログのフィルタリングを実施することで抑制をおこないました。
my.cnfに以下の設定を追記し、mysqldを再起動させることで上記のログの抑制が適用されました。 リードレプリカDBはサービス停止メンテナンス中に再起動を行いました。
[mysqld]
log_error_suppression_list = MY-013360
RDSに関してはlog_error_suppression_list
のパラメータを設定することができないため、現状そのままとなっています。
解決策としては使用するユーザー認証プラグインをcaching_sha2_password
にすることですが、アプリケーションを含めた修正も含まれることと、急ぎ対応が必要ではないため、次回のアップグレードまでに対応を行う方針となりました。
また、ProxySQLも2024年3月4日にリリースされたProxySQL 2.6.0でcaching_sha2_password
がサポートされたようです。
Added support for caching_sha2_password
https://proxysql.com/blog/releasing-proxysql-v2-6-0/
アップグレード後の変更点
レイテンシの改善
Primaryのアップグレード後、カラーミーショップのショップページのレイテンシが(若干ですが)早くなりました。
MySQL8.0は5.7よりも最大2倍高速になったとのことなので、これの恩恵を受けたものと思われます。
https://www.mysql.com/jp/products/enterprise/database/
アップグレードのみでレイテンシが早くなったのはSREとしては嬉しい結果となりました。
Gravitonインスタンス
MySQL 8.0.28以降であれば、Graviton3インスタンスを使用することができます。 DB インスタンスクラス - Amazon Relational Database Service
Gravitonインスタンスの詳細については割愛しますが、armベースのサーバーで、性能はそのままコストダウンすることができる可能性があるRDSインスタンスです。
現在使用しているリザーブドインスタンスの期限までに準備をし、更新期限でGravitonインスタンスへ切り替えが行えるように進めています。
感想
アップグレード後に大きな障害などはなく概ね無事に期日までのアップグレードを行うことができました。
作業することとしては準備が99%、メンテナンス日に残り1%とコンソールの変更ボタンを押す勇気だなと思いました。
22年4月に新卒入社し、技術部プラットフォームグループに配属してからこの規模のプロジェクトは初めての経験でした。割り込みなど当初想定していたスケジュール通りにいかないことが多々あり、改めて計画性や予備日程の重要性を感じることができました。
この記事が面白かったと思っていただけたのであれば、アップグレードプロジェクトを一緒に進めてもらった同じチームのgurasanがYAPC::Hiroshima 2024で発表した入門EOL対応のスライドもぜひ合わせて読んでいただければと思います。
YAPC::Hiroshima 2024で登壇してきました - Pepabo Tech Portal
以上カラーミーショップで使用しているデータベースのMySQL8.0へのアップグレード記録でした。 外部公開ができない情報も多く、曖昧な表現になっている箇所もございますが、パブリッククラウド+プライベートクラウドのハイブリッドクラウド環境で運用しているMySQLメジャーアップデートを行った内容としてご参考になれば幸いです。