エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

データベース移行でやらかした話

はじめに

こんにちは。エムスリー エンジニアリンググループの高島(id:rst76)です。

この記事はエムスリー SRE がお届けするブログリレーの 12 日目です。 ブログリレーに何を書こうかと悩んでいたのですが、つい先日、データベースを移行する際に障害を起こしてしまったので、その話をしたいと思います。 人の失敗談は面白い学ぶところが多いので…

何が起きたか

エムスリーでは多くのオンプレミスのサービスをクラウドに移行しているところで、今回移行したのはメールマガジン配信サービスのデータベースです。 複数のサービスが同居するオンプレミスの共用データベースから分離して、 AWS の Aurora PostgreSQL へ移行することになりました。 夜中にメールマガジンを配信することはないので夜のうちに作業を進め、移行そのものは無事に完了しました。 ところが翌朝に稼働状況を監視していたところ、最初のうちは問題なく動作していたのですが、配信が増えるにつれて配信処理に遅れが生じるようになりました。

その1:サイジング誤り?

データベースのメトリクスを確認すると、CPU 使用率が 100% に貼りついていました。 最初に疑ったのは、サイジングの誤りによるデータベースインスタンスの処理能力不足です。 移行元データベースのアクセスをもとに移行先データベースのサイズを見積もっていたものの、特に CPU 使用率はそこまで詳細に確認していなかったので、見積もりを誤っていた可能性があると考えました。 そこで Aurora のインスタンスサイズを変更して、処理性能を 2 倍に増やすことにしました。

過去の利用状況から 2 倍もあれば十分だろうと考えたのですが、後から振り返るとこれは中途半端な対応でした。 別の原因があるかもしれず、これで問題が解決する保証はありません。 いったん 4 倍あるいは 8 倍に増やした方がよかったと思います。 実際、これにより配信速度は若干改善されたものの、配信が増えると、また CPU 使用率は 100% に貼りつくようになってしまいました。

その2:不適切な SQL ?

ここでさらにインスタンスサイズを増やすという選択肢もありましたが、そこまでの性能が必要だということは考えづらかったので、別の原因を疑い始めました。 実行されている SQL を確認すると、最近の機能追加による特定の SQL が処理時間の多くを占めていることが分かりました。 さらに実行計画を確認すると、フルスキャンが発生しており、これが性能を大きく劣化させていると推測できました。 そこで、当該 SQL が利用できるようなインデックスを付与したところ、CPU 使用率は大きく下がり、配信の遅れも無事に解消されました。

以下の図は CPU 使用率の推移です。青色で表された最初のインスタンスの CPU 使用率が 100% に達した後、より大きな橙色のインスタンスに変更したものの、そちらも 100% に達したこと、インデックス付与後に改善されていることが確認できます。

f:id:rst76:20210124204754p:plain
CPU 使用率の推移

その3:ANALYZE 漏れ!

さて、1 つの SQL がこれだけ性能を劣化させていたのですから、移行元のデータベースでも悪影響はあったはずです。 ところが過去のメトリクスを確認しても、その SQL による悪影響は見られませんでした。 移行元データベースは前述の通り共用なのでスペックの高いハードウェアで稼働していますが、それでも複数の CPU を占有するくらいの負荷であれば、それと分かるはずです。 ここで問題となった SQL の実行計画を移行元データベースで確認すると、なんと、移行先データベースとは異なる、フルスキャンの発生しない実行計画となっていました。

改めて確認すると、そもそも移行先のデータベースでは統計情報が取得されていないことが発覚したのでした。 今回の移行はダンプ&リストアで実施したのですが、リストアの際に ANALYZE の取得が漏れており、更新が少ないテーブルなので自動取得もされなかったのです。

なおリストアの際の ANALYZE は、 PostgreSQL のドキュメント でも推奨されています。忘れずに実行することをお勧めします。

おわりに

という訳で、そもそもの原因は ANALYZE の実行漏れだと分かりました。移行時に統計情報を取得しておけば問題は生じなかったと思います。 とはいえデータベースの移行や運用をする上では、今回の原因に限らず、このような性能問題が生じることはあるのではないでしょうか。

そのような場合に備えるという意味では、あらかじめ余裕のあるインスタンスを用意しておき、利用状況に応じてダウンサイジングするというのがよさそうです(実際にそういった方針で移行を進めたチームもあります)。 また、今回の障害を受けてポストモーテムは実施しましたが、たとえばプレモーテムなども実施していれば、問題の可能性に気づくことができたかもしれません。

個人的には反省点も多く手痛い失敗でしたが、こうした事例共有も通じて、チームとしての成熟度を高めていきたいと考えています。

We're Hiring!

エムスリーでは、サービスの信頼性を少しでも高められるように様々な対応を進めており、一緒に推進するメンバーが一人でも多く必要です。 今回の話を聞いて、もっといい方法があると思われた方も、一緒に悩んでいこうという方も、ぜひ応募してください!

open.talentio.com

jobs.m3.com