
Laravel 应用切换数据库后仍连接旧库,常见原因并非缓存问题,而是 .env 中残留的 DB_SOCKET 配置强制指定了本地 Unix 套接字路径,导致绕过 DB_HOST 设置直连旧 MySQL 实例。
laravel 应用切换数据库后仍连接旧库,常见原因并非缓存问题,而是 `.env` 中残留的 `db_socket` 配置强制指定了本地 unix 套接字路径,导致绕过 `db_host` 设置直连旧 mysql 实例。
当你在 Laravel 8 中将数据库从 DB1 切换到 DB2(同为 MySQL),即使已正确修改 .env 中的 DB_HOST、DB_PORT、DB_DATABASE 等字段,并执行了 php artisan config:clear、php artisan config:cache、php artisan optimize:clear 甚至重启 Nginx/PHP-FPM,应用仍顽固连接 DB1——这往往不是缓存失效,而是 DB_SOCKET 的隐式优先级干扰。
Laravel 的 MySQL 配置在 config/database.php 中默认使用如下逻辑(精简示意):
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''), // ← 关键!若非空,则优先使用 socket 连接
// ...
],
⚠️ 注意:当 DB_SOCKET 被设置(如 DB_SOCKET=/tmp/mysql.sock),PDO 会忽略 DB_HOST 和 DB_PORT,直接通过 Unix 域套接字连接本地 MySQL 实例——而这实例极大概率就是原先的 DB1(例如本机默认 MySQL 服务),导致所有配置变更形同虚设。
验证方法:
- 运行
php artisan db:sql成功连接 DB2?→ 因该命令可能绕过部分连接逻辑或使用独立配置; -
php artisan tinker中执行\DB::connection('mysql')->table('nonexistent_in_db1')->get()报错?→ 确认实际连接的是 DB1; - 停止 DB1 后网站立即报
No such file or directory?→ 典型 Unix socket 连接失败特征,印证DB_SOCKET在生效。
✅ 解决方案:
彻底检查并删除 .env 文件中的 DB_SOCKET 行(或设为空:DB_SOCKET=)。
无需重启服务或清缓存——只要 DB_SOCKET 为空,Laravel 就会回归标准 TCP 连接模式,严格遵循 DB_HOST/DB_PORT 指向 DB2。
? 额外建议:
- 使用
php artisan tinker快速验证连接目标:>>> \DB::connection()->getPdo()->getAttribute(\PDO::ATTR_CONNECTION_STATUS) => "localhost via UNIX socket" // → 仍在走 socket,需检查 DB_SOCKET >>> \DB::connection()->getPdo()->getAttribute(\PDO::ATTR_SERVER_VERSION) => "8.0.33-0ubuntu0.22.04.2" // 可交叉比对 DB2 版本确认
- 生产环境部署时,建议在 CI/CD 流程中加入
.env合规性检查(如禁止DB_SOCKET出现在非本地开发环境); - 若确需 socket 连接(如高性能本地场景),请确保
DB_SOCKET指向目标数据库(DB2)对应的套接字路径,并同步停用DB_HOST冗余配置。
根本原则:DB_SOCKET 是高优先级连接方式,有则必用;切换数据库时,它比 DB_HOST 更“沉默”也更危险——务必显式清理。











