図解で、Datadog DBM データベースのモニタリング設定（MySQL）

# サーバーがホストするMySQLのモニタリング設定手順
アプリやデータベースの監視モニタリングは、サーバーの監視モニタリングよりも多くの種類・設定パラメータがあるのでセットアップの公式ドキュメントが多岐に渡りボリュームが比較的多いのは仕方ない。そこで、ざっと設定手順を確認/紹介したいときのために図解でシンプルな設定手順を記載する。
データベースは、Postgres, Oracle 他のDB種類、そして AWS RDS, Aurora, Azure他ホスト方式の違いで多数組み合わせが存在する。今回はサーバーOSにインストールした MySQL を対象に Datadog Database Monitoring (DBM) を対象に最小限の設定手順を記載する。最終章にDB種類/制限事項/条件を記載する。

**設定でのつまづきポイントは３つ**

-  DBログファイルの権限
Datadogエージェントが読み込むDBログファイルに読み込みできる権限を設定すること
- MySQLのバージョン毎
スキーマの設定コマンドが異なるので、バージョンに合わせてコマンドを選ぶこと
- DBパフォーマンス設定
パフォーマンスの詳細は、いくつかのオプションを追加設定することをおススメ


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/900eeb8d-288d-cd21-602a-da211c302dba.png)


## MySQL モニタリング対象の構成
セルフホスト型MySQL（サーバーOS にインストールした MySQL）を監視モニタリングする。モニタリングは、クエリの応答時間とエラー率を可視化し、監視はDB接続できないときにアラート通知する。検証環境：Ubuntu22.04 + MySQL:MariaDB10.6

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/7273b2c8-b018-4a64-21a7-48e02e8604ff.png)

## 設定手順
Datadogエージェントがインストール済みであることを前提とする。
1. MySQL のパフォーマンススキーマを有効化する設定
2. MySQL にOSユーザー[datadog]を追加し、パフォーマンスの読み取り権限を付与する
3. Datadogエージェントの mysqlコンフィグを設定する
4. MySQL のログを取得する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/ea141bf9-191c-e33f-667f-b1d260a0a5b9.png)


## （１）MySQL のパフォーマンススキーマを有効化する設定
Datadogエージェントがクエリのメトリクスを収集するには下記パラメータ[*1]が必須だが、ほとんどはMySQLデフォルトなら有効になっていた（*1:MySQL5.7以降）

[MySQL 5.7 以上](https://docs.datadoghq.com/ja/database_monitoring/setup_mysql/selfhosted/?tab=mysql57)　※下記
[MySQL 5.6](https://docs.datadoghq.com/ja/database_monitoring/setup_mysql/selfhosted/?tab=mysql56)　※公式ドキュメントを参照方

```
performance_schema: ON（必須）
max_digest_length: 4096（必須）
performance-schema-consumer-events-statements-current: ON（必須）
performance-schema-consumer-events-waits-current: ON（必須）
# その他: 任意, 推奨のパラメータは公式ドキュメントを参照方
```

設定値の確認手順

``` Ubuntuコマンド
$ sudo mysql -u root
```

``` MySQLコマンド
MariaDB> SHOW VARIABLES LIKE 'performance_schema';
MariaDB> SHOW VARIABLES LIKE 'max_digest_length';
MariaDB> SHOW VARIABLES LIKE 'performance-schema-consumer-events-statements-current';
MariaDB> SHOW VARIABLES LIKE 'performance-schema-consumer-events-waits-current';

▼ 表示サンプル
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| performance_schema | ON    |
+--------------------+-------+
```

パフォーマンススキーマの値が必須値と異なる場合は MySQL コンフィグに下記追加する。

``` my.cnf
[mysqld]
performance_schema=ON
max_digest_length=4096
performance-schema-consumer-events-statements-current=ON
performance-schema-consumer-events-waits-current=ON
```

[my.cnf]の保存場所/シンボリックリンクが複数あったので競合しないように注意

```
/etc/mysql/conf.d/my.cnf
/etc/mysql/mariadb.cnf
/etc/mysql/mariadb.conf.d/
/etc/mysql/my.cnf -> /etc/alternatives/my.cnf
                     /etc/alternatives/my.cnf -> /etc/mysql/mariadb.cnf
```

## （２）MySQL にOSユーザー[datadog]を追加し、パフォーマンスの読み取り権限を付与する

``` Ubuntuコマンド
$ sudo mysql -u root
```

DBを読み取りするためにユーザー[datadog]を任意のパスワードを決めて作成。[%]は任意のサーバーからログインするが[loalhost]を指定してDBをホストしているサーバーのDatadogエージェントに制限することも可能。

ここもMySQLのバージョン毎に異なる
[MySQL 5.7 以上](https://docs.datadoghq.com/ja/database_monitoring/setup_mysql/selfhosted/?tab=mysql57)　※下記
[MySQL 5.6](https://docs.datadoghq.com/ja/database_monitoring/setup_mysql/selfhosted/?tab=mysql56)　※公式ドキュメントを参照方


```
CREATE USER datadog@'%' IDENTIFIED by '任意のdatadogパスワード';
```

ユーザー[datadog]に権限を付与
```
ALTER USER datadog@'%' WITH MAX_USER_CONNECTIONS 5;
GRANT REPLICATION CLIENT ON *.* TO datadog@'%';
GRANT PROCESS ON *.* TO datadog@'%';
GRANT SELECT ON performance_schema.* TO datadog@'%';
```

存在しなければスキーマ[datadog]を作成し、権限[Execute]をユーザー[datadog]に付与。
```
CREATE SCHEMA IF NOT EXISTS datadog;
GRANT EXECUTE ON datadog.* to datadog@'%';
GRANT CREATE TEMPORARY TABLES ON datadog.* TO datadog@'%';
```

データベースエンジンがクエリ実行を分析できるようにする。
プロシージャを試用してSQLクエリの実行計画をJSON形式で出力できるようにして、スキーマ[datadog]内にストアドプロシージャ[explain_statement]を作成し、[explain]コマンドを実行できるようにする。

```
DELIMITER $$
CREATE PROCEDURE datadog.explain_statement(IN query TEXT)
    SQL SECURITY DEFINER
BEGIN
    SET @explain := CONCAT('EXPLAIN FORMAT=json ', query);
    PREPARE stmt FROM @explain;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;
```

推奨：パフォーマンススキーマのcomsumers設定を一括で有効化する。
スキーマ[datadog]内にストアドプロシージャ[enable_events_statements_consumers]を作成し、events_statements_*で始まる機能を有効 YESにしてこのプロシージャの実行権を付与する。
```
DELIMITER $$
CREATE PROCEDURE datadog.enable_events_statements_consumers()
    SQL SECURITY DEFINER
BEGIN
    UPDATE performance_schema.setup_consumers SET enabled='YES' WHERE name LIKE 'events_statements_%';
    UPDATE performance_schema.setup_consumers SET enabled='YES' WHERE name = 'events_waits_current';
END $$
DELIMITER ;
GRANT EXECUTE ON PROCEDURE datadog.enable_events_statements_consumers TO datadog@'%';
```

## （３）Datadogエージェントの mysqlコンフィグを設定する
MySQLメトリックスを取得するため mysql.yamlを作成、コンフィグを設定する。
``` 
$ cd /etc/datadog-agent/conf.d
$ cp mysql.d/conf.yaml.example mysql.yaml
```

datadogのコンフィグは /etc/datadog-agent/conf.d ディレクトリに yaml ファイルを置いても参照してくれるので SSH接続したときに色分けして見やすいようにすることも可能。どのチェックが有効なのかディレクトリ内を出入りしなくても見つけやすくなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/1d36e3db-8b22-e543-7de0-5a92072c1706.png)

``` mysql.yaml
init_config:
instances:
  - dbm: true
    host: 127.0.0.1
    port: 3306
    username: datadog
    password: '（暗号化した*1）任意のdatadogパスワード'
```

*1: 平文でパスワードを記載することもできる

## 再起動して MySQL ダッシュボードを検査

MySQLとDatadogエージェントを再起動
```
$ sudo systemctl restart mysql
$ sudo systemctl restart datadog-agent
$ sudo datadog-agent status

    mysql (14.2.0)
    --------------
      Instance ID: mysql:7f8794a2eed816c5 [OK]
      Configuration Source: file:/etc/datadog-agent/conf.d/mysql.yaml
      <略>
      Database Monitoring Activity Samples: Last Run: 2, Total: 9,462
      Database Monitoring Metadata Samples: Last Run: 1, Total: 307
      Database Monitoring Query Metrics: Last Run: 2, Total: 9,459
      Database Monitoring Query Samples: Last Run: 2, Total: 1,448
      <略>
```


Datadogダッシュボードの検査
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/4955b783-92e5-77ca-1f52-4dbb034761d0.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/c7c5aaaa-8fae-ba4b-9a9f-449fbebe2024.png)

## （４）MySQL のログを取得する

まずはログ保存場所を調べる
```
MariaDB [(none)]> SHOW VARIABLES LIKE 'log_error';
MariaDB [(none)]> SHOW VARIABLES LIKE 'general_log_file'
MariaDB [(none)]> SHOW VARIABLES LIKE 'slow_query_log_file';
MariaDB [(none)]> SHOW VARIABLES LIKE 'log_bin_basename';

▼ サンプル
+---------------------+---------------+
| Variable_name       | Value         |
+---------------------+---------------+
| slow_query_log_file | game-slow.log |
+---------------------+---------------+
```

```
MariaDB [(none)]> SHOW VARIABLES LIKE 'datadir';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+
```

ディレクトリ［/var/lib/mysql］にログが存在しないので、MySQLのコンフィグでログ出力を設定する
``` my.cnf -> /etc/alternatives/my.cnf -> /etc/mysql/mariadb.cnf
general_log_file = /var/lib/mysql/game.log
slow_query_log_file = /var/lib/mysql/game-slow.log
log_error = /var/log/mysql/error.log
# 一般クエリを有効にすると全てのクエリが記録されるがファイルが急速に大きくなる
#general_log = 1
# 遅いクエリのみ記録するlong_query_time = 2で秒数を指定できる
slow_query_log = 1
long_query_time = 3
```

これだけだとユーザー[dd-agent]がログファイルのアクセス権がない。
```
Path: /var/lib/mysql/game.log
Status: Error: open /var/lib/mysql/game.log: permission denied

Path: /var/lib/mysql/game-slow.log
Status: Error: open /var/lib/mysql/game-slow.log: permission denied
```

ログファイルの所有グループは[mysql]なので、ユーザー[dd-agent]を追加して検査する。
```
$ ll
-rw-rw----  1 mysql mysql    592118 Jan 26 22:37 game.log
-rw-rw----  1 mysql mysql     21177 Jan 26 23:32 game-slow.log

$ sudo usermod -aG mysql dd-agent
$ groups dd-agent
dd-agent : dd-agent adm mysql kano docker
```

ディレクトリにもアクセス権を追加
```
sudo chown mysql:mysql /var/lib/mysql/
sudo chmod 750 /var/lib/mysql/
```

MySQL がログを出力したら、Datadogエージェントのコンフィグ[mysql.yaml]にログファイルのパスを追加する。

``` /etc/datadog-agent/conf.d/mysql.yaml
logs:
  - type: file
    path: /var/log/mysql/error.log
    source: mysql
  - type: file
    path: /var/lib/mysql/game.log
    source: mysql
  - type: file
    path: /var/lib/mysql/game-slow.log
    source: mysql
```


mysqlとdatadog-agentを再起動してMySQLダッシュボードでログを検査する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/459aa9ad-f0ef-e5a7-ef0c-ebbe618edd7d.png)

以上、DBMを設定したときの手順確認。

## DB接続障害を監視する（アラート通知）
Monitors > New Monitor
監視するメトリックは[mysql.can_connect]、3回以上失敗でアラート通知するという設定の場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/69e76c45-165e-dd93-b469-952fda0a7b8d.png)

mysql を停止して障害アラートを検査した
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/fff8db1f-f8e9-b6f8-aebd-9bff41a11d51.png)




## DB種類/制限事項/条件

### DBモニタリングの対象DB
- AWS RDS,
- AWS Aurora
- Self Hosted（サーバーOSにインストール）
- Google CloudSQL
- Azure Database for MySQL

### 条件
- MySQLバージョン 5.6以降
- Datadogエージェント 7.36.1以降

### 制限事項
- パフォーマンス影響 ワークロードの1%未満
- Datadogエージェントのローカル127.0.0.1。プロキシ、ロードバランサー、コネクションプーラーを介してDB接続しないこと。
- [MySQL設定詳細](https://docs.datadoghq.com/ja/database_monitoring/setup_mysql/selfhosted/?tab=mysql57)
- [機密情報は難読化される](https://docs.datadoghq.com/ja/database_monitoring/data_collected/#%E6%A9%9F%E5%AF%86%E6%83%85%E5%A0%B1)

### モニタリング負荷（オーバーヘッド）
- チェックの最小収集間隔15秒
- クエリメトリクスの収集間隔10秒
- クエリアクティビティの収集間隔10秒
- クエリサンプルの収集間隔1秒
- 設定の収集間隔600秒

### オーバーヘッド（Agentバージョン: 7.50.2）
- CPU: 平均CPUの約2%
- メモリ: 約300 MiB
- ネットワーク帯域幅: IN約40KB/秒 | OUT約30KB/秒

以上

## まとめ
仮想サーバーがホストする MySQL を対象に、Datadog データベースモニタリング(DBM)設定手順を検証した。DBモニタリングでできること、設定手順まで確認できた。