监控MySQL运行状态:MySQLD Exporter

2023-05-19 19:54:28 浏览数 (1)

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle旗下的产品。 MySQL是最流行的关系型数据库管理系统之一。数据库的稳定运行是保证业务可用性的关键因素之一。这一小节当中将介绍如何使用Prometheus提供的MySQLD Exporter实现对MySQL数据库性能以及资源利用率的监控和度量。

# 二进制部署MySQL_Exporter

代码语言:javascript复制
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.12.0/mysqld_exporter-0.12.0.linux-amd64.tar.gz
tar xvf mysqld_exporter-0.12.0.linux-amd64.tar.gz
mv mysqld_exporter-0.12.0.linux-amd64 /data/
# 创建配置文件
cat >> /data/mysql_exporter/localhost_db.cnf <<EOF
[client]
user=mysqld_exporter
password=12345678
EOF
# 创建systemd服务
cat > /etc/systemd/system/mysql_exporter.service << EOF
[Unit]
Description=mysql_exporter
After=network.target

[Service]
Type=simple
User=prometheus
ExecStart=/data/mysql_exporter/mysqld_exporter --config.my-cnf="/data/mysql_exporter/localhost_db.cnf" --web.listen-address=":9105"
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

# grant permission to database.

代码语言:javascript复制
GRANT REPLICATION CLIENT, PROCESS ON *.* TO 'mysqld_exporter'@'localhost' identified by '12345678';
GRANT SELECT ON performance_schema.* TO 'mysqld_exporter'@'localhost';
flush privileges;

# Docker部署部署MySQLD Exporter

为了简化测试环境复杂度,这里使用Docker Compose定义并启动MySQL以及MySQLD Exporter:

代码语言:javascript复制
version: '3'
services:
  mysql:
    image: mysql:5.7
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_DATABASE=database
  mysqlexporter:
    image: prom/mysqld-exporter
    ports:
      - "9104:9104"
    environment:
      - DATA_SOURCE_NAME=root:password@(mysql:3306)/database

这里通过环境变量DATA_SOURCE_NAME方式定义监控目标。使用Docker Compose启动测试用的MySQL实例以及MySQLD Exporter:

代码语言:javascript复制
$ docker-compose up -d

启动完成后,可以通过以下命令登录到MySQL容器当中,并执行MySQL相关的指令:

代码语言:javascript复制
$ docker exec -it <mysql_container_id> mysql -uroot -ppassword
mysql>

可以通过http://localhost:9104 (opens new window)访问MySQLD Exporter暴露的服务:

可以通过/metrics查看mysql_up指标判断当前MySQLD Exporter是否正常连接到了MySQL实例,当指标值为1时表示能够正常获取监控数据:

代码语言:javascript复制
# HELP mysql_up Whether the MySQL server is up.
# TYPE mysql_up gauge
mysql_up 1

修改Prometheus配置文件/etc/prometheus/prometheus.yml,增加对MySQLD Exporter实例的采集任务配置:

代码语言:javascript复制
- job_name: mysqld
  static_configs:
  - targets:
    - localhost:9104

启动Prometheus:

代码语言:javascript复制
prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/data/prometheus

通过Prometheus的状态页,可以查看当前Target的状态:

为了确保数据库的稳定运行,通常会关注一下四个与性能和资源利用率相关的指标:查询吞吐量、连接情况、缓冲池使用情况以及查询执行性能等。

# 监控数据库吞吐量

对于数据库而言,最重要的工作就是实现对数据的增、删、改、查。为了衡量数据库服务器当前的吞吐量变化情况。在MySQL内部通过一个名为Questions的计数器,当客户端发送一个查询语句后,其值就会 1。可以通过以下MySQL指令查询Questions等服务器状态变量的值:

代码语言:javascript复制
mysql> SHOW GLOBAL STATUS LIKE "Questions";
 --------------- ------- 
| Variable_name | Value |
 --------------- ------- 
| Questions     | 1326  |
 --------------- ------- 
1 row in set (0.00 sec)

MySQLD Exporter中返回的样本数据中通过mysql_global_status_questions反映当前Questions计数器的大小:

代码语言:javascript复制
# HELP mysql_global_status_questions Generic metric from SHOW GLOBAL STATUS.
# TYPE mysql_global_status_questions untyped
mysql_global_status_questions 1016

通过以下PromQL可以查看当前MySQL实例查询速率的变化情况,查询数量的突变往往暗示着可能发生了某些严重的问题,因此用于用户应该关注并且设置响应的告警规则,以及时获取该指标的变化情况:

代码语言:javascript复制
rate(mysql_global_status_questions[2m])

一般还可以从监控读操作和写操作的执行情况进行判断。通过MySQL全局状态中的Com_select可以查询到当前服务器执行查询语句的总次数:相应的,也可以通过Com_insert、Com_update以及Com_delete的总量衡量当前服务器写操作的总次数,例如,可以通过以下指令查询当前MySQL实例insert语句的执行次数总量:

代码语言:javascript复制
mysql> SHOW GLOBAL STATUS LIKE "Com_insert";
 --------------- ------- 
| Variable_name | Value |
 --------------- ------- 
| Com_insert    | 0     |
 --------------- ------- 
1 row in set (0.00 sec)

从MySQLD Exporter的/metrics返回的监控样本中,可以通过global_status_commands_total获取当前实例各类指令执行的次数:

代码语言:javascript复制
# HELP mysql_global_status_commands_total Total number of executed MySQL commands.
# TYPE mysql_global_status_commands_total counter
mysql_global_status_commands_total{command="admin_commands"} 0
mysql_global_status_commands_total{command="alter_db"} 0
mysql_global_status_commands_total{command="alter_db_upgrade"} 0
mysql_global_status_commands_total{command="select"} 10
mysql_global_status_commands_total{command="insert"} 2
mysql_global_status_commands_total{command="update"} 2
mysql_global_status_commands_total{command="delete"} 1

用户可以通过以下PromQL查看当前MySQL实例写操作速率的变化情况:

代码语言:javascript复制
sum(rate(mysql_global_status_commands_total{command=~"insert|update|delete"}[2m])) without (command)

# 连接情况

在MySQL中通过全局设置max_connections限制了当前服务器允许的最大客户端连接数量。一旦可用连接数被用尽,新的客户端连接都会被直接拒绝。 因此当监控MySQL运行状态时,需要时刻关注MySQL服务器的连接情况。用户可以通过以下指令查看当前MySQL服务的max_connections配置:

代码语言:javascript复制
mysql> SHOW VARIABLES LIKE 'max_connections';
 ----------------- ------- 
| Variable_name   | Value |
 ----------------- ------- 
| max_connections | 151   |
 ----------------- ------- 
1 row in set (0.01 sec)

MySQL默认的最大链接数为151。临时调整最大连接数,可以通过以下指令进行设置:

代码语言:javascript复制
SET GLOBAL max_connections = 200;

如果想永久化设置,则需要通过修改MySQL配置文件my.cnf,添加以下内容:

代码语言:javascript复制
max_connections = 200

通过Global Status中的Threads_connected、Aborted_connects、Connection_errors_max_connections以及Threads_running可以查看当前MySQL实例的连接情况。

例如,通过以下指令可以直接当前MySQL实例的连接数:

代码语言:javascript复制
mysql> SHOW GLOBAL STATUS LIKE "Threads_connected";
 ------------------- ------- 
| Variable_name     | Value |
 ------------------- ------- 
| Threads_connected | 1     |
 ------------------- ------- 
1 row in set (0.00 sec)

当所有可用连接都被占用时,如果一个客户端尝试连接至MySQL,会出现“Too many connections(连接数过多)”错误,同时Connection_errors_max_connections的值也会增加。为了防止出现此类情况,你应该监控可用连接的数量,并确保其值保持在max_connections限制以内。同时如果Aborted_connects的数量不断增加时,说明客户端尝试连接到MySQL都失败了。此时可以通过Connection_errors_max_connections以及Connection_errors_internal分析连接失败的问题原因。

下面列举了与MySQL连接相关的监控指标:

  • mysql_global_variables_max_connections: 允许的最大连接数;
  • mysql_global_status_threads_connected: 当前开放的连接;
  • mysql_global_status_threads_running:当前开放的连接;
  • mysql_global_status_aborted_connects:当前开放的连接;
  • mysql_global_status_connection_errors_total{error="max_connections"}:由于超出最大连接数导致的错误;
  • mysql_global_status_connection_errors_total{error="internal"}:由于系统内部导致的错误;

通过PromQL查询当前剩余的可用连接数:

代码语言:javascript复制
mysql_global_variables_max_connections - mysql_global_status_threads_connected

使用PromQL查询当前MySQL实例连接拒绝数:

代码语言:javascript复制
mysql_global_status_aborted_connects

grafana模板

7362

0 人点赞