Connection refused 错误:检查服务状态与端口
MySQL 启动失败或客户端连不上时,
Connection refused是最常见报错。它不表示密码错,而是根本没通到 MySQL 进程。 先确认服务是否运行:
systemctl status mysql(Ubuntu/Debian)或
systemctl status mysqld(CentOS/RHEL) 检查监听地址和端口:默认是
127.0.0.1:3306,但配置文件中
bind-address设为
127.0.0.1会拒绝远程连接;设为
0.0.0.0才允许外部访问(注意防火墙) 验证端口是否被占用:
ss -tuln | grep :3306或
netstat -tuln | grep :3306;若无输出,说明 MySQL 没监听 查看错误日志定位启动失败原因:
/var/log/mysql/error.log(Debian/Ubuntu)或
/var/log/mysqld.log(RHEL/CentOS)
Access denied for user 错误:权限与认证插件问题
Access denied for user 'xxx'@'localhost'看似是密码错,但实际常因用户不存在、host 不匹配,或 MySQL 8.0+ 默认使用
caching_sha2_password插件导致客户端不兼容。 登录本地
mysql -u root -p后,查用户是否存在:
SELECT user, host, plugin FROM mysql.user WHERE user = 'xxx';注意
host字段必须精确匹配——
'user'@'localhost'和
'user'@'127.0.0.1'是两个不同账户(Unix socket vs TCP) MySQL 8.0+ 新建用户默认用
caching_sha2_password,旧版客户端(如某些 PHP 7.2、Navicat 旧版)不支持;可临时改用
mysql_native_password:
ALTER USER 'xxx'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';执行后别忘了
FLUSH PRIVILEGES;
Too many connections 错误:调整 max_connections 与连接泄漏
应用报
Too many connections,不是数据库崩了,而是当前活跃连接数超了
max_connections限制(默认通常 151)。 查当前设置:
SHOW VARIABLES LIKE 'max_connections';查实时连接数:
SHOW STATUS LIKE 'Threads_connected';或更细粒度:
SELECT COUNT(*) FROM information_schema.PROCESSLIST;临时调高(重启失效):
SET GLOBAL max_connections = 300;永久生效需改配置文件
/etc/mysql/mysql.conf.d/mysqld.cnf(Debian)或
/etc/my.cnf(RHEL),在
[mysqld]下加:
max_connections = 300更重要的是排查连接泄漏:应用未正确关闭
connection.close()、短连接未复用、连接池配置不合理(如
maxIdle>
maxActive)都可能导致堆积
Lock wait timeout exceeded 错误:事务阻塞与长事务排查
Lock wait timeout exceeded表示一个事务在等锁,等太久超时了。不是死锁(MySQL 会自动检测并回滚一方),而是“排队太久被踢出”。 查谁在堵着:
SELECT * FROM information_schema.INNODB_TRX\G看
TRX_STATE、
TRX_STARTED、
TRX_QUERY查锁等待关系:
SELECT * FROM information_schema.INNODB_LOCK_WAITS\G查当前所有连接和语句:
SHOW FULL PROCESSLIST;关注
State列为
Locked或
Waiting for table metadata lock的行 常见诱因:未提交的事务、
ALTER TABLE大表、
SELECT ... FOR UPDATE后没及时提交、备份脚本用
mysqldump --single-transaction但事务卡住 应急可杀掉阻塞源:
KILL <i>trx_id</i>;或
KILL <i>processlist_id</i>;(谨慎操作)
真正难的不是看懂报错,而是把
SHOW ENGINE INNODB STATUS\G输出里那段“TRANSACTIONS”和“LATEST DETECTED DEADLOCK”信息快速对应到业务代码里的某次查询——这需要你习惯在事务开始时打日志,记录 trace_id 和 SQL。
