AWS RDS(Aurora MySQL)のスロークエリログをpt-query-digestで解析する

✨目的や背景

MySQLのパフォーマンスチューニングをする際に、pt-query-digestでスロークエリログ(以下、スローログとする。)を分析をするのはわりと一般的だと思います。

pt-query-digestを使用するには生のスローログファイルが必要ですが、AWS RDSのスローログは、CloudWatch Logsに出力されます。 ※スローログの出力先として、CloudWatch Logsの他にMySQLのテーブルに書き込む方法もありますが、あまり使っている人はいないと思うので割愛します。

そのため、CloudWatch Logsのスローログを、生のスローログファイルとしてローカルに持ってきたいです。いろいろ試したのですが、一番楽にできた方法をメモしておきます。

🏗アーキテクチャ

スローログファイルの準備

CloudWatch Logs Insightを使用します!

スローログを出力している「ロググループ」と「分析したい期間」を指定して以下の単純なクエリを実行します。

fields @message
| sort @timestamp desc
| limit 1000

※リミットは念のためつけてます。無くてもよいです。

クエリ結果をJSON形式でエクスポートして、自分のPCにダウンロードします。

あとはローカルで、jqコマンドを使って生ログの形式に整形します。

cat logs-insights-results.json | jq -r '.[]."@message"' -r > slow.log

pt-query-digestで解析

これでスローログの生ログファイルができたので、あとは普通にpt-query-digestで解析するだけです。

# 普通に解析する場合
pt-query-digest slow.log

# 合計実行時間でソート(私がよく使うオプションです)
pt-query-digest --order-by Query_time:sum slow.log

🤔 検討した別の方法(またなぜその方法にしなかったのか?)

AWS CLI方式

AWS CLIaws logs get-log-eventsを使っても、スローログをローカルに持ってくることができます。ただこのコマンドには「応答サイズ1MBに収まる最大ログイベント数で、最大10,000ログイベント」という上限があり、今回対象のRDSのスローログは、結構な量があったためこの上限に引っかかってしまいました。 応答に含まれるトークンを使用すれば残りのログを取得できるのですが、ちょっと面倒になったのでAWS CLI方式は見送りました。 またaws logs get-log-eventsはログストリーム1つしか指定できないので、ログストリームが複数ある場合は意識する必要がありそれもデメリットです。

📝 まとめ

最初はAWS CLI方式でスクリプトを作ろうと思っていたのですが、単発実行であればCloudWatch Logs Insightを使ったほうが楽だな〜と思いました。 頻繁にやる作業ではないのですが、必要になるときはそれなりにあると思うので、参考にしていただければと思います。