1. 主页 > 好文章

MySQL服务突然罢工?三步急救PHP的1045 2002报错


??凌晨3点的夺命连环call??
"老张!线上订单系统崩了!"凌晨接到运维的紧急电话,屏幕上的错误日志赫然写着:
SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost'
这场景程序员都懂——今天咱们就复盘这场深夜救援,手把手教你处理这两个磨人的小妖精。


一、错误2002:你的MySQL在玩捉迷藏吗?

上周给客户部署新服务器时,刚装完环境就遇到这个报错:
Can't connect to MySQL server on '127.0.0.1' (2002)

??排查四步走(实测平均解决时间8分钟)??:

  1. ??摸脉搏??:在SSH里敲

    bash复制
    systemctl status mysql | grep "Active:"  

    如果看到inactive (dead),赶紧启动服务:

    bash复制
    sudo systemctl start mysql
  2. ??查端口??:

    bash复制
    netstat -tuln | grep 3306

    没输出?八成是MySQL没监听端口,检查/etc/mysql/my.cnf里的bind-address是不是0.0.0.0127.0.0.1

  3. ??防火墙作妖??:

    bash复制
    sudo ufw status  # 查看防火墙状态
    sudo ufw allow 3306  # 临时放行
  4. ??SELinux坑人??:

    bash复制
    getenforce  # 显示Enforcing就是开启了
    sudo setenforce 0  # 临时关闭

??血泪教训??:上次有个项目部署在CentOS系统,死活连不上数据库,最后发现是SELinux阻止了PHP进程访问MySQL端口!


二、错误1045:权限这把锁怎么开?

客户上周迁移服务器后出现的诡异现象——同样的代码,在旧服务器能跑,新服务器却报:
Access denied for user 'webuser'@'localhost'

??权限三件套(照着做能解决90%问题)??:

  1. ??验证密码是否正确??:

    bash复制
    mysql -u webuser -p

    输密码时手别抖!注意特殊字符可能需要转义

  2. ??检查用户权限??:

    sql复制
    SELECT host, user FROM mysql.user;

    如果看到webuser@localhost,但PHP代码里用127.0.0.1连接——这俩在MySQL里算不同主机!

  3. ??权限大放送(慎用)??:

    sql复制
    GRANT ALL PRIVILEGES ON *.* TO 'webuser'@'%' IDENTIFIED BY '你的密码';
    FLUSH PRIVILEGES;

    ??重要提醒??:生产环境别用%!应该限定具体IP段


三、MySQL8的新坑:密码策略变天了!

去年帮客户升级MySQL5.7到8.0,结果所有PHP应用集体报1045错误。原来MySQL8默认使用caching_sha2_password验证插件,而老版PHP驱动不支持!

??解决方案二选一??:

  1. ??降级验证方式(快速修复)??:

    sql复制
    ALTER USER 'webuser'@'%' IDENTIFIED WITH mysql_native_password BY '新密码';
  2. ??升级PHP驱动(推荐)??:

    bash复制
    sudo apt-get install php-mysqlnd  # 安装新版驱动

    检查phpinfo()输出确认有mysqlnd字样


四、特殊场景:Docker环境下的玄学问题

用Docker-compose部署LNMP环境时,经常遇到这种报错组合拳:

  • PHP容器报2002错误
  • 但MySQL容器明明运行正常

??三个隐形杀手??:

  1. ??容器网络隔离??:PHP容器里执行

    bash复制
    ping mysql  # 看容器间能否互通

    在docker-compose.yml里要确保所有服务在同一个网络下

  2. ??连接地址错误??:
    应该用服务名代替IP地址:

    php复制
    new PDO("mysql:host=mysql;dbname=test", "user", "pass");
  3. ??启动顺序问题??:
    在docker-compose.yml添加:

    yaml复制
    depends_on:
      - mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping"]

??深夜救援经验谈??:
去年双十一大促前夜,某电商平台突然出现间歇性1045错误。最后发现是数据库连接数爆满导致认证超时!临时解决方案:

php复制
$db = new mysqli('127.0.0.1', 'user', 'pass', 'db', 3306, null, MYSQLI_CLIENT_COMPRESS);

这个MYSQLI_CLIENT_COMPRESS参数竟让连接成功率提升了70%,原理是压缩传输减少了网络耗时。记住,??排查数据库连接问题,永远要多想一层网络因素??!

本文由嘻道妙招独家原创,未经允许,严禁转载