能设,但需分版本和部署方式:5.7.21+/8.0.14+支持会话级设置,但日志判定仍依赖启动时全局值;云RDS可直接控制台单独配置;自建多实例须按实例拆配my.cnf并显式指定。
MySQL 慢查询日志里 long_query_time 不能按实例单独设?
能设,但得看版本和部署方式。5.7.21+ 和 8.0.14+ 支持会话级 long_query_time,但慢查询日志本身仍是全局开关;真正要实现“每台服务器独立阈值”,必须绕开日志文件路径统一、mysqld 进程共用配置的惯性思维。
- 如果用的是云厂商托管 RDS(如阿里云、腾讯云),直接在控制台为每个实例单独配
slow_query_log和long_query_time,底层已隔离 - 如果是自建 MySQL,且多个实例跑在同一台物理机上(多端口/多 socket),
my.cnf必须按实例拆成多个配置文件,启动时用--defaults-file=/etc/my3307.cnf显式指定 - 别信“改完
SET GLOBAL long_query_time = 2就生效”——它只影响新连接,且不写入日志的判定逻辑仍依赖启动时读取的全局值(尤其 5.6 及更早)
用 pt-query-digest 做事后分析时如何区分不同服务器?
关键不在解析命令本身,而在日志采集阶段就打上实例标识。否则所有日志混在一起,pt-query-digest 再强也分不清哪条是主库慢、哪条是报表从库慢。
- 采集脚本里加
--filter '$event->{server_id} = "db-prod-01",或用--filter '$event->{hostname} = "10.20.30.41",确保每条日志带来源标记 - 避免直接 tail 多个
slow.log合并到一个文件——pt-query-digest会把时间戳错乱的记录误判为“超长执行”,导致阈值漂移 - 若用 Prometheus +
mysqld_exporter,确认每个 target 的labels包含instance="db-shard-a:3307",报警规则里用mysql_global_status_slow_queries{instance=~"db-.*"}才能按需聚合
Prometheus 报警规则里怎么写“不同服务器不同 long_query_time”?
不能硬编码数字,得靠标签继承 + recording rule 预计算。直接在 alert.rules 里写 mysql_global_status_slow_queries > 5 是无效的——这个指标本身不带耗时维度,它只是计数。
- 先定义 recording rule:
mysql_slow_queries_per_sec{instance, job} = rate(mysql_global_status_slow_queries{job="mysql"}[5m]) - 再基于业务角色打标:给 db-shard-a 加 label
slow_threshold="1s",db-report 加slow_threshold="5s",通过 service discovery 或 static config 注入 - 报警表达式写成:
mysql_slow_queries_per_sec > on(instance) group_left(slow_threshold) mysql_slow_threshold{job="mysql"},让 Prometheus 自动按实例匹配阈值
为什么改了 long_query_time 却没看到新慢查询进日志?
最常见原因是没关掉 log_queries_not_using_indexes 干扰,或者 SQL 里用了 SQL_NO_CACHE / SELECT SLEEP(1) 这类被 MySQL 特殊处理的语句。
- 检查当前生效值:
SELECT @@global.long_query_time, @@session.long_query_time;,注意 session 级设置对日志无影响 - 确认日志开关真开了:
SELECT @@global.slow_query_log;,有些环境默认 OFF,SET GLOBAL slow_query_log = ON后还要重启客户端才触发重连 - MySQL 8.0+ 默认用系统变量
log_output = 'FILE',但如果设成了'TABLE',就得查mysql.slow_log表,且该表默认不启用索引,查起来反而慢
阈值差异化不是加个配置就能跑通的事,核心在于采集链路是否保真、标签是否贯穿全链路、以及你用的到底是日志原始事件还是导出后的聚合指标——这三个地方漏一个,报警就变成随机事件。










