Hyperf 3.0+ 升级后多库连接问题核心是连接池隔离变严、驱动切换为 hyperf/db-connection、配置加载时机变化;需移除旧包、替换命名空间、独立配置各库连接池及参数,并注意 Swow 环境的池配置差异。

Hyperf 升级后多数据库连接出问题,核心不在“能不能连多个库”,而在于连接池隔离规则变严、驱动组件迁移、配置加载时机变化。旧写法看似能跑,但高并发下容易连接泄漏、认证失败或事务错乱。
确认数据库组件已切换为 db-connection
Hyperf 3.0+ 已弃用 hyperf/database,改用 hyperf/db-connection。若仍保留旧包,会直接报 Class not found 或 Call to undefined method:
- 执行
composer remove hyperf/database,再运行composer require hyperf/db-connection - 全局搜索替换
use Hyperf\Database\...→use Hyperf\DbConnection\...(例如ConnectionInterface、QueryFactoryInterface) -
Db::connection('xxx')仍可用,但底层已由ConnectionInterface实现,确保 DI 容器中已注册该接口
每个数据库实例必须独立配置连接池
MySQL 5.7 和 8.0、PostgreSQL 12 和 14、甚至同版本但部署在 RDS 与自建环境的实例,都因协议/认证/SQL 模式差异,不能共用一个连接池:
- 在
config/autoload/databases.php的'connections'中,为每个库定义唯一键名(如'mysql_v57_log'、'mysql_v80_core') - 每个连接块必须显式声明
'driver'、完整'pool'配置(含min_connections、max_connections),不能继承 default 池 - MySQL 8.0 需加
'options' => [PDO::MYSQL_ATTR_SSL_MODE => PDO::SSL_NONE];5.7 若启用了预处理,建议设PDO::ATTR_EMULATE_PREPARES => true
运行时切换连接要避开常见陷阱
用 Db::connection('xxx') 切换是安全的,但要注意上下文和生命周期:
- Eloquent 模型中指定
protected $connection = 'log_db';即可绑定专属库,无需每次调用 - 事务必须显式传入连接名:
Db::connection('report_db')->transaction(...),否则默认走default - 避免在协程中间件或初始化阶段提前调用
Db::connection()——此时配置可能未加载完毕,尤其使用 Apollo/Nacos 时易触发Address not available
Swow 环境需重配连接池参数
若启用 Swow(mode => SWOW_BASE),原 Swoole 风格的 pool 配置会被忽略,必须用 Swow 专用结构:
- 删除原有
pool下的heartbeat、max_idle_time等字段 - 改为:
'pool' => ['min_connections' => 8, 'max_connections' => 64, 'check_interval' => 3000, 'retry_interval' => 100] - 修改后务必清空
runtime/container并重启,否则旧 Pool 实例残留导致新配置不生效


















