🐙

Cloud SQLでスロークエリを検知する

2024/03/25に公開

この記事でやること

Cloud SQL(MySQL)で稼働しているデータベースのスロークエリをオンにすることで処理に時間がかかるクエリを記録できるようにします。

具体的には以下の設定を行います。

  • Cloud SQLのスロークエリの設定
  • Cloud Loggingのログポリシーアラートの設定

スロークエリログを設定する

クエリログを有効にするを参考に、Terraformを利用してデータベースフラグを追加します。

main.tf
resource "google_sql_database_instance" "default" {
  ## 諸々データベースの基本的な設定は省略しています
  settings {
+    database_flags {
+      name  = "log_output"
+      value = "FILE"
+    }
+    database_flags {
+      name  = "slow_query_log"
+      value = "on"
+    }
  }
}

terraform applyに成功すると、Cloud SQLのコンソール画面でlog_outputslow_query_logフラグが設定されていることが確認できます。

なお、「スロークエリ」に該当するのはlong_query_timeを超えた場合です。デフォルトでは10秒が設定されています。(long_query_timeも同様にTerraformで設定可能です。)

試してみる

スロークエリを意図的に発生させるため、sleepを利用してロギングされるか確認します。

select sleep(11);

ログを確認すると、スロークエリが記録されていることがわかります。(一部マスクしてます)

# Time: 2024-03-01T01:50:55.879244Z
# User@Host: xxxx[xxxx] @  [xxxxxxxxxxx]  thread_id: 2146446  server_id: 1359838164
# Query_time: 11.001692  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 1
use database_main;
SET timestamp=1709257844;
select sleep(11);

スロークエリを検知する(Slack通知)

上記までではスロークエリがログに残るだけですので、素早く検知するためにSlackへの通知もできるようにします。
なお、Slack以外にもメール等への通知も可能です。(通知チャンネルの作成と管理

ログベースの指標に関するアラートを参考に設定します。
ログの条件には以下のように設定しました。

resource.type="cloudsql_database"
insertId=~".*slow.*"
insertIdについて

また、特定のユーザーグループへのメンションを含む本文を作成します。

slow queryが検知されました
<!subteam^S999ABCDEFG>

本文中でSlackのユーザーグループにメンションするには、少し特殊な書き方が必要なようです。(Mentioning groupsを参考)

上記までをTerraformで書くと以下のようになります。

Terraform
# ログベースのアラートポリシーの作成(スロークエリ)
resource "google_monitoring_alert_policy" "slow_query_alert_policy" {
  display_name          = "スロークエリ監視"
  notification_channels = [google_monitoring_notification_channel.slack_notify.name]
  combiner              = "OR"

  conditions {
    display_name = "slow_query_logs"
    condition_matched_log {
      filter = "resource.type=\"cloudsql_database\" insertId=~\".*slow.*\""
    }
  }

  alert_strategy {
    notification_rate_limit {
      period = "300s"
    }
    auto_close = "604800s"
  }

  documentation {
    content = "スロークエリが発生しました。  \n<!subteam^S999ABCDEFG>"
  }
}

ここまでで必要なリソースが準備できたので、スロークエリが発生すると下記のような通知が飛ぶようになります。

終わり。

参考

https://cloud.google.com/sql/docs/mysql/diagnose-issues?hl=ja#query-logs
https://dev.mysql.com/doc/refman/8.0/en/slow-query-log.html
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_long_query_time
https://cloud.google.com/logging/docs/logs-based-metrics/charts-and-alerts?hl=ja
https://api.slack.com/reference/surfaces/formatting
https://cloud.google.com/monitoring/support/notification-options?hl=ja#slack

GitHubで編集を提案
Welmo Engineer Blog

Discussion