ProxySQL(七)—— MySQL 监控指南

目录

一、概述

二、通用统计表

[1. global_variables ------ 变量兼容](#1. global_variables —— 变量兼容)

[2. stats_memory_metrics ------ 内存使用监控](#2. stats_memory_metrics —— 内存使用监控)

[三、MySQL 统计表](#三、MySQL 统计表)

[1. stats_mysql_processlist ------ 实时查询监控](#1. stats_mysql_processlist —— 实时查询监控)

[2. stats_mysql_query_digest ------ 慢查询聚合分析](#2. stats_mysql_query_digest —— 慢查询聚合分析)

[3. stats_mysql_commands_counters ------ 命令类型统计](#3. stats_mysql_commands_counters —— 命令类型统计)

[4. stats_mysql_global ------ 全局指标](#4. stats_mysql_global —— 全局指标)

[5. stats_mysql_connection_pool ------ 后端连接池](#5. stats_mysql_connection_pool —— 后端连接池)

[6. stats_mysql_free_connections ------ 空闲连接详情](#6. stats_mysql_free_connections —— 空闲连接详情)

[7. stats_mysql_errors ------ 后端错误追踪](#7. stats_mysql_errors —— 后端错误追踪)

[8. stats_mysql_query_rules ------ 规则命中统计](#8. stats_mysql_query_rules —— 规则命中统计)

[9. stats_mysql_users ------ 用户连接统计](#9. stats_mysql_users —— 用户连接统计)

[10. stats_mysql_client_host_cache ------ 客户端失败缓存](#10. stats_mysql_client_host_cache —— 客户端失败缓存)

[11. stats_mysql_gtid_executed ------ GTID 执行追踪](#11. stats_mysql_gtid_executed —— GTID 执行追踪)

[12. stats_mysql_prepared_statements_info ------ 预处理语句](#12. stats_mysql_prepared_statements_info —— 预处理语句)

[四、DBA 日常监控](#四、DBA 日常监控)

[1. 进程状态监控(替代 SHOW PROCESSLIST)](#1. 进程状态监控(替代 SHOW PROCESSLIST))

[2. 慢查询监控](#2. 慢查询监控)

[3. 长时间运行查询监控](#3. 长时间运行查询监控)

[4. 事务监控](#4. 事务监控)

[5. 连接负载分布](#5. 连接负载分布)

[6. 后端健康监控](#6. 后端健康监控)

[7. 错误追踪](#7. 错误追踪)

[8. 连接池效率](#8. 连接池效率)

五、最佳实践

[1. 慢查询配置](#1. 慢查询配置)

(1)确认统计功能已启用

(2)设置慢查询阈值

(3)启用客户端地址追踪

[2. 告警阈值建议](#2. 告警阈值建议)

[3. 日常巡检 SQL 集合](#3. 日常巡检 SQL 集合)

六、常见问题(FAQ)

[七、MySQL 与 ProxySQL 监控对照表](#七、MySQL 与 ProxySQL 监控对照表)

八、总结

参考文档:


一、概述

ProxySQL 的 stats 库提供了两类统计表:

  • 通用统计表:与具体数据库协议无关的 ProxySQL 自身指标。
  • MySQL 统计表:针对 MySQL 流量的运行时统计,包括查询性能、连接池、后端健康、错误率等。

访问方式:所有统计表都需要连接 ProxySQL 管理端口(缺省6033),通过 stats. 前缀访问,例如:

sql 复制代码
SELECT * FROM stats.stats_mysql_processlist;

二、通用统计表

这些表涵盖了非特定于 MySQL、PostgreSQL 或 ProxySQL 集群的通用统计信息,为客户端库提供了一个兼容性适配层。它们展示了 ProxySQL 内部内存使用情况的视图,以及全局 TLS 和代理级别的指标。

1. global_variables ------ 变量兼容

用途:有些 MySQL 客户端(比如 PHP 的 PDO、Python 的 MySQLdb 等)在建立连接后,会习惯性地执行一句 SELECT @@max_allowed_packet 来确认服务端能接收多大的数据包,所以 ProxySQL 在 stats.global_variables 表里硬编码了这唯一的一行数据:

sql 复制代码
ProxySQL Admin> select * from stats.global_variables;
+--------------------------+----------------+
| variable_name            | variable_value |
+--------------------------+----------------+
| mysql-max_allowed_packet | 4194304        |
+--------------------------+----------------+
1 row in set (0.00 sec)

这是一个静态的"摆设",专门用来应付某些"一上来就查系统变量"的客户端,防止它们报错。表中的值没有意义。

表结构

sql 复制代码
CREATE TABLE global_variables (
    Variable_Name VARCHAR NOT NULL PRIMARY KEY,
    Variable_Value VARCHAR NOT NULL
)

2. stats_memory_metrics ------ 内存使用监控

此表显示 ProxySQL 内部各种结构的内存使用情况。目前只跟踪了少数结构:SQLite、认证模块、查询摘要。最重要的监控值是与 jemalloc(ProxySQL 内置的内存分配器)相关的值。

表结构

sql 复制代码
CREATE TABLE stats_memory_metrics (
    Variable_Name VARCHAR NOT NULL PRIMARY KEY,
    Variable_Value VARCHAR NOT NULL
)

Jemalloc 指标:

  • jemalloc_allocated: 应用程序分配的字节数

  • jemalloc_active: 应用程序分配的页面中的字节数

  • jemalloc_mapped: 分配器映射的扩展块中的字节数

  • jemalloc_metadata: 专用于元数据的字节数

  • jemalloc_resident: 分配器映射的物理驻留数据页面中的字节数

  • jemalloc_retained: 保留以供将来重用的虚拟内存映射中的字节数

其他内存指标:

  • Auth_memory: 认证模块用于存储用户凭证和属性的内存

  • SQLite3_memory_bytes: 嵌入式 SQLite 使用的内存

  • query_digest_memory: 用于存储与 stats_mysql_query_digest 相关数据的内存

  • mysql_query_rules_memory: 查询规则使用的内存

  • mysql_firewall_users_table: 防火墙用户查找表使用的内存

  • mysql_firewall_users_config: 防火墙用户配置使用的内存

  • mysql_firewall_rules_table: 防火墙规则查找表使用的内存

  • mysql_firewall_rules_config: 防火墙规则配置使用的内存

  • stack_memory_mysql_threads: MySQL 工作线程内存 * 栈大小

  • stack_memory_admin_threads: 管理连接内存 * 栈大小

  • stack_memory_cluster_threads: ProxySQL 集群线程内存 * 栈大小

三、MySQL 统计表

1. stats_mysql_processlist ------ 实时查询监控

用途 :提供当前 ProxySQL 连接正在执行的操作信息,相当于 MySQL 的 SHOW PROCESSLIST

表结构

sql 复制代码
CREATE TABLE stats.stats_mysql_processlist (
    ThreadID INT NOT NULL,
    SessionID INTEGER PRIMARY KEY,
    user VARCHAR,
    db VARCHAR,
    cli_host VARCHAR,
    cli_port VARCHAR,
    hostgroup VARCHAR,
    l_srv_host VARCHAR,
    l_srv_port VARCHAR,
    srv_host VARCHAR,
    srv_port VARCHAR,
    command VARCHAR,
    time_ms INT NOT NULL,
    info VARCHAR,
    status_flags INT,
    extended_info VARCHAR
);

字段语义

字段 说明
ThreadID ProxySQL 内部线程 ID(从 0 开始编号)
SessionID 会话全局唯一标识符,可用于 KILL 连接
user 客户端连接 ProxySQL 使用的 MySQL 用户名
db 当前选中的 schema
cli_host / cli_port 客户端与 ProxySQL 之间的 TCP 连接地址
hostgroup 当前主机组(查询路由的目标)
srv_host / srv_port 后端 MySQL 服务器地址
command 正在执行的 MySQL 命令类型
time_ms 当前命令状态已持续的毫秒数
info 实际执行的查询文本
extended_info JSON 对象,包含详细的连接和会话信息(autocommit、charset、transaction 状态等)

提示 :ProxySQL 也支持 SHOW PROCESSLISTSHOW FULL PROCESSLIST 命令。

2. stats_mysql_query_digest ------ 慢查询聚合分析

用途这是慢查询监控的核心表 。基于 SQL 指纹(参数替换为 ?)聚合统计,用于识别慢查询模式和优化目标。ProxySQL 会把结构相同、但参数值不同的 SQL 语句归为同一类来统计。"SQL 指纹" 就是把 SQL 语句里的具体数值去掉,替换成 ?,只保留它的"骨架"。

表结构

sql 复制代码
CREATE TABLE stats.stats_mysql_query_digest (
    hostgroup INT,
    schemaname VARCHAR NOT NULL,
    username VARCHAR NOT NULL,
    client_address VARCHAR NOT NULL,
    digest VARCHAR NOT NULL,
    digest_text VARCHAR NOT NULL,
    count_star INTEGER NOT NULL,
    first_seen INTEGER NOT NULL,
    last_seen INTEGER NOT NULL,
    sum_time INTEGER NOT NULL,
    min_time INTEGER NOT NULL,
    max_time INTEGER NOT NULL,
    sum_rows_affected INTEGER NOT NULL,
    sum_rows_sent INTEGER NOT NULL,
    PRIMARY KEY(hostgroup, schemaname, username, client_address, digest)
);

字段语义

字段 说明
hostgroup 查询发送的目标主机组;-1 表示查询缓存命中
schemaname 被查询的 schema
username 客户端连接 ProxySQL 使用的用户名
client_address 客户端地址(需启用 mysql-query_digests_track_hostname=true
digest 十六进制哈希,唯一标识参数化后的查询模式
digest_text 参数化后的查询文本(参数替换为 ?
count_star 执行总次数
first_seen / last_seen Unix 时间戳,首次/最后看到的时间
sum_time 总执行时间(微秒
min_time / max_time 最小/最大执行时间(微秒)
sum_rows_affected 影响的总行数
sum_rows_sent 发送给客户端的总行数(不含查询缓存)

重要 :表中的时间是从 ProxySQL 接收到客户端查询,到 ProxySQL 准备好向客户端发送结果之间的时间。包含了 charset 变更、schema 切换、等待连接、后端故障转移等所有开销,最接近客户端感知的延迟

启用条件 :需要 mysql-commands_statsmysql-query_digests 均为 true(默认启用,建议不要禁用)。

3. stats_mysql_commands_counters ------ 命令类型统计

用途:按 SQL 命令类型(SELECT、INSERT、UPDATE 等)分类统计,并按执行时间分桶。

表结构

sql 复制代码
CREATE TABLE stats.stats_mysql_commands_counters (
    Command VARCHAR NOT NULL,
    Total_Time_us INT NOT NULL,
    Total_cnt INT NOT NULL,
    cnt_100us INT NOT NULL,
    cnt_500us INT NOT NULL,
    cnt_1ms INT NOT NULL,
    cnt_5ms INT NOT NULL,
    cnt_10ms INT NOT NULL,
    cnt_50ms INT NOT NULL,
    cnt_100ms INT NOT NULL,
    cnt_500ms INT NOT NULL,
    cnt_1s INT NOT NULL,
    cnt_5s INT NOT NULL,
    cnt_10s INT NOT NULL,
    cnt_INFs INT NOT NULL,
    PRIMARY KEY(Command)
);

字段语义

字段 说明
Command SQL 命令类型(如 SELECT、INSERT、UPDATE、FLUSH、KILL 等)
Total_Time_us 该类命令总耗时(微秒)
Total_cnt 执行总次数
cnt_100us 在 100 微秒内完成的次数
cnt_500us 在 100-500 微秒内完成的次数
... 以此类推,直到 cnt_10s
cnt_INFs 执行时间超过 10 秒的次数

注意 :统计需要 mysql-commands_stats=true(默认启用),建议不要禁用

4. stats_mysql_global ------ 全局指标

用途:最重要的统计表之一,导出 ProxySQL 内部的各种全局计数器。

表结构

sql 复制代码
CREATE TABLE stats.stats_mysql_global (
    Variable_Name VARCHAR NOT NULL PRIMARY KEY,
    Variable_Value VARCHAR NOT NULL
);

关键指标分类

运行时间和连接

指标 说明
ProxySQL_Uptime ProxySQL 运行秒数
Active_Transactions 当前正在处理事务的客户端连接数
Client_Connections_connected 当前连接的客户端数
Client_Connections_created 累计创建的客户端连接数
Client_Connections_aborted 失败或异常关闭的客户端连接数
Server_Connections_connected 当前后端连接数
Server_Connections_created 累计创建的后端连接数

查询统计

指标 说明
Questions 客户端请求/语句总数
Slow_queries 超过 mysql-long_query_time 毫秒的慢查询数
Queries_backends_bytes_sent 发送给后端的字节总数
Queries_backends_bytes_recv 从后端接收的字节总数

连接池

指标 说明
ConnPool_get_conn_success 从连接池成功获取连接的次数
ConnPool_get_conn_failure 从连接池获取连接失败的次数
ConnPool_get_conn_immediate 从本地连接池缓存立即获取的连接数

预处理语句

指标 说明
Com_frontend_stmt_prepare 客户端执行的 PREPARE 数量
Com_frontend_stmt_execute 客户端执行的 EXECUTE 数量
Stmt_Client_Active_Total 客户端正在使用的预处理语句总数
Stmt_Client_Active_Unique 客户端正在使用的唯一预处理语句数
Stmt_Cached ProxySQL 缓存了元数据的全局预处理语句数

查询缓存

指标 说明
Query_Cache_Memory_bytes 查询缓存使用的内存
Query_Cache_Entries 查询缓存中的条目数
Query_Cache_count_GET 查询缓存的读请求次数
Query_Cache_count_GET_OK 查询缓存读请求成功的次数

监控健康

指标 说明
MySQL_Monitor_connect_check_OK/ERR 连接检查成功/失败次数
MySQL_Monitor_ping_check_OK/ERR Ping 检查成功/失败次数
MySQL_Monitor_read_only_check_OK/ERR 只读检查成功/失败次数

错误与拒绝

指标 说明
Access_Denied_Max_Connections 因达到最大连接数被拒绝的连接数
Access_Denied_Max_User_Connections 因达到用户级最大连接数被拒绝的连接数
Access_Denied_Wrong_Password 因密码错误被拒绝的连接数

5. stats_mysql_connection_pool ------ 后端连接池

用途:导出后端服务器的连接池统计,包括连接使用情况、查询量和延迟。

表结构

sql 复制代码
CREATE TABLE stats.stats_mysql_connection_pool (
    hostgroup VARCHAR,
    srv_host VARCHAR,
    srv_port VARCHAR,
    status VARCHAR,
    ConnUsed INT,
    ConnFree INT,
    ConnOK INT,
    ConnERR INT,
    MaxConnUsed INT,
    Queries INT,
    Queries_GTID_sync INT,
    Bytes_data_sent INT,
    Bytes_data_recv INT,
    Latency_us INT
);

字段语义

字段 说明
hostgroup 后端服务器所属主机组
status 后端状态:ONLINESHUNNEDOFFLINE_SOFTOFFLINE_HARD
ConnUsed 当前正在使用的连接数
ConnFree 连接池中保持的空闲连接数
ConnOK 成功建立的总连接数
ConnERR 失败的连接尝试总数
MaxConnUsed 同时使用的连接数历史峰值
Queries 路由到该后端的查询总数
Latency_us Monitor 报告的当前 ping 延迟(微秒)

6. stats_mysql_free_connections ------ 空闲连接详情

用途:提供连接池中每个空闲连接的详细信息。

表结构

sql 复制代码
CREATE TABLE stats.stats_mysql_free_connections (
    fd INT NOT NULL,
    hostgroup INT NOT NULL,
    srv_host VARCHAR NOT NULL,
    srv_port INT NOT NULL,
    user VARCHAR NOT NULL,
    schema VARCHAR,
    init_connect VARCHAR,
    time_zone VARCHAR,
    sql_mode VARCHAR,
    autocommit VARCHAR,
    idle_ms INT,
    statistics VARCHAR,
    mysql_info VARCHAR
);

关键字段fd(文件描述符)、userschemaidle_ms(空闲毫秒数)

7. stats_mysql_errors ------ 后端错误追踪

用途:追踪后端服务器在查询执行期间报告的错误,按错误号聚合。

表结构

sql 复制代码
CREATE TABLE stats.stats_mysql_errors (
    hostgroup INT NOT NULL,
    hostname VARCHAR NOT NULL,
    port INT NOT NULL,
    username VARCHAR NOT NULL,
    client_address VARCHAR NOT NULL,
    schemaname VARCHAR NOT NULL,
    errno INT NOT NULL,
    count_star INTEGER NOT NULL,
    first_seen INTEGER NOT NULL,
    last_seen INTEGER NOT NULL,
    last_error VARCHAR NOT NULL DEFAULT '',
    PRIMARY KEY (hostgroup, hostname, port, username, schemaname, errno)
);

关键字段hostnameerrnocount_starlast_error

8. stats_mysql_query_rules ------ 规则命中统计

用途:显示每条查询规则匹配流量的次数。

表结构

sql 复制代码
CREATE TABLE stats.stats_mysql_query_rules (
    rule_id INTEGER PRIMARY KEY,
    hits INT NOT NULL
);

注意hits 值在每次 LOAD MYSQL QUERY RULES TO RUNTIME 时重置。

9. stats_mysql_users ------ 用户连接统计

用途:报告用户的当前前端连接数和允许的最大连接数。

表结构

sql 复制代码
CREATE TABLE stats.stats_mysql_users (
    username VARCHAR PRIMARY KEY,
    frontend_connections INT NOT NULL,
    frontend_max_connections INT NOT NULL
);

10. stats_mysql_client_host_cache ------ 客户端失败缓存

用途 :记录客户端连接失败的记录(需启用 mysql-client_host_cache_size > 0)。

表结构

sql 复制代码
CREATE TABLE stats.stats_mysql_client_host_cache (
    client_address VARCHAR NOT NULL,
    error_count INT NOT NULL,
    last_updated BIGINT NOT NULL
);

11. stats_mysql_gtid_executed ------ GTID 执行追踪

用途:提供后端节点上 GTID 执行情况,用于一致性读路由。

表结构

sql 复制代码
CREATE TABLE stats.stats_mysql_gtid_executed (
    hostname VARCHAR NOT NULL,
    port INT NOT NULL DEFAULT 3306,
    gtid_executed VARCHAR,
    events INT NOT NULL
);

12. stats_mysql_prepared_statements_info ------ 预处理语句

用途:提供跨客户端和后端连接的预处理语句全局映射信息。

表结构

sql 复制代码
CREATE TABLE stats.stats_mysql_prepared_statements_info (
    global_stmt_id INT NOT NULL,
    hostgroup INT NOT NULL,
    schemaname VARCHAR NOT NULL,
    username VARCHAR NOT NULL,
    digest VARCHAR NOT NULL,
    ref_count_client INT NOT NULL,
    ref_count_server INT NOT NULL,
    num_columns INT NOT NULL,
    num_params INT NOT NULL,
    query VARCHAR NOT NULL
);

关键字段global_stmt_idref_count_clientref_count_server

四、DBA 日常监控

1. 进程状态监控(替代 SHOW PROCESSLIST)

MySQL 原生命令

sql 复制代码
SELECT state, COUNT(*) FROM information_schema.processlist GROUP BY state;

ProxySQL 等效实现

sql 复制代码
-- 按 command 分组统计
SELECT command, COUNT(*) AS count 
FROM stats.stats_mysql_processlist 
GROUP BY command;

-- 查看活跃查询(排除 Sleep)
SELECT command, COUNT(*) AS active_count
FROM stats.stats_mysql_processlist
WHERE command != 'Sleep'
GROUP BY command;

2. 慢查询监控

sql 复制代码
-- 查看慢查询总数
SELECT variable_name, variable_value 
FROM stats.stats_mysql_global 
WHERE variable_name = 'Slow_queries';

-- 按总耗时排序的 TOP 慢查询
SELECT 
    digest_text,
    count_star AS exec_count,
    ROUND(sum_time/1000000, 2) AS total_sec,
    ROUND((sum_time/count_star)/1000, 2) AS avg_ms,
    ROUND(max_time/1000, 2) AS max_ms
FROM stats.stats_mysql_query_digest
WHERE count_star > 0
ORDER BY sum_time DESC
LIMIT 10;

-- 按平均延迟排序的慢查询
SELECT 
    digest_text,
    count_star,
    ROUND((sum_time/count_star)/1000, 2) AS avg_ms
FROM stats.stats_mysql_query_digest
WHERE count_star > 0
ORDER BY avg_ms DESC
LIMIT 10;

3. 长时间运行查询监控

sql 复制代码
-- 执行时间超过 10 秒的查询
SELECT SessionID, user, db, command, time_ms, SUBSTR(info, 1, 200) AS query
FROM stats.stats_mysql_processlist
WHERE command != 'Sleep' AND time_ms > 10000
ORDER BY time_ms DESC;

-- 执行时间 TOP 10
SELECT SessionID, user, db, time_ms, SUBSTR(info, 1, 200) AS query
FROM stats.stats_mysql_processlist
WHERE command != 'Sleep'
ORDER BY time_ms DESC
LIMIT 10;

4. 事务监控

sql 复制代码
-- 查看当前正在执行的事务
SELECT SessionID, user, db, time_ms,
       JSON_EXTRACT(extended_info, '$.conn.autocommit') AS autocommit,
       JSON_EXTRACT(extended_info, '$.conn.status.transaction') AS in_transaction,
       SUBSTR(info, 1, 100) AS query
FROM stats.stats_mysql_processlist
WHERE JSON_EXTRACT(extended_info, '$.conn.status.transaction') = true;

-- 查看 autocommit=0 的连接(可能的长事务)
SELECT SessionID, user, db, time_ms,
       JSON_EXTRACT(extended_info, '$.conn.autocommit') AS autocommit
FROM stats.stats_mysql_processlist
WHERE JSON_EXTRACT(extended_info, '$.conn.autocommit') = 'false';

5. 连接负载分布

sql 复制代码
-- 按用户分组统计连接数
SELECT user, COUNT(*) AS connections
FROM stats.stats_mysql_processlist
GROUP BY user
ORDER BY connections DESC;

-- 按后端服务器分组统计
SELECT srv_host, srv_port, COUNT(*) AS backend_connections
FROM stats.stats_mysql_processlist
WHERE srv_host IS NOT NULL
GROUP BY srv_host, srv_port;

6. 后端健康监控

sql 复制代码
-- 查看后端服务器状态
SELECT hostgroup, srv_host, status, ConnUsed, ConnFree, ConnERR, Latency_us
FROM stats.stats_mysql_connection_pool
ORDER BY status DESC, Latency_us DESC;

-- 查看被 SHUNNED 的后端
SELECT hostgroup, srv_host, status, ConnERR
FROM stats.stats_mysql_connection_pool
WHERE status = 'SHUNNED';

7. 错误追踪

sql 复制代码
-- 最常见的后端错误
SELECT hostgroup, hostname, errno, count_star, last_error
FROM stats.stats_mysql_errors
ORDER BY count_star DESC
LIMIT 10;

-- 特定错误类型查询
SELECT * FROM stats.stats_mysql_errors WHERE errno = 1045;

8. 连接池效率

sql 复制代码
-- 连接池命中率
SELECT 
    (SELECT variable_value FROM stats.stats_mysql_global 
     WHERE variable_name='ConnPool_get_conn_success') AS pool_hits,
    (SELECT variable_value FROM stats.stats_mysql_global 
     WHERE variable_name='ConnPool_get_conn_failure') AS pool_misses,
    ROUND(100 * (SELECT variable_value FROM stats.stats_mysql_global 
          WHERE variable_name='ConnPool_get_conn_success') / 
          NULLIF((SELECT variable_value FROM stats.stats_mysql_global 
          WHERE variable_name='ConnPool_get_conn_success') + 
                 (SELECT variable_value FROM stats.stats_mysql_global 
          WHERE variable_name='ConnPool_get_conn_failure'), 0), 2) AS hit_rate_pct;

-- 连接复用率(前端连接数 vs 后端连接数)
SELECT 
    (SELECT variable_value FROM stats.stats_mysql_global 
     WHERE variable_name='Client_Connections_connected') AS frontend,
    (SELECT variable_value FROM stats.stats_mysql_global 
     WHERE variable_name='Server_Connections_connected') AS backend,
    ROUND(100 * (SELECT variable_value FROM stats.stats_mysql_global 
          WHERE variable_name='Server_Connections_connected') / 
          NULLIF((SELECT variable_value FROM stats.stats_mysql_global 
          WHERE variable_name='Client_Connections_connected'), 0), 2) AS reuse_ratio;

五、最佳实践

1. 慢查询配置

(1)确认统计功能已启用

sql 复制代码
SELECT variable_name, variable_value FROM global_variables 
WHERE variable_name IN ('mysql-commands_stats', 'mysql-query_digests');
-- 期望均为 'true'

(2)设置慢查询阈值

sql 复制代码
-- 默认 1000 毫秒 = 1 秒,调整为 500 毫秒
UPDATE global_variables SET variable_value='500' WHERE variable_name='mysql-long_query_time';
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;

(3)启用客户端地址追踪

sql 复制代码
UPDATE global_variables SET variable_value='true' WHERE variable_name='mysql-query_digests_track_hostname';
LOAD MYSQL VARIABLES TO RUNTIME;

2. 告警阈值建议

监控项 建议阈值 告警含义 来源表
Client_Connections_aborted 增量 >100/分钟 客户端连接异常 stats_mysql_global
ConnPool_get_conn_failure 比例 >5% 连接池不足或后端故障 stats_mysql_global
后端 Latency_us >10000 (10ms) 网络或后端响应慢 stats_mysql_connection_pool
后端 status = SHUNNED 任何 后端被临时屏蔽 stats_mysql_connection_pool
Slow_queries 增量 >10/分钟 存在慢查询 stats_mysql_global
Access_Denied_* 增量 >5/分钟 可能存在攻击或配置错误 stats_mysql_global
query_digest_memory >500MB 查询摘要占用内存过高 stats_memory_metrics
MySQL_Monitor_*_ERR 增量 >0 健康检查失败 stats_mysql_global

3. 日常巡检 SQL 集合

sql 复制代码
-- ============================================================
-- ProxySQL 2.6.5 每日巡检 SQL
-- ============================================================

-- 1. 系统概览
SELECT 
    MAX(CASE WHEN Variable_Name = 'ProxySQL_Uptime' THEN Variable_Value END) AS uptime_sec,
    MAX(CASE WHEN Variable_Name = 'Client_Connections_connected' THEN Variable_Value END) AS frontend_conns,
    MAX(CASE WHEN Variable_Name = 'Server_Connections_connected' THEN Variable_Value END) AS backend_conns,
    MAX(CASE WHEN Variable_Name = 'Questions' THEN Variable_Value END) AS total_queries,
    MAX(CASE WHEN Variable_Name = 'Slow_queries' THEN Variable_Value END) AS slow_queries
FROM stats.stats_mysql_global
WHERE Variable_Name IN ('ProxySQL_Uptime', 'Client_Connections_connected', 
                        'Server_Connections_connected', 'Questions', 'Slow_queries');

-- 2. 进程状态分组
SELECT COALESCE(command, 'Unknown') AS state, COUNT(*) AS count
FROM stats.stats_mysql_processlist
GROUP BY command
ORDER BY count DESC;

-- 3. 长时间运行查询(超过 10 秒)
SELECT SessionID, user, db, time_ms, SUBSTR(info, 1, 200) AS query
FROM stats.stats_mysql_processlist
WHERE command != 'Sleep' AND time_ms > 10000
ORDER BY time_ms DESC;

-- 4. 当前事务列表
SELECT SessionID, user, db, time_ms,
       JSON_EXTRACT(extended_info, '$.conn.autocommit') AS autocommit,
       JSON_EXTRACT(extended_info, '$.conn.status.transaction') AS in_transaction
FROM stats.stats_mysql_processlist
WHERE JSON_EXTRACT(extended_info, '$.conn.status.transaction') = true;

-- 5. 连接负载分布(按用户)
SELECT user, COUNT(*) AS connections
FROM stats.stats_mysql_processlist
GROUP BY user
ORDER BY connections DESC;

-- 6. 后端服务器健康状态
SELECT hostgroup, srv_host, status, ConnUsed, ConnFree, ConnERR, Latency_us
FROM stats.stats_mysql_connection_pool
ORDER BY status DESC, Latency_us DESC;

-- 7. 慢查询统计 TOP 5
SELECT digest_text,
       count_star AS exec_count,
       ROUND(sum_time/1000000, 2) AS total_sec,
       ROUND((sum_time/count_star)/1000, 2) AS avg_ms
FROM stats.stats_mysql_query_digest
WHERE count_star > 0
ORDER BY sum_time DESC
LIMIT 5;

-- 8. 错误统计 TOP 5
SELECT hostgroup, hostname, errno, count_star, last_error
FROM stats.stats_mysql_errors
ORDER BY count_star DESC
LIMIT 5;

-- 9. 连接池效率
SELECT 
    (SELECT variable_value FROM stats.stats_mysql_global WHERE variable_name='ConnPool_get_conn_success') AS pool_hits,
    (SELECT variable_value FROM stats.stats_mysql_global WHERE variable_name='ConnPool_get_conn_failure') AS pool_misses,
    ROUND(100 * (SELECT variable_value FROM stats.stats_mysql_global WHERE variable_name='ConnPool_get_conn_success') / 
          NULLIF((SELECT variable_value FROM stats.stats_mysql_global WHERE variable_name='ConnPool_get_conn_success') + 
                 (SELECT variable_value FROM stats.stats_mysql_global WHERE variable_name='ConnPool_get_conn_failure'), 0), 2) AS hit_rate_pct;

-- 10. 内存使用概览
SELECT variable_name, variable_value
FROM stats.stats_memory_metrics
WHERE variable_name IN ('SQLite3_memory_bytes', 'query_digest_memory', 
                        'jemalloc_active', 'stack_memory_mysql_threads');

六、常见问题(FAQ)

Q1: 查询 stats_mysql_query_digest 没有数据?

检查步骤

  1. 确认有查询流量经过 ProxySQL

  2. 检查变量:

    sql 复制代码
    SELECT variable_value FROM global_variables 
    WHERE variable_name IN ('mysql-commands_stats', 'mysql-query_digests');

    两者都应为 true

  3. 若刚启动,等待几秒让数据积累

Q2: stats_mysql_processlist 中的 time_ms 单位是什么?

:毫秒(milliseconds)。

Q3: 如何 KILL 一个卡住的查询?

:先从 stats_mysql_processlist 获取 SessionID,然后执行:

sql 复制代码
KILL CONNECTION <SessionID>;

Q4: stats_mysql_query_digest 中的 sum_time 单位是什么?

:微秒(microseconds)。除以 1,000,000 得秒,除以 1,000 得毫秒。

Q5: 如何在不重启 ProxySQL 的情况下重置统计?

:使用各个 _reset 表:

sql 复制代码
SELECT * FROM stats.stats_mysql_query_digest_reset;
SELECT * FROM stats.stats_mysql_connection_pool_reset;
SELECT * FROM stats.stats_mysql_errors_reset;

注意stats_mysql_global 没有 _reset 表,需要重启才能完全重置。

Q6: 慢查询统计中 hostgroup = -1 表示什么?

:表示该查询是从查询缓存(Query Cache)中命中的,没有实际发送到后端服务器。

Q7: 2.6.5 版本中 stats_proxysql_globalstats_tls_certificates 表存在吗?

不存在。这两个表是在 ProxySQL 3.0.7 版本中引入的。

Q8: ProxySQL 能否监控锁等待?

:不能直接监控。ProxySQL 不提供锁等待信息(锁信息在后端 MySQL 中)。建议:

  • 通过 ProxySQL 路由到后端 MySQL 查询 information_schema.INNODB_TRX

  • 或直接连接后端 MySQL 查看 SHOW ENGINE INNODB STATUS

Q9: 为什么 Com_backend_stmt_close 始终为 0?

:在当前实现中,ProxySQL 从不主动关闭预处理语句(关闭需要网络往返,效率低下)。当后端连接达到 mysql-max_stmts_per_connection 并归还到连接池被重置时,会隐式关闭所有预处理语句。

Q10: 如何查询 stats 库中的表?

:使用 SELECT * FROM stats.表名 的格式,例如:

sql 复制代码
SELECT * FROM stats.stats_mysql_processlist;

七、MySQL 与 ProxySQL 监控对照表

监控目的 MySQL 原生命令 ProxySQL 2.6.5 等效命令
查看当前连接 SHOW PROCESSLIST SELECT * FROM stats.stats_mysql_processlist
按状态分组 SELECT state,COUNT(*) FROM information_schema.processlist GROUP BY state SELECT command,COUNT(*) FROM stats.stats_mysql_processlist GROUP BY command
慢查询数量 SHOW GLOBAL STATUS LIKE 'Slow_queries' SELECT * FROM stats.stats_mysql_global WHERE variable_name='Slow_queries'
连接数 SHOW GLOBAL STATUS LIKE 'Threads_connected' SELECT * FROM stats.stats_mysql_global WHERE variable_name='Client_Connections_connected'
查询计数器 SHOW GLOBAL STATUS LIKE 'Questions' SELECT * FROM stats.stats_mysql_global WHERE variable_name='Questions'
用户连接分布 SELECT user,COUNT(*) FROM information_schema.processlist GROUP BY user SELECT user,COUNT(*) FROM stats.stats_mysql_processlist GROUP BY user
运行时间最长查询 SELECT * FROM information_schema.processlist ORDER BY time DESC SELECT * FROM stats.stats_mysql_processlist ORDER BY time_ms DESC
后端延迟 SHOW SLAVE STATUS 中的 Seconds_Behind_Master SELECT Latency_us FROM stats.stats_mysql_connection_pool
全局状态 SHOW GLOBAL STATUS SELECT * FROM stats.stats_mysql_global
内存使用 SHOW VARIABLES LIKE 'innodb_buffer_pool_size' SELECT * FROM stats.stats_memory_metrics

八、总结

ProxySQL 2.6.5 的 stats 库提供了全面的 MySQL 流量监控能力:

监控需求 使用表
实时查询 stats_mysql_processlist
慢查询分析 stats_mysql_query_digest
命令类型分布 stats_mysql_commands_counters
全局指标 stats_mysql_global
连接池健康 stats_mysql_connection_poolstats_mysql_free_connections
错误追踪 stats_mysql_errors
规则命中 stats_mysql_query_rules
用户连接限制 stats_mysql_users
内存监控 stats_memory_metrics
GTID 一致性 stats_mysql_gtid_executed
预处理语句 stats_mysql_prepared_statements_info

建议将 [3. 日常巡检 SQL 集合](#3. 日常巡检 SQL 集合) 的 SQL 纳入自动化监控系统,以便及时发现和定位问题。

参考文档:

  1. General Stats Tables --- ProxySQL Documentation
  2. MySQL Stats Tables --- ProxySQL Documentation
相关推荐
wzy06231 天前
ProxySQL(四)—— 基准测试
基准测试·proxysql
wzy06232 天前
ProxySQL(五)—— 代理多组独立的 MySQL 主从实例
proxysql
wzy06236 天前
ProxySQL(三)—— 数据分片
分库分表·proxysql·sharding
wzy06237 天前
ProxySQL(二)—— 实现 MySQL 主从自动失败切换
proxysql·主从自动切换
wzy06238 天前
ProxySQL(一)—— 实现 MySQL 读写分离、读负载均衡
负载均衡·读写分离·proxysql
ldj202024 天前
ProxySQL 代理Mysql实现读写分离
读写分离·主从同步·proxysql
散修-小胖子3 个月前
ProxySQL编译报错
mysql·proxysql
號先生1 年前
ProxySQL构建PolarDB-X标准版高可用路由服务三节点集群
proxysql·polardbx·polardbx集群·高可用路由
小时候的阳光2 年前
Docker方式部署ProxySQL和Keepalived组合实现MGR的高可用访问
mysql·docker·keepalived·mgr·proxysql