MySQL 调试环境不是装个客户端就行,核心是让 SQL 执行过程“看得见、停得住、改得动”。重点不在安装,而在开启日志、连接可控、语句可复现。
启用 general_log 查看每条执行语句
这是排查“SQL 没走预期逻辑”最直接的手段。它记录所有到达 MySQL 服务端的语句(含连接、断开),但默认关闭,且开启后有明显性能损耗,仅限本地调试或低流量环境。
general_log必须设为
ON,且
general_log_file指向可写的路径(如
/tmp/mysql-general.log) 动态开启命令:
SET GLOBAL general_log = ON; SET GLOBAL general_log_file = '/tmp/mysql-general.log';注意:重启 MySQL 后失效,如需持久化,需在
my.cnf的
[mysqld]段添加:
general_log = ON general_log_file = /tmp/mysql-general.log日志里会混入连接/断开信息,用
SELECT、
UPDATE等关键字过滤更高效
用 slow_query_log 定位执行慢的语句
当用户反馈“页面卡”,但不知道哪条 SQL 慢时,这个日志比猜更有用。它不记录所有语句,只记录超过
long_query_time(默认 10 秒)的查询,可调低到
0.1秒用于调试。 开启方式:
SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 0.1; SET GLOBAL slow_query_log_file = '/tmp/mysql-slow.log';关键点:
log_queries_not_using_indexes设为
ON可暴露缺失索引的查询,但会产生大量日志,调试初期建议先关着 注意:该日志不记录参数化查询中的实际值(如
WHERE id = ?),只记问号,所以需配合应用层日志或
general_log看真实参数
连接调试环境必须用 --protocol=tcp
本地开发常直连
localhost,但 MySQL 默认会走 socket 文件(
/tmp/mysql.sock),导致你配的
port、
bind-address、甚至某些网络层调试工具(如
tcpdump)完全失效。 强制走 TCP 连接:
mysql -h 127.0.0.1 -P 3306 -u root -p(注意是
127.0.0.1,不是
localhost) 验证是否生效:执行
SELECT @@hostname, @@port;,再查
SHOW PROCESSLIST;,
Host列应显示
127.0.0.1:xxxxx而非
localhost否则你改了
my.cnf的
bind-address = 0.0.0.0也白搭,因为根本没走网络栈
用 init_connect 注入调试上下文(慎用)
当需要统一给每个新连接自动设置变量(如
SQL_MODE、时区、或打标记),又不想改应用代码时,
init_connect是唯一选项。但它对 SUPER 权限用户无效,且语句出错会导致连接直接断开。 示例:为所有普通连接自动开启
profiling(用于单条语句耗时分析):
SET GLOBAL init_connect = 'SET profiling = 1;';必须确保语句语法绝对正确,且不能含 SELECT;推荐先在普通用户连接中手动执行一次验证 生产环境禁用,调试完立刻清空:
SET GLOBAL init_connect = '';它不触发
general_log,所以看不到这条语句本身被执行了——这点容易漏掉排查线索
真正难的不是打开这些开关,而是理解它们之间的干扰关系:比如开了
general_log又连不上,大概率是日志路径不可写;
slow_query_log没内容,可能是
long_query_time还没刷进全局变量,或者语句压根没进 server 层(比如权限拒绝发生在解析前)。调试环境的价值,永远取决于你能否快速判断“日志为什么没出来”。
