LoginSignup
7
5

More than 1 year has passed since last update.

DB 高負荷時に数秒でサクッと原因を特定する (aws RDS)

Last updated at Posted at 2019-12-05

概要

なんかよくわからないけど DB の負荷が高くなったどー
という監視アラートが出たとき、あなたはどうしますか?

そういうときに何が原因で負荷が高くなっているかサクッと追いたいですね。
CPU の状態や、スワップの状態、コネクション数から調べることもできますが、これだけでは何が原因で重くなったのかはっきりしないことは多いです。

対象読者

  • aws が何なのか知っている人、運用している人 (aws は食べ物ではない)
  • RDS で DB 管理していること
  • スロークエリログを cloudwatch もしくは DB に保存できる環境であること

準備

DB 側

数秒でサクッと原因を特定できるようにするためには、事前に準備が必要です

まずは RDS のパラメータグループで以下の設定を変更してください (デフォルトのパラメータグループでは変更できないようです)

  • slow_query_log: 1
  • long_query_time: 0.1 ~ (単位 秒)
  • log_output: FILE (TABLE でもよいですが、その場合の方法は今回は割愛)

次に、RDS 自体の設定で [Modify] を設定し、[Slow query log] にチェックをいれます

そうすることで RDS の Configuration に Slow query という cloudwatch へのリンクができます。

スクリーンショット 2019-12-05 9.06.35.png

リンク先を開くと、キャプチャの ① が log-group-name で ② が log-stream-name です。メモしておきましょう。

スクリーンショット 2019-12-05 9.08.28.png

集計側 (local など)

セットアップ

mac の場合 homebrew 導入済みの前提で記載しますと、以下のように percona-toolkit を導入します

$ brew install percona-toolkit

jq コマンドも導入しておきます

$ brew install jq

mac の場合は、以下のように aws-cli を導入します

$ brew install awscli
$ aws configure // aws の設定を行う

スクリプト配置

ということで、 slow-query-summary.sh というスクリプトで中身を以下のようにします
pt-query-digest のオプションを指定すれば、explain も出したり、余計なクエリをフィルタしたりできますが、ここでは割愛します

LOG_GROUP には先程メモした log-group-name を、 LOG_STREAM には先程メモした log-stream-name をいれます

mac - FreeBSD系

#!/bin/bash -u

LOG_GROUP=hogehoge
LOG_STREAM=fugafuga

SCRIPT_NAME=`basename $0`
if [ $# -ne 2 ]; then
  echo "指定された引数は$#個です。" 1>&2
  echo "実行するには2個の引数が必要です。" 1>&2
  echo "Usage: $SCRIPT_NAME "\""2019-12-01 12:00:00"\"" "\""2019-12-01 13:00:00"\" 1>&2
  exit 1
fi

start="$1"
end="$2"

echo start datetime iso-8601..
echo $(TZ=JST-9 date -jf "%Y-%m-%d %H:%M:%S" "$start" +%s);
echo end datetime iso-8601..
echo $(TZ=JST-9 date -jf "%Y-%m-%d %H:%M:%S" "$end" +%s);

starttime=$(expr `TZ=JST-9 date -jf "%Y-%m-%d %H:%M:%S" "$start" +%s` \* 1000)
endtime=$(expr `TZ=JST-9 date -jf "%Y-%m-%d %H:%M:%S" "$end" +%s` \* 1000)

aws --profile prod logs get-log-events \
  --log-group-name ${LOG_GROUP} \
  --log-stream-name ${LOG_STREAM} \
  --start-time ${starttime} \
  --end-time ${endtime} \
  --query 'events[].message' \
  |jq -r '.[]' \
  | pt-query-digest --limit 10000

gnu 系

#!/bin/bash -u

LOG_GROUP=hogehoge
LOG_STREAM=fugafuga

SCRIPT_NAME=`basename $0`
if [ $# -ne 2 ]; then
  echo "指定された引数は$#個です。" 1>&2
  echo "実行するには2個の引数が必要です。" 1>&2
  echo "Usage: $SCRIPT_NAME "\""2019-12-01 12:00:00"\"" "\""2019-12-01 13:00:00"\" 1>&2
  exit 1
fi

start="$1"
end="$2"

echo start datetime iso-8601..
echo $(TZ=JST-9 date --iso-8601="seconds" --date "$start");
echo end datetime iso-8601..
echo $(TZ=JST-9 date --iso-8601="seconds" --date "$end");

starttime=$(expr `TZ=JST-9 date --date "$start" +%s` \* 1000)
endtime=$(expr `TZ=JST-9 date --date "$end" +%s` \* 1000)

aws --profile prod logs get-log-events \
  --log-group-name ${LOG_GROUP} \
  --log-stream-name ${LOG_STREAM} \
  --start-time ${starttime} \
  --end-time ${endtime} \
  --query 'events[].message' \
  |jq -r '.[]' \
  | pt-query-digest --limit 10000

最後に実行権限をつけます

$ chmod +x ./slow-query-summary.sh

重くなったなというときに、以下のようにスクリプトを実行すれば、簡単にスロークエリログのサマリが表示されるようになります。

./slow-query-summary.sh  "2019-12-01 12:00:00" "2019-12-01 13:00:00"

※キャプチャはサマリの部分だけですが、実際のスロークエリログもでてきます

スクリーンショット 2019-12-05 9.20.46.png

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5