MySQL调试核心是让SQL执行“看得见、停得住、改得动”,需开启general_log查全语句、slow_query_log定位慢查询、强制TCP连接确保网络层可控,并慎用init_connect注入上下文。
MySQL 调试环境不是装个客户端就行,核心是让 SQL 执行过程“看得见、停得住、改得动”。重点不在安装,而在开启日志、连接可控、语句可复现。
这是排查“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';
my.cnf 的 [mysqld] 段添加:general_log = ON general_log_file = /tmp/mysql-general.log
SELECT、UPDATE 等关键字过滤更高效当用户反馈“页面卡”,但不知道哪条 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 看真实参数本地开发常直连 localhost,但 MySQL 默认会走 socket 文件(/tmp/mysql.sock),导致你配的 port、bind-address、甚至某些网络层调试工具(如 tcpdump)完全失效。
mysql -h 127.0.0.1 -P 3306 -u root -p(注意是
127.0.0.1,不是 localhost)SELECT @@hostname, @@port;,再查 SHOW PROCESSLIST;,Host 列应显示 1
27.0.0.1:xxxxx 而非 localhost
my.cnf 的 bind-address = 0.0.0.0 也白搭,因为根本没走网络栈
当需要统一给每个新连接自动设置变量(如 SQL_MODE、时区、或打标记),又不想改应用代码时,init_connect 是唯一选项。但它对 SUPER 权限用户无效,且语句出错会导致连接直接断开。
profiling(用于单条语句耗时分析):SET GLOBAL init_connect = 'SET profiling = 1;';
SET GLOBAL init_connect = '';
general_log,所以看不到这条语句本身被执行了——这点容易漏掉排查线索真正难的不是打开这些开关,而是理解它们之间的干扰关系:比如开了 general_log 又连不上,大概率是日志路径不可写;slow_query_log 没内容,可能是 long_query_time 还没刷进全局变量,或者语句压根没进 server 层(比如权限拒绝发生在解析前)。调试环境的价值,永远取决于你能否快速判断“日志为什么没出来”。