こんにちは!エンジニアの福間(fkm_y)です。 先日、弊社でデータベースの技術顧問をして頂いてる三谷(mita2)さんに開発部向けのMySQLロックのデータベース勉強会を実施したのでそのレポートをお伝えします。
開催背景
弊社では三谷さんによるデータベース勉強会を定期的に開催しています。以前にもロックに関するMySQL勉強会を開催していたのですが、1年半経過しており参加していない開発メンバーのほうが多くなっていたことやプロダクトの成長によりデッドロックなどのロックに起因する問題が目立ち始めていたことから増強版のMySQLロックのデータベース勉強会を開催することになりました。
概要
- データベースのロックについて
- ロックタイムアウトについて
- デッドロックについて
- まとめ
データベースのロックについて
なぜデータベースにロック機構があるのかから知ることが重要です。性能と安全性を両立するためにあるということから丁寧に解説していただきました。
レコードロックというと「条件に合致した行」のみがロックされると勘違いされがちですが、「スキャンしたインデックス」に対してロックすることを覚えておくことが重要です。そのためロック範囲は実行計画に依存するためクエリチューニングを適切に行うことも重要です。
ロックタイムアウトについて
ロックタイムアウトは、先行するトランザクションが保持しているロックの解放の待ち時間がinnodb_lock_wait_timeout
パラメータの値を超え、タイムアウトすることによって発生するエラーです。
デッドロックは即時にエラーとなりますがタイムアウトは待ち時間を用してからエラーとなるため、ユーザー体験はデッドロックより損ねてしまいます。
ロックタイムアウトの原因はinnodb_lock_wait_timeout
を超えるトランザクションが存在することであるため、基本的にはパフォーマンス問題になります。そのためどこでパフォーマンスが遅くなっているか調査して対応する必要があります。
ANDPADでは Bugsnag、Datadog APM、CloudWatch Logs を導入しており、それらを利用したロックタイムアウトの調査方法について解説していただきました。
- ロック待ちになったトランザクションを調べるため、Bugsnagでエラーの発生時間、エラーが発生したソースコード、テーブルを確認した後、Datadog で実際のクエリを確認します。
- ロックしていたトランザクションを調べるため、Datadog APM を利用してエラー発生時間前後の処理を確認します。その後、生クエリを確認するため CloudWatch Logs を確認します。
※一部非公開ですが、後述のスライドで詳細が説明されています。
デッドロックについて
デッドロックは同じリソースのロックを互いに取り合っている状態でデータベースの不具合ではありません。
こちらもANDPADに導入している Bugsnag、Datadog APM、CloudWatch Logs を利用したデッドロックの調査方法について解説していただきました。
- Bugsnagでデッドロックエラーの発生時間、エラーが発生したソースコード、テーブルを確認する。
- CloudWatch Logs で該当時間周辺のDBのエラーログを取得する。
- Bugsnag の情報とDBのエラーログから原因を推測して特定します。
特にデッドロックが発生した原因を特定するためにCloudWatch Logs で取得した DBのエラーログをどのように三谷さんが読んでいるかを図解で丁寧に解説していただき、エラーログのどこが重要なポイントでどの順番で読んでいくと良いのかはとても勉強になりました。
※一部非公開ですが後述のスライドで詳細が説明されています。
デッドロックの対処方法についても解説いただきました。 トランザクションを再実行する処理を追加できれば手軽で良いですが、トランザクションの途中でリトライする処理の場合は実装が難しいと思うのでその場合はロック時間を短くするアプローチやロックの取り合いを防ぐため更新する順序を揃える方法があります。
トランザクションを小さくしてロック時間を短くする際には整合性を損なわないように注意が必要です。
まとめ
いずれも丁寧な解説だったのですが、特にデッドロック調査のためのエラーログの読み方はとても参考になり良かったと思います。
勉強会前はロックタイムアウトとデッドロックを混同していそうな人もいましたがこの勉強会で別物であることを認知してもらえたような気がします。DBのロックに関するエラーが発生した場合の調査方法が整理され特定の開発者だけが調査出来る状態を脱せることが出来そうに思いました。
当日の資料
勉強会で使用された三谷さんのスライドはこちらになります。
なおスライド内のエンドポイントや社内ドキュメントのリンクは社外向けにマスキングや置換をしています。
さいごに
ブログの他記事でも掲載されているように、アンドパッドではデータベース勉強会に限らず社内社外問わず勉強会を開催しています!プロダクトを成長させつつ是非私たちと一緒に研鑽を積み重ねましょう!
「取り敢えず話だけでも聞いてみたい!」人向けのカジュアル面談の制度もありますので是非話だけでも聞きに来てみてください。