pt-variable-advisor
分析 MySQL 的 SHOW VARIABLES 输出,按一组规则给出变量配置的问题与改进建议。
语法
pt-variable-advisor [OPTIONS] [DSN]从本机 localhost 取 SHOW VARIABLES:
pt-variable-advisor localhost从已保存的 vars.txt 读取变量:
pt-variable-advisor --source-of-variables vars.txt安全提示
不要在命令行用 --password 提供 MySQL 密码:命令行密码对系统上所有用户可见,且会存入 ps 命令的采集输出。请使用 MySQL 选项文件或 --ask-pass。
用法示例
以下命令假定连接信息(账号/密码)已通过选项文件或本机 socket 配好,命令里只写 h=主机(必要时加 P=端口),不出现明文密码。命令可直接复制,替换其中的主机名即可。本工具只读 SHOW VARIABLES,不改任何配置。
场景:巡检一台远程实例
接手一台不熟悉的服务器时,直接对远程实例跑一遍,快速拿到它的参数隐患清单:
pt-variable-advisor h=db1.example.com,P=3306场景:忽略已知的无用告警
你明知服务器用了非默认端口、且密码策略已另有管控,不想被 port/old_passwords 这类 NOTE 反复刷屏,用 --ignore-rules 把对应规则 ID 跳过:
pt-variable-advisor h=db1 --ignore-rules port,old_passwords场景:看完整的改进说明
默认只打印每条规则的第一句话,排查重要隐患时加上 --verbose 打印完整描述,看清"为什么这么改":
pt-variable-advisor --verbose h=db1场景:导出快照后离线分析
不便直连生产机、或想在变更前后对比时,先在目标机把 SHOW VARIABLES 落盘,再离线分析:
mysql -e "SHOW VARIABLES" > vars.txt
pt-variable-advisor --source-of-variables vars.txt功能说明
工具检查 SHOW VARIABLES 中的变量值,按下面的 RULES 逐条匹配,把命中规则的变量与对应建议报出来,帮助你发现服务器上的不良设置。每条规则有三部分:ID(规则短名,同一变量多条规则用 -1、-2、-N 编号)、severity(NOTE/WARN/CRIT,即提示/警告/严重)、description(含义说明)。默认只打印每条规则描述的第一句话;提高 --verbose 会打印更多内容。
规则(RULES)
级别含义:NOTE=提示,WARN=警告,CRIT=严重。
| 规则 ID | 级别 | 含义 |
|---|---|---|
auto_increment | NOTE | 是否在双源/环复制里往多台服务器写同一表,这通常很危险且多为误用 |
concurrent_insert | NOTE | MyISAM 表因删除留下的空洞可能永远不会被复用 |
connect_timeout | NOTE | 该值过大可能造成拒绝服务(DoS)漏洞 |
debug | CRIT | 带调试能力编译的服务器不应上生产,性能影响很大 |
delay_key_write | WARN | MyISAM 索引块不到必要时不刷盘,服务器崩溃时 MyISAM 损坏可能比平时严重得多 |
flush | WARN | 该选项可能大幅降低性能 |
flush_time | WARN | 该设置可能每 flush_time 秒造成很差的性能;也可能大幅降低性能 |
have_bdb | NOTE | BDB 引擎已废弃,没用它就用 skip_bdb 关掉 |
init_connect | NOTE | 服务器启用了 init_connect |
init_file | NOTE | 服务器启用了 init_file |
init_slave | NOTE | 服务器启用了 init_slave |
init_replica | NOTE | 服务器启用了 init_replica |
innodb_additional_mem_pool_size | WARN | 该变量一般无需大于 20MB |
innodb_buffer_pool_size | WARN | InnoDB 缓冲池未显式配置;生产环境应显式配置,默认 10MB 不合适 |
innodb_checksums | WARN | InnoDB 校验和已关闭,数据不防硬件损坏等错误 |
innodb_doublewrite | WARN | InnoDB 双写已关闭,除非用防部分写文件系统否则数据不安全 |
innodb_fast_shutdown | WARN | InnoDB 关闭行为非默认,可能导致性能差或启动时需崩溃恢复 |
innodb_flush_log_at_trx_commit-1 | WARN | InnoDB 未设严格 ACID 模式,崩溃可能丢事务 |
innodb_flush_log_at_trx_commit-2 | WARN | 设为 0 相比 2 无性能收益且可能丢更多数据;为性能应从 1 改为 2 而非 0 |
innodb_force_recovery | WARN | InnoDB 处于强制恢复模式,只应临时用于数据损坏恢复,不可常态使用 |
innodb_lock_wait_timeout | WARN | 该值异常长,锁不释放时可能导致系统过载 |
innodb_log_buffer_size | WARN | InnoDB 日志缓冲一般不应大于 16MB;大 BLOB 操作本就不适合 InnoDB |
innodb_log_file_size | WARN | InnoDB 日志文件为默认值,生产系统不可用 |
innodb_max_dirty_pages_pct | NOTE | 该值低于默认,会过度刷盘、增加 I/O 负载 |
key_buffer_size | WARN | 键缓冲为默认值,对多数生产系统不合适,应大于默认 8MB |
large_pages | NOTE | 启用了大页 |
locked_in_memory | NOTE | 服务器用 --memlock 锁在内存中 |
log_warnings-1 | NOTE | log_warnings 关闭,异常事件(不安全复制语句、中断连接)不记入错误日志 |
log_warnings-2 | NOTE | log_warnings 须大于 1 才会记录中断连接等异常事件 |
low_priority_updates | NOTE | 服务器用了非默认更新锁优先级,可能使更新查询意外等待读查询 |
max_binlog_size | NOTE | max_binlog_size 小于默认 1GB |
max_connect_errors | NOTE | max_connect_errors 应设到平台允许的最大值 |
max_connections | WARN | 若真有上千线程在跑,系统花在调度线程上的时间多于干活,应结合负载评估 |
myisam_repair_threads | NOTE | myisam_repair_threads > 1 启用多线程修复,相对未经充分测试且仍属 beta |
old_passwords | WARN | 老式密码不安全,明文在网络上传输 |
optimizer_prune_level | WARN | 优化器对复杂查询用穷举搜索,规划可能很慢 |
port | NOTE | 服务器监听在非默认端口 |
query_cache_size-1 | NOTE | 查询缓存大于 128MB 难以扩展,多核机器上性能不稳定 |
query_cache_size-2 | WARN | 查询缓存大于 256MB 会造成严重性能问题,尤其多核机器 |
query_cache_size-3 | NOTE | 查询缓存启用就会造成严重性能问题,尤其高并发多核负载 |
read_buffer_size-1 | NOTE | read_buffer_size 一般应保持默认,除非专家判定要改 |
read_buffer_size-2 | WARN | read_buffer_size 不应大于 8MB;大于 2MB 会显著伤害性能甚至使服务器崩溃/疯狂交换/极不稳定 |
read_rnd_buffer_size-1 | NOTE | read_rnd_buffer_size 一般应保持默认,除非专家判定要改 |
read_rnd_buffer_size-2 | WARN | read_rnd_buffer_size 不应大于 4M,一般应保持默认 |
relay_log_space_limit | WARN | 设 relay_log_space_limit 会让从库立即停止从源抓 binlog,增加源崩溃时丢数据风险 |
slave_net_timeout | WARN | 该值过高,太久才发现到源的连接失败并重试;应设 60 秒或更小,建议用 pt-heartbeat 防止源空闲时误超时 |
replica_net_timeout | WARN | 同 slave_net_timeout:该值过高,应设 60 秒或更小,建议用 pt-heartbeat |
slave_skip_errors | CRIT | 不应设该选项;复制报错要查根因,从库数据可能已与源不一致,可用 pt-table-checksum 核查 |
replica_skip_errors | CRIT | 同 slave_skip_errors:不应设,复制报错用 pt-table-checksum 核查 |
sort_buffer_size-1 | NOTE | sort_buffer_size 一般应保持默认,除非专家判定要改 |
sort_buffer_size-2 | NOTE | sort_buffer_size 一般应保持默认;大于几 MB 会显著伤害性能甚至使服务器崩溃/疯狂交换/极不稳定 |
sql_notes | NOTE | 服务器配置为不把 Note 级警告记入错误日志 |
sync_frm | WARN | 最好设 sync_frm,使 .frm 文件在崩溃时安全刷盘 |
tx_isolation-1 | NOTE | 服务器事务隔离级别非默认 |
tx_isolation-2 | WARN | 多数应用应用默认 REPEATABLE-READ,少数情况 READ-COMMITTED |
expire_logs_days | WARN | 开了 binlog 但未启用自动清理,磁盘会写满;勿在 MySQL 外删 binlog,应让 MySQL 清理 |
innodb_file_io_threads | NOTE | 该选项除 Windows 外无用 |
innodb_data_file_path | NOTE | InnoDB 自动扩展文件可能占用难回收的大量磁盘;有人偏好 innodb_file_per_table 并为 ibdata1 分配定长文件 |
innodb_flush_method | NOTE | 多数用 InnoDB 的生产服务器应设 O_DIRECT 避免双缓冲,除非 I/O 性能很低 |
innodb_locks_unsafe_for_binlog | WARN | 该选项使基于语句的 binlog 下时间点恢复与复制不可信 |
innodb_support_xa | WARN | InnoDB 与 binlog 间内部 XA 支持已关,崩溃恢复后 binlog 可能与 InnoDB 状态不一致,复制可能因乱序语句漂移 |
log_bin | WARN | 未开 binlog,时间点恢复与复制均不可行 |
log_output | WARN | 把日志输出导向表性能影响很大 |
max_relay_log_size | NOTE | 定义了自定义 max_relay_log_size |
myisam_recover_options | WARN | myisam_recover_options 应设为如 BACKUP,FORCE 以确保注意到表损坏 |
storage_engine | NOTE | 服务器用非标准存储引擎作默认 |
sync_binlog | WARN | 开了 binlog 但未配 sync_binlog 让每事务刷盘以保证持久性 |
tmp_table_size | NOTE | 内部隐式内存临时表有效最小尺寸是 min(tmp_table_size, max_heap_table_size),故 max_heap_table_size 应至少与 tmp_table_size 一样大 |
old mysql version | WARN | 各 major 版本推荐最低版本:3.23、4.1.20、5.0.37、5.1.30、5.5.8、5.6.10、5.7.9、8.0.11(不报 Innovation 版本) |
end-of-life mysql version | NOTE | 8.0 之前的每个版本现已正式停止维护(EOL) |
选项
| 选项 | 说明 |
|---|---|
--ask-pass | 连接 MySQL 时交互式询问密码 |
--[no]buffer-stdout | 默认:yes。开启 STDOUT 缓冲;用 tee、kubectl logs 等后处理工具想看实时进度时关闭 |
-A, --charset | 类型:string。默认字符集(utf8 时设置 binmode/mysql_enable_utf8 并执行 SET NAMES UTF8) |
--config | 类型:Array。读取逗号分隔的配置文件列表;若指定必须放在命令行第一个选项 |
--daemonize | fork 到后台脱离 shell(仅 POSIX 系统) |
-D, --database | 类型:string。连接该数据库 |
-F, --defaults-file | 类型:string。只从该文件读 mysql 选项,必须绝对路径 |
--help | 显示帮助并退出 |
-h, --host | 类型:string。连接的主机 |
--ignore-rules | 类型:hash。忽略这些规则 ID(逗号分隔的规则 ID 列表) |
-s, --mysql_ssl | 类型:int。建立 SSL MySQL 连接 |
-p, --password | 类型:string。连接密码(含逗号需转义) |
--pid | 类型:string。创建给定 PID 文件;冲突规则与自动清理见官方文档 |
-P, --port | 类型:int。连接端口 |
--set-vars | 类型:Array。逗号分隔的 变量=值 设置 MySQL 变量;默认 wait_timeout=10000;设不上打印警告继续 |
-S, --socket | 类型:string。连接 socket 文件 |
--source-of-variables | 类型:string;默认:mysql。SHOW VARIABLES 的来源:mysql(须同时在命令行给 DSN)、none 或文件名 |
-u, --user | 类型:string。登录用户(若非当前用户) |
-v, --verbose | 累积:yes;默认:1。提高输出详细程度;默认只打印每条规则描述的第一句,更高层级打印更多 |
--version | 显示版本并退出 |
--[no]version-check | 默认:yes。检查 Percona Toolkit、MySQL 等最新版本与已知问题版本(详见版本检查) |
DSN 选项
| 键 | DSN 部分 | 说明 |
|---|---|---|
A | charset | 默认字符集 |
D | database | 默认数据库 |
F | mysql_read_default_file | 只从给定文件读取默认选项 |
h | host | 要连接的主机 |
p | password | 连接密码(含逗号需转义) |
P | port | 连接端口 |
S | mysql_socket | 连接使用的 socket 文件 |
u | user | 登录用户(若非当前用户) |
s | mysql_ssl | 建立 SSL 连接 |
其他信息
作者:Baron Schwartz 和 Daniel Nichter
通用说明:已知问题的反馈方式、PTDEBUG 调试安全提示、系统要求基线,见 通用说明。
更多细节请阅读 官方文档。