Aurora MySQLの負荷は高騰していないのにエラーレートが悪化した原因がPerformance Schemaだった話

メディア統括本部 サービスリライアビリティグループ(SRG)の鬼海雄太(@fat47)です。
#SRG(Service Reliability Group)は、主に弊社メディアサービスのインフラ周りを横断的にサポートしており、既存サービスの改善や新規立ち上げ、OSS貢献などを行っているグループです。
本記事では、ある日起きたAurora MySQLの障害対応事例を紹介します。
 

ある日突然アプリケーションのエラーレート悪化アラートが発報


ある日突然、アプリケーションのエラーレートが悪化しアラートが発報されました。

初動調査

該当時間のAurora MySQLのRDSインスタンスのエラーログを確認すると、以下のようなログが残っていました。
Aurora MySQLがメモリ不足によるOOMの発生を回避するために、コネクションを切ったりクエリを拒否したりしていたようです。
メトリクスを確認してみると、ある日を境にFreeableMemoryが右肩下がりになっていることがわかりました。
 
時間差でSwapUsageも上がっています。
 
他にDB負荷に関連するメトリクスに変化がないか確認してみます。CPU使用率は1ヶ月のスパンで見ても大きな変化はなさそうです。
 
Database Insightで直近1週間の平均アクティブセッション(AAS)を見ても、悪化はしてなさそうです。スロークエリログも発生していませんでした。
 
クエリー数の傾向にも変化もなさそうです。
コネクション数の傾向にも変化はありません。
 
FreeableMemoryが右肩下がりをした日にアプリケーションの新機能リリースがあり、それが関係していそう。ということはわかりました。
しかし、メモリ逼迫以外のメトリクスが上昇しておらずどうしたものかと思っていました。

一件のブログ記事を見つける


アンドパッドさんのこちらの記事でPerformance Schemaが原因でFreeableMemoryが低下するという事象が紹介されていました。
 
記事内の事例ではAurora MySQL 3.04(MySQL8.0.28)から3.10(MySQL8.0.42)にアップグレードによって、特定インスタンスのデフォルト挙動が変わったことが原因でした。
今回私が見ていた環境はAurora MySQL 3.04でしたので、この記事とまったく同じ事象ではないのですが、要因としてPerformance Schemaが怪しいということで調査しました。

Performance Schemaを調査


Performance Schemaの全体のメモリ使用量を確認したところ、約5.2GB消費していることがわかりました。
Currentの値と最大使用量の値が一致しており、いまだ消費が伸び続けていることがわかります。
 
消費メモリの内訳の上位を確認してみると、host/account別サマリが支配的ということがわかりました。
 
host/accountの件数をカウントしてみると、約16000件ずつあることがわかりました。
 
accoutsの中を見てみると、ユニークな接続元HOSTが大量に並んでおり、異なるIPアドレスで記録されていることがわかりました。

根本原因


Freeable Memoryが下がりはじめた日のアプリケーションリリースで、Kubernates CronJobによる毎分実行のバッチ処理が追加されていたことが判明しました。
これによって短命のPodが毎回新しいPod IPでDBへ接続され、 / が累積で増え続けて、
それぞれのサマリも増殖し、Performance Schemaのメモリ消費が肥大化していました。
 
その結果、Freeable Memoryが減り続け、Swap Usageも増加し最終的にAurora側のOOM回避挙動が出たため、クエリのKillが発生しアプリケーションのレイテンシ悪化につながりました。
 

一次対応


Aurora MySQLのパラメータグループの以下のパラメータを変更しました。
パラメータ名デフォルト値変更後の値
0 ( 自動管理 )1 (手動管理 )
-1 ( 無制限 )100
-1 ( 無制限 )100
Performance Schema関連のパラメータを変更するため、performance_schemaを手動管理に変更して、 それぞれに上限値を設定しました。
この2つはデフォルトでは無制限のため、今回のように累積し続けることになってしまいました。
なお、これらのパラメータの変更の適用にはRDSインスタンスの再起動が必要な点には注意が必要です。
 
この対応によって、FreeableMemoryの右肩下がりの状況と、SwapUsageの発生を解消することができました。
 の2つに上限を設定した場合のデメリットとして、パフォーマンスインサイトのホスト別集計で上限を超えた場合に、ホスト別情報が欠落してしまう点があります。

おわりに


システムアラートが鳴ったのにDBの負荷系指標が平和な場合、Performance Schemaの肥大化も疑ったほうがよいという事例を紹介しました。
今回は2つのperformance_schema関連のパラメータに上限値を設定して問題を解消しました。
他にも、アプリケーションとAurora MySQLの間にRDS Proxyを挟んで接続元HOSTを安定させるという手段も考えられます。
 
SRGにご興味ありましたらぜひこちらからご連絡ください。