MySQL アラート設計としきい値:レイテンシ・エラー率・レプリカ遅延の基準

MySQL の運用において、適切なアラート設計は障害の早期発見と予防に不可欠です。この記事では、レイテンシ・エラー率・レプリカ遅延の 3 つの重要な監視項目について、実践的なしきい値設定とアラート設計を解説します。これから MySQL の監視体制を構築する方、既存のアラートを見直したい方に向けて、具体的な基準と実装例をご紹介しますね。
背景
MySQL のパフォーマンス監視は、サービスの安定稼働に直結する重要な課題です。しかし、どの指標をどのようなしきい値で監視すべきか、明確な基準を持つことは簡単ではありません。
データベースの負荷やトラフィックパターンはサービスごとに異なり、適切なしきい値も環境によって変わります。また、アラートが多すぎると重要な通知を見逃してしまい、逆に少なすぎると障害の兆候を捉えられないというジレンマがあります。
以下の図は、MySQL 監視における主要な指標の関係性を示しています。
mermaidflowchart TB
client["クライアント<br/>アプリケーション"] -->|クエリ実行| mysql["MySQL<br/>プライマリ"]
mysql -->|レスポンス| client
mysql -->|レプリケーション| replica["MySQL<br/>レプリカ"]
subgraph monitoring["監視項目"]
latency["レイテンシ<br/>クエリ応答時間"]
error["エラー率<br/>失敗率・接続エラー"]
replication["レプリカ遅延<br/>データ同期遅延"]
end
mysql -.->|計測| latency
mysql -.->|計測| error
replica -.->|計測| replication
この図から、クライアントとデータベース間のやり取りにおいて、3 つの異なる側面から健全性を監視する必要があることがわかります。
課題
MySQL の監視設計では、以下のような課題に直面することが多いでしょう。
まず、しきい値の妥当性の判断が困難です。レイテンシ 100ms は遅いのか、エラー率 1%は許容範囲なのか、初めて監視を設計する場合は判断基準がないため悩みます。
次に、**アラート疲れ(Alert Fatigue)**の問題があります。しきい値を厳しく設定しすぎると、些細な変動でもアラートが発生し、本当に対応すべき障害を見逃してしまうリスクが高まるのです。
さらに、監視レベルの設定も重要な課題となります。警告レベルと緊急レベルをどう分けるべきか、どの時点でエスカレーションすべきかの基準が曖昧だと、適切な対応が遅れてしまいます。
また、環境差の考慮も必要です。開発環境・ステージング環境・本番環境では、求められるパフォーマンス基準が異なるため、一律のしきい値では対応できません。
以下の図は、これらの課題がどのように相互作用するかを示しています。
mermaidflowchart LR
threshold["しきい値設定"] -->|厳しすぎる| fatigue["アラート疲れ"]
threshold -->|緩すぎる| miss["障害見逃し"]
fatigue -->|重要度判断困難| response["対応遅延"]
miss -->|発見遅延| response
env["環境差"] -->|基準不明確| threshold
level["監視レベル"] -->|区分曖昧| threshold
response -->|サービス影響| impact["ユーザー体験低下"]
このように、適切なバランスを見つけることが監視設計の鍵となります。
解決策
これらの課題に対して、段階的なアラートレベルと具体的なしきい値基準を定義することで、効果的な監視体制を構築できます。
アラートレベルの定義
アラートは以下の 3 段階で設計することをお勧めします。
# | レベル | 対応時間 | 対応者 | 目的 |
---|---|---|---|---|
1 | INFO(情報) | 営業時間内 | 開発チーム | 傾向監視・予防保守 |
2 | WARNING(警告) | 1 時間以内 | オンコール担当 | 早期対応・悪化防止 |
3 | CRITICAL(緊急) | 即時(15 分以内) | オンコール担当 + マネージャー | 即時対応・サービス復旧 |
この段階的なアプローチにより、重要度に応じた適切な対応が可能になります。
レイテンシのしきい値設計
クエリ応答時間は、ユーザー体験に直結する最も重要な指標の一つです。
平均レイテンシ(avg_latency)の基準:
# | レベル | しきい値 | 継続時間 | 理由 |
---|---|---|---|---|
1 | INFO | 50ms 以上 | 10 分間 | 通常より遅い状態の検出 |
2 | WARNING | 100ms 以上 | 5 分間 | ユーザー体験への影響開始 |
3 | CRITICAL | 500ms 以上 | 1 分間 | 深刻なパフォーマンス劣化 |
P95 レイテンシ(95 パーセンタイル)の基準:
# | レベル | しきい値 | 継続時間 | 理由 |
---|---|---|---|---|
1 | INFO | 200ms 以上 | 10 分間 | 一部のクエリが遅延 |
2 | WARNING | 500ms 以上 | 5 分間 | 多くのユーザーに影響 |
3 | CRITICAL | 1000ms 以上 | 1 分間 | サービス品質の著しい低下 |
平均値だけでなく P95 を監視することで、一部のユーザーに発生する問題も見逃さずに対応できます。
エラー率のしきい値設計
接続エラーやクエリエラーは、アプリケーションの障害に直結します。
接続エラー率の基準:
# | レベル | しきい値 | 継続時間 | 理由 |
---|---|---|---|---|
1 | INFO | 0.1% 以上 | 5 分間 | 散発的なエラーの検出 |
2 | WARNING | 1% 以上 | 3 分間 | 接続プールの問題可能性 |
3 | CRITICAL | 5% 以上 | 1 分間 | データベース接続障害 |
クエリエラー率の基準:
# | レベル | しきい値 | 継続時間 | 理由 |
---|---|---|---|---|
1 | INFO | 0.5% 以上 | 5 分間 | アプリケーションバグの兆候 |
2 | WARNING | 2% 以上 | 3 分間 | データ不整合やスキーマ問題 |
3 | CRITICAL | 10% 以上 | 1 分間 | 深刻なアプリケーション障害 |
エラー率は絶対値が小さくても影響が大きいため、比較的低いしきい値を設定します。
レプリカ遅延のしきい値設計
レプリケーション遅延は、データの一貫性とスケーラビリティに影響します。
レプリカ遅延の基準:
# | レベル | しきい値 | 継続時間 | 理由 |
---|---|---|---|---|
1 | INFO | 10 秒以上 | 5 分間 | 通常より遅い同期速度 |
2 | WARNING | 30 秒以上 | 3 分間 | 読み取り一貫性への影響 |
3 | CRITICAL | 60 秒以上 | 1 分間 | レプリケーション停止の可能性 |
レプリカ停止の検出:
# | レベル | 条件 | 理由 |
---|---|---|---|
1 | CRITICAL | レプリケーションスレッド停止 | データ同期完全停止 |
2 | CRITICAL | レプリカ 5 分間応答なし | レプリカサーバー障害 |
以下の図は、アラートレベルと対応フローの関係を示しています。
mermaidstateDiagram-v2
[*] --> Normal: 正常稼働
Normal --> Info: しきい値超過<br/>INFO レベル
Info --> Normal: 自動復旧
Info --> Warn: 悪化継続<br/>WARNING レベル
Warn --> Info: 改善傾向
Warn --> Critical: さらに悪化<br/>CRITICAL レベル
Critical --> Warn: 一時回復
Critical --> Incident: 対応開始<br/>インシデント化
Incident --> Normal: 完全復旧
note right of Info
営業時間内対応
傾向分析
end note
note right of Warn
1時間以内対応
原因調査開始
end note
note right of Critical
即時対応
エスカレーション
end note
この状態遷移により、問題の深刻度に応じた適切な対応フローが実現できます。
具体例
ここでは、Prometheus と Grafana を使った実際の監視設定例をご紹介します。段階的に実装していきましょう。
MySQL Exporter の設定
まず、MySQL のメトリクスを収集するために MySQL Exporter を導入します。
Docker Compose での MySQL Exporter 設定:
yamlversion: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: myapp
ports:
- '3306:3306'
volumes:
- mysql_data:/var/lib/mysql
MySQL 本体のコンテナを定義します。本番環境ではパスワードは環境変数やシークレット管理ツールで管理してください。
yamlmysql-exporter:
image: prom/mysqld-exporter:latest
environment:
DATA_SOURCE_NAME: 'exporter:exporterpassword@(mysql:3306)/'
ports:
- '9104:9104'
depends_on:
- mysql
MySQL Exporter を設定し、MySQL からメトリクスを収集します。ポート 9104 で Prometheus がスクレイプできるようにします。
yamlprometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- ./alerts.yml:/etc/prometheus/alerts.yml
ports:
- '9090:9090'
command:
- '--config.file=/etc/prometheus/prometheus.yml'
Prometheus サーバーを起動し、設定ファイルとアラートルールを読み込みます。
yamlvolumes:
mysql_data:
データ永続化のためのボリュームを定義します。
Prometheus 設定
次に、Prometheus でメトリクスを収集する設定を行います。
prometheus.yml の基本設定:
yamlglobal:
scrape_interval: 15s # 15秒ごとにメトリクスを収集
evaluation_interval: 15s # 15秒ごとにアラートルールを評価
# アラートマネージャーの設定
alerting:
alertmanagers:
- static_configs:
- targets:
- 'alertmanager:9093'
グローバル設定で収集間隔とアラート評価間隔を定義します。頻繁すぎると負荷が高まるため、15 秒が適切でしょう。
yaml# アラートルールファイルの読み込み
rule_files:
- 'alerts.yml'
# メトリクス収集対象の設定
scrape_configs:
- job_name: 'mysql'
static_configs:
- targets: ['mysql-exporter:9104']
labels:
env: 'production'
service: 'mysql'
MySQL Exporter からメトリクスを収集する設定です。環境やサービスのラベルを付けることで、後でフィルタリングしやすくなります。
アラートルールの実装
続いて、具体的なアラートルールを定義していきます。
alerts.yml のグループ定義:
yamlgroups:
- name: mysql_latency_alerts
interval: 30s # 30秒ごとにこのグループのルールを評価
レイテンシ関連のアラートをグループ化します。グループごとに評価間隔を設定できます。
平均レイテンシの WARNING アラート:
yamlrules:
- alert: MySQLHighAverageLatency
expr: |
rate(mysql_global_status_queries[5m]) > 0
and
(rate(mysql_global_status_slow_queries[5m]) / rate(mysql_global_status_queries[5m])) > 0.1
for: 5m
labels:
severity: warning
component: mysql
annotations:
summary: 'MySQL 平均レイテンシが高い (instance {{ $labels.instance }})'
description: '過去5分間のスロークエリ比率が10%を超えています。現在の値: {{ $value | humanizePercentage }}'
スロークエリの比率を監視します。クエリ実行数に対するスロークエリの割合が 10%を超えた状態が 5 分間継続すると WARNING アラートが発火します。
平均レイテンシの CRITICAL アラート:
yaml- alert: MySQLCriticalAverageLatency
expr: |
rate(mysql_global_status_queries[1m]) > 0
and
(rate(mysql_global_status_slow_queries[1m]) / rate(mysql_global_status_queries[1m])) > 0.5
for: 1m
labels:
severity: critical
component: mysql
annotations:
summary: 'MySQL 平均レイテンシが非常に高い (instance {{ $labels.instance }})'
description: '過去1分間のスロークエリ比率が50%を超えています。即座の対応が必要です。現在の値: {{ $value | humanizePercentage }}'
より深刻な状況を検出します。スロークエリ比率が 50%を超えた状態が 1 分間継続すると CRITICAL アラートが発火しますね。
エラー率のアラートグループ:
yaml- name: mysql_error_alerts
interval: 30s
rules:
- alert: MySQLHighConnectionErrorRate
expr: |
rate(mysql_global_status_aborted_connects[5m]) > 0.01
for: 3m
labels:
severity: warning
component: mysql
annotations:
summary: 'MySQL 接続エラー率が高い (instance {{ $labels.instance }})'
description: '接続エラーが発生しています。レート: {{ $value | humanize }}/秒'
接続エラーを監視します。1 秒あたり 0.01 回(1 分あたり約 0.6 回)以上のエラーが 3 分間継続すると WARNING が発火します。
接続エラーの CRITICAL アラート:
yaml- alert: MySQLCriticalConnectionErrorRate
expr: |
rate(mysql_global_status_aborted_connects[1m]) > 0.05
for: 1m
labels:
severity: critical
component: mysql
annotations:
summary: 'MySQL 接続エラー率が非常に高い (instance {{ $labels.instance }})'
description: '大量の接続エラーが発生しています。データベース接続に深刻な問題があります。レート: {{ $value | humanize }}/秒'
深刻な接続エラーを検出します。1 秒あたり 0.05 回以上のエラーが 1 分間継続すると即座に対応が必要です。
レプリカ遅延のアラートグループ:
yaml- name: mysql_replication_alerts
interval: 30s
rules:
- alert: MySQLReplicationLagWarning
expr: |
mysql_slave_status_seconds_behind_master > 30
for: 3m
labels:
severity: warning
component: mysql-replication
annotations:
summary: 'MySQL レプリカ遅延が発生 (instance {{ $labels.instance }})'
description: 'レプリケーション遅延が30秒を超えています。現在の遅延: {{ $value }}秒'
レプリカの遅延を監視します。30 秒以上の遅延が 3 分間継続すると WARNING アラートが発火します。
レプリカ遅延の CRITICAL アラート:
yaml- alert: MySQLReplicationLagCritical
expr: |
mysql_slave_status_seconds_behind_master > 60
for: 1m
labels:
severity: critical
component: mysql-replication
annotations:
summary: 'MySQL レプリカ遅延が深刻 (instance {{ $labels.instance }})'
description: 'レプリケーション遅延が60秒を超えています。データ一貫性に影響があります。現在の遅延: {{ $value }}秒'
深刻なレプリカ遅延を検出します。60 秒以上の遅延が 1 分間継続すると CRITICAL アラートが発火しますね。
レプリケーション停止の検出:
yaml- alert: MySQLReplicationStopped
expr: |
mysql_slave_status_slave_io_running == 0
or
mysql_slave_status_slave_sql_running == 0
for: 1m
labels:
severity: critical
component: mysql-replication
annotations:
summary: 'MySQL レプリケーションが停止 (instance {{ $labels.instance }})'
description: 'レプリケーションスレッドが停止しています。IO Running: {{ $labels.slave_io_running }}, SQL Running: {{ $labels.slave_sql_running }}'
レプリケーションスレッドの停止を即座に検出します。IO スレッドまたは SQL スレッドが停止すると、1 分以内に CRITICAL アラートが発火します。
Grafana ダッシュボード設定
最後に、これらのメトリクスを可視化する Grafana ダッシュボードを設定します。
レイテンシパネルの PromQL クエリ:
promql# 平均クエリ実行時間
rate(mysql_global_status_slow_queries[5m]) / rate(mysql_global_status_queries[5m])
スロークエリの比率を計算し、レイテンシの傾向を可視化します。
promql# P95 レイテンシの推定(ヒストグラムがある場合)
histogram_quantile(0.95,
rate(mysql_query_duration_seconds_bucket[5m])
)
95 パーセンタイルのレイテンシを表示します。大多数のユーザーが体験する応答時間がわかります。
エラー率パネルの PromQL クエリ:
promql# 接続エラー率(1秒あたり)
rate(mysql_global_status_aborted_connects[5m])
接続エラーの発生頻度を時系列で表示します。
promql# クエリエラー率(パーセント)
rate(mysql_global_status_connection_errors_total[5m]) /
rate(mysql_global_status_connections[5m]) * 100
全接続に対するエラーの割合をパーセントで表示します。
レプリカ遅延パネルの PromQL クエリ:
promql# レプリカ遅延(秒)
mysql_slave_status_seconds_behind_master
レプリカの遅延時間をリアルタイムで表示します。
promql# レプリケーション状態
mysql_slave_status_slave_io_running * mysql_slave_status_slave_sql_running
レプリケーションスレッドの稼働状態を監視します。両方が 1 の場合のみ正常です。
アラート通知の設定
アラートを適切な担当者に通知するための設定も重要ですね。
Alertmanager の設定例(alertmanager.yml):
yamlglobal:
resolve_timeout: 5m # アラート解決の判定時間
# 通知テンプレート
templates:
- '/etc/alertmanager/templates/*.tmpl'
# ルーティング設定
route:
group_by: ['alertname', 'severity']
group_wait: 30s # 初回アラート待機時間
group_interval: 5m # グループ内の追加アラート間隔
repeat_interval: 3h # アラート再送間隔
基本的なルーティング設定を行います。同じアラートが頻繁に送信されないよう、適切な間隔を設定します。
yaml# デフォルトレシーバー
receiver: 'default-receiver'
# 重要度別ルーティング
routes:
- match:
severity: critical
receiver: 'critical-receiver'
continue: true
- match:
severity: warning
receiver: 'warning-receiver'
重要度に応じて異なる通知先にルーティングします。CRITICAL は即座に通知が必要です。
Slack 通知の設定:
yamlreceivers:
- name: 'default-receiver'
slack_configs:
- api_url: 'YOUR_SLACK_WEBHOOK_URL'
channel: '#mysql-monitoring'
title: 'MySQL アラート'
text: |
{{ range .Alerts }}
*アラート:* {{ .Labels.alertname }}
*重要度:* {{ .Labels.severity }}
*説明:* {{ .Annotations.description }}
{{ end }}
デフォルトの通知設定です。Slack の Webhook URL を設定してください。
yaml- name: 'critical-receiver'
slack_configs:
- api_url: 'YOUR_SLACK_WEBHOOK_URL'
channel: '#mysql-critical'
title: '🚨 MySQL 緊急アラート'
text: |
@channel
{{ range .Alerts }}
*アラート:* {{ .Labels.alertname }}
*インスタンス:* {{ .Labels.instance }}
*説明:* {{ .Annotations.description }}
*対応:* 即座の対応が必要です
{{ end }}
CRITICAL レベルのアラートは専用チャンネルに @channel 付きで通知します。担当者全員に確実に届きますね。
yaml- name: 'warning-receiver'
slack_configs:
- api_url: 'YOUR_SLACK_WEBHOOK_URL'
channel: '#mysql-warnings'
title: '⚠️ MySQL 警告'
text: |
{{ range .Alerts }}
*アラート:* {{ .Labels.alertname }}
*インスタンス:* {{ .Labels.instance }}
*説明:* {{ .Annotations.description }}
{{ end }}
WARNING レベルは別チャンネルで通知し、緊急度を分けて管理します。
以下の図は、アラート発生から通知、対応までのフローを示しています。
mermaidsequenceDiagram
participant M as MySQL
participant E as Exporter
participant P as Prometheus
participant A as Alertmanager
participant S as Slack
participant T as 担当者
M->>E: メトリクス提供
E->>P: メトリクス収集<br/>(15秒ごと)
P->>P: ルール評価<br/>(30秒ごと)
Note over P: しきい値超過検出
P->>A: アラート送信
A->>A: グルーピング<br/>待機30秒
A->>S: Slack通知送信
S->>T: 通知受信
T->>M: 調査・対応
M->>E: 正常化メトリクス
E->>P: 正常値収集
P->>A: アラート解決
A->>S: 解決通知
この一連のフローにより、問題の検出から対応、解決までを追跡できます。
環境別設定の例
開発環境と本番環境で異なるしきい値を設定する方法もご紹介します。
環境別アラートルールの設定:
yamlgroups:
- name: mysql_latency_production
interval: 30s
rules:
- alert: MySQLHighLatencyProduction
expr: |
(rate(mysql_global_status_slow_queries[5m]) / rate(mysql_global_status_queries[5m])) > 0.1
and on(instance) mysql_exporter_build_info{env="production"}
for: 5m
labels:
severity: warning
env: production
本番環境専用のアラートルールです。env="production"
ラベルでフィルタリングします。
yaml- name: mysql_latency_development
interval: 30s
rules:
- alert: MySQLHighLatencyDevelopment
expr: |
(rate(mysql_global_status_slow_queries[5m]) / rate(mysql_global_status_queries[5m])) > 0.3
and on(instance) mysql_exporter_build_info{env="development"}
for: 10m
labels:
severity: info
env: development
開発環境では、しきい値を緩く(0.3)、継続時間を長く(10 分)設定します。頻繁なアラートを避けつつ、傾向は把握できますね。
まとめ
MySQL のアラート設計では、レイテンシ・エラー率・レプリカ遅延の 3 つの主要指標を段階的に監視することが重要です。
INFO・WARNING・CRITICAL の 3 段階のアラートレベルを設定することで、問題の深刻度に応じた適切な対応が可能になります。レイテンシは平均値と P95 の両方を監視し、エラー率は低いしきい値で早期検出、レプリカ遅延は 30 秒・60 秒・停止の 3 段階で監視することをお勧めします。
Prometheus と Grafana を組み合わせることで、メトリクス収集・アラート発火・可視化・通知までを一貫して実装できます。環境ごとに異なるしきい値を設定し、アラート疲れを防ぎながら重要な問題を見逃さない監視体制を構築してください。
これらの基準は出発点として活用し、実際のトラフィックパターンやサービス要件に応じて調整していくことで、より効果的な監視システムが完成します。適切なアラート設計により、障害の早期発見とサービスの安定稼働を実現しましょう。
関連リンク
- article
MySQL アラート設計としきい値:レイテンシ・エラー率・レプリカ遅延の基準
- article
MySQL 読み書き分離設計:ProxySQL で一貫性とスループットを両立
- article
MySQL オプティマイザヒント早見表:/\*+ NO_MERGE, INDEX, HASH_JOIN \*/ 実例集
- article
MySQL Shell(mysqlsh)入門:AdminAPI で InnoDB Cluster を最短構築
- article
MySQL Optimizer Hints 実測比較:INDEX_MERGE/NO_RANGE_OPTIMIZATION ほか
- article
MySQL ロック待ち・タイムアウトの解決:SHOW ENGINE INNODB STATUS の読み解き方
- article
NestJS 監視運用:SLI/SLO とダッシュボード設計(Prometheus/Grafana/Loki)
- article
WebRTC AV1/VP9/H.264 ベンチ比較 2025:画質・CPU/GPU 負荷・互換性を実測
- article
MySQL アラート設計としきい値:レイテンシ・エラー率・レプリカ遅延の基準
- article
Vitest フレーク検知技術の運用:`--retry` / シード固定 / ランダム順序で堅牢化
- article
Motion(旧 Framer Motion)デザインレビュー運用:Figma パラメータ同期と差分共有のワークフロー
- article
esbuild プリバンドルを理解する:Vite の optimizeDeps 深掘り
- blog
iPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
- blog
Googleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
- blog
【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
- blog
Googleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
- blog
Pixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
- blog
フロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
- review
今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
- review
ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来