CentOS 上 Laravel 数据库连接失败的常见原因与排查
一 常见根因概览
- 数据库服务未启动:如 MySQL/MariaDB 未运行,应用自然无法连接。
- 连接参数错误:.env 或 config/database.php 中的 DB_HOST/DB_PORT/DB_DATABASE/DB_USERNAME/DB_PASSWORD 任一错误都会导致失败。
- 网络与访问控制:服务器防火墙(如 firewalld)或云安全组未放行 3306,或数据库仅监听 127.0.0.1。
- 数据库用户权限不足或主机限制:用户未授予远程访问或目标库权限,或授权主机与连接来源不匹配。
- PHP 扩展缺失:未安装 pdo_mysql(或 mysqli)等扩展,导致底层驱动不可用。
- 配置缓存未更新:修改 .env 后未执行 php artisan config:clear,应用仍使用旧配置。
- SELinux 策略限制:SELinux 处于 enforcing 且策略阻止连接。
- 连接超时或数据库负载异常:网络抖动、数据库繁忙导致握手或查询超时。
二 快速定位步骤
- 核对连接参数:确认 .env 中 DB_CONNECTION=mysql,以及 DB_HOST/DB_PORT/DB_DATABASE/DB_USERNAME/DB_PASSWORD 正确;必要时在应用服务器上用命令行直连验证:
mysql -h 实际主机 -P 3306 -u 用户名 -p
- 检查数据库服务状态与监听:
- 状态:systemctl status mysqld
- 监听:ss -nlt | grep 3306 或 netstat -tnlp | grep 3306
- 验证网络与防火墙:
- firewalld:firewall-cmd --list-ports 与 firewall-cmd --add-port=3306/tcp --permanent && firewall-cmd --reload
- 云环境:检查安全组入站规则是否允许来自应用服务器的 3306/TCP。
- 检查用户权限与主机匹配:确保用户授权包含应用来源主机(如 ‘user’@‘应用服务器IP’ 或 ‘%’),并授予目标库权限。
- 查看日志定位:
- Laravel:storage/logs/laravel.log
- MySQL:/var/log/mysqld.log
- 确认 PHP 扩展:php -m | grep -E ‘pdo_mysql|mysqli’;缺失则安装对应扩展并重启 php-fpm。
- 清除配置缓存:php artisan config:clear(修改 .env 后务必执行)。
- 排除 SELinux:临时 setenforce 0 验证,若解决需调整 SELinux 策略或设为 Permissive(不建议长期)。
三 典型报错与对应处理
- SQLSTATE[HY000] [2002] Connection refused / 目标计算机主动拒绝连接:多为数据库未启动、端口未监听、或防火墙/安全组阻断;先确认 mysqld 运行与 3306 监听,再放行防火墙/安全组。
- SQLSTATE[28000] [1045] Access denied for user:用户名/密码错误或用户无对应主机权限;核对凭据,并用 GRANT 授予从应用服务器来的访问。
- SQLSTATE[HY000] [2006] MySQL server has gone away / 超时:连接超时或数据包过大;在 config/database.php 增加 ‘options’ => [PDO::ATTR_TIMEOUT => 30] 或调整 wait_timeout。
- PDOException: could not find driver:缺少 pdo_mysql 扩展;安装扩展并重启 php-fpm。
- No such file or directory(使用 socket 时):指定了 127.0.0.1 却用 socket 连接或 socket 路径错误;统一使用 127.0.0.1:3306 或正确配置 socket。
四 最小可用配置与命令清单
- .env 示例(MySQL):
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_db
DB_USERNAME=your_user
DB_PASSWORD=your_password
- 常用命令:
- 服务:systemctl status mysqld;systemctl start mysqld;systemctl enable mysqld
- 监听:ss -nlt | grep 3306
- 防火墙:firewall-cmd --add-port=3306/tcp --permanent && firewall-cmd --reload
- 权限:GRANT ALL PRIVILEGES ON your_db.* TO ‘your_user’@‘应用服务器IP’ IDENTIFIED BY ‘your_password’; FLUSH PRIVILEGES;
- Laravel:php artisan config:clear;php artisan migrate
- 日志:tail -f storage/logs/laravel.log;tail -f /var/log/mysqld.log