本文の内容は、2021年11月4日にDavid de Torres Huertaが投稿したブログ(https://sysdig.com/blog/mysql-monitoring/)を元に日本語に翻訳・再構成した内容となっております。
MySQL Prometheus エクスポーターを使えば、PrometheusでMySQLのモニタリングが簡単にできます。MySQLは紹介するまでもなく、世界で最も使用されているリレーショナル・データベースの一つであり、しかもオープンソースです。
このように人気のあるデータベースであるということは、それを支えるコミュニティも巨大であるということです。ですから、心配しないでください:あなたは一人ではありません。
この記事では、Prometheus を使って MySQL サーバーの監視を行う方法を説明します。エクスポーターの設定から、主要なメトリクスは何か、アラートの例を交えて説明します。MySQL を RDS で運用している場合は、Amazon RDS を監視するためのトップ 5 キーメトリクスをお見逃しなく。
設定方法
エクスポーターをクラスターにデプロイする前に、データベースにエクスポーターのユーザーとパスワードを作成する必要があります。MySQLデータベースに入り、以下のクエリを実行します:CREATE USER 'exporter'@'%' IDENTIFIED BY 'YOUR-PASSWORD' WITH MAX_USER_CONNECTIONS 3; GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';
SQL文中のユーザー名とパスワードを、独自のものに置き換えてください。
エクスポーターのユーザー名とパスワードをデータベースに登録したら、エクスポーターの認証情報を記載した
mysql-exporter.cnf
ファイルを作成しなければなりません。また、このファイルには、MySQL データベースに接続するための URL を host
フィールドに記述します:[client] user = exporter password = "YOUR-PASSWORD" host=YOUR-DB-IP
Kubernetesクラスターでは、
mysql-exporter.cnf
ファイルでシークレットを作成します。このファイルは、データベースとの認証のためにエクスポーターにマウントされます。kubectl create secret generic mysql-exporter \ --from-file=.my.cnf=./mysql-exporter.cnf
MySQL Prometheus エクスポーターのデプロイ方法
Prometheus で MySQL の監視を開始するには、MySQL エクスポーター をクラスターにデプロイする必要があります。エクスポーターをデプロイするには、以下のサンプルファイルを使用することができます。
--- apiVersion: apps/v1 kind: Deployment metadata: name: mysql-exporter-exporter spec: selector: matchLabels: app: mysql-exporter replicas: 1 template: metadata: labels: app: mysql-exporter annotations: prometheus.io/scrape: "true" prometheus.io/port: "9104" spec: containers: - name: mysql-exporter image: prom/mysqld-exporter:latest args: - --config.my-cnf=/tmp/.my.cnf ports: - containerPort: 9104 volumeMounts: - name: my-cnf mountPath: /tmp/.my.cnf subPath: .my.cnf resources: limits: memory: "256Mi" cpu: "256m" volumes: - name: my-cnf secret: defaultMode: 420 secretName: mysql-exporter items: - key: .my.cnf path: .my.cnf
エクスポーターのDeploymentを適用すると、Prometheusはすでに標準的なアノテーションを持っているので、自動的にMySQLのメトリクスのスクレイピングを開始します。
PrometheusでMySQLを監視するためのメトリクス Top 5
#1 可用性
MySQLインスタンスの可用性を監視するメトリクスは2つあります。1つ目はmysql_up
。このメトリクスがゼロに等しい場合、エクスポーターはデータベースにアクセスできず、これはデータベースが不健康または故障しているという症状である可能性があります。以下のクエリで、データベースがダウンした場合に通知するアラートを作成することができます:
mysql_up == 0
また、
mysql_global_status_uptime
というメトリクスは、前のメトリクスのレーダーの下を通過する可能性のある高速な再起動について知ることができます。以下のPrometheusクエリでアラートを作成し、アップタイムが30分未満のインスタンスを検出することができます。mysql_global_status_uptime < 1800
#2 コネクション
データベースのエラーの主な原因のひとつは、接続エラーです。mysql_global_status_connection_errors_total
というメトリクスを使うと、データベースがいつこれらのエラーを発生させているかを検出することができます:rate(mysql_global_status_connection_errors_total[5m])
接続エラーの一般的な原因の 1 つは、利用可能な接続がないことです。このPrometheusのクエリーで、使用可能な接続の割合を確認することができます:
100 * mysql_global_status_threads_connected / mysql_global_variables_max_connections
この値が100に近い場合、データベースは新しい接続を拒否し始める可能性があります。この問題を解決するには、最大接続数を増やすことができます。その前に、システムで利用可能なオープンファイルの数を確認してください。以下のPrometheusのクエリーで確認できます。
mysql_global_variables_open_files_limit - mysql_global_variables_innodb_open_files
PromQLをもっと深く知りたいですか?PromQLの入門ガイドを読んで、Prometheusがどのようにデータを保存するか、PromQLの関数や演算子の使い方を学びましょう。
#3 スロークエリー
多くのデータベースと同様に、MySQLはスロークエリーのログを記録します。このログのエントリー数は、mysql_global_status_slow_queries
というメトリクスで確認することができます。以下のPrometheusクエリーでアラートを作成すると、スロークエリーのログに新しいエントリがあったときに通知され、パフォーマンスの問題があることを意味します:rate(mysql_global_status_slow_queries[5m])
#4 キャッシュヒット率
MySQLは、ディスクの読み書き操作を最適化するためにインメモリキャッシュを使用しています。キャッシュのヒット率が低いと、データベースのパフォーマンスに影響を与えます。このPrometheusのクエリーは、オープンテーブルのキャッシュヒット率の値を表示します。rate(mysql_global_status_table_open_cache_hits[5m]) / (rate(mysql_global_status_table_open_cache_hits[5m]) + rate(mysql_global_status_table_open_cache_misses[5m]))
また、以下のpromQLクエリでバッファプールキャッシュを監視することができます。
(rate(mysql_global_status_innodb_buffer_pool_read_requests[5m]) - rate(mysql_global_status_innodb_buffer_pool_reads[5m])) / rate(mysql_global_status_innodb_buffer_pool_read_requests[5m]))
MySQLの設定でオープンテーブルやプールキャッシュのバッファサイズをチューニングすることができますが、そうするとインスタンスのメモリ使用量に影響することを覚えておいてください。十分なメモリがあることを確認してください。cAdvisor メトリクスを使用して、コンテナの利用可能なメモリを確認できます:
sum by (namespace,pod,container)((container_memory_usage_bytes{container!="POD",container!=""} - on (namespace,pod,container) avg by (namespace,pod,container)(kube_pod_container_resource_limits{resource="memory"})) * -1 >0 ) / (1024*1024*1024)
MySQLインスタンスがAWS RDSにある場合は、RDSインスタンスの監視方法についてのブログ記事をご参照ください。
#5 クエリーの種類
MySQL データベースでは、SELECT クエリーの種類ごとに情報を提供するメトリクスを使用して、その使用状況の統計を取ることができます:- Full join: mysql_global_status_select_full_join
- Full range join: mysql_global_status_select_full_range_join
- Select range check (各行の後にキーの使用状況をチェックするキーなしで結合): mysql_global_status_select_range_check
- Select scan: mysql_global_status_select_scan
いずれもカウンターなので、Prometheusのクエリーでは次のように関数rateを使うことを覚えておきましょう:
rate(mysql_global_status_select_full_join[5m])
同様に、MySQL でのソート クエリーの使用状況を統計を取ることもできます:
- Sort rows: mysql_global_status_sort_rows
- 範囲を使用して行われたソートの数: mysql_global_status_sort_range
- Sort merge (ソートアルゴリズムが行わなければならなかったマージパスの数): mysql_global_status_sort_merge_passes
- テーブルをスキャンして行われたソートの数: mysql_global_status_sort_scan
次のステップ
この記事では、Prometheus を使って MySQL のモニタリングを開始するのがいかに簡単かを学びました。必要なのは、適切なエクスポーターと設定だけです。また、Prometheus で MySQL を監視する際に念頭に置くべき主要な Prometheus クエリーについても学びました。
Prometheus クエリーを書くためのインスピレーションを得たい場合は、Kubernetes を監視するための例を見たり、PromQL getting started cheatsheet をダウンロードしたりすることができます。