Hyperf 3.1+要求每个协议或大版本不同的数据库实例必须配置独立连接池和语义化连接名,因MySQL 5.7/8.0、PostgreSQL 12/14在认证、预处理、系统变量上不兼容,共用会导致握手失败、prepared statement错误或Too many connections;需在databases.php中为每个实例(如mysql_v57_rds)显式声明driver、pool参数及options,并在Swow环境下按专用结构重配check_interval≥3000等参数,修改后须清空runtime/container并重启。

Hyperf 新版本(3.1+,特别是 3.2.3)对多数据库连接的支持更严格也更清晰:它不再允许“一个连接池混用不同协议或大版本数据库”,而是要求每个行为差异明显的数据库实例——哪怕同是 MySQL,只要版本、部署方式或认证机制不同——都必须配置独立连接池和语义化连接名。
必须按实例级别单独配置连接池
Hyperf 的连接池基于 PDO 协程封装,而 MySQL 5.7 与 8.0、PostgreSQL 12 与 14 在认证插件、预处理语句行为、系统变量响应上存在底层不兼容。共用连接池会导致 handshake 失败、prepared statement 不存在、Too many connections 等运行时错误。
- MySQL 8.0 默认使用 caching_sha2_password,5.7 是 mysql_native_password;若未显式指定
auth_plugin或 PDO 选项,部分连接会卡在握手阶段 - PostgreSQL 14 启用强类型 prepared statement,旧版 pgsql 扩展可能抛出
PDOException: prepared statement "pdo_stmt_" does not exist - max_connections 统一设高,低版本实例(如 MySQL 5.7 RDS 默认 max_connections=200)容易因超限被拒绝
配置文件中定义语义化连接名与完整 pool 参数
在 config/autoload/databases.php 的 'connections' 数组中,为每个实例声明独立键名,并补全 driver、host、version(建议注释标注)、charset 及完整的 pool 子项:
- 连接名要有业务/环境/版本含义,例如:
mysql_v57_rds、mysql_v80_local、pgsql_v14_cloud,避免db1、db2这类无意义命名 -
pool内必须显式设'enable_pool' => true,且min_connections/max_connections按该实例实际承载力设置(如 RDS 实例 max_connections=200,则其连接池max_connections建议 ≤150) - 认证差异需通过
options显式控制:MySQL 8.0 推荐加PDO::ATTR_EMULATE_PREPARES => false,5.7 可能需设true;PostgreSQL 建议加'commands' => ['SET TIME ZONE \'UTC\'']
Swow 环境下需重配连接池参数
若启用 Swow(≥1.5.0,mode => SWOW_BASE),旧 Swoole 兼容层的 pool 配置会被忽略,必须改用 Swow 专用结构:
- 删除原
pool一级配置,改为同级新增'pool' => [ ... ],含check_interval >= 3000(毫秒)、retry_interval > 0 - 典型值参考:
min_connections => 8、max_connections => 64、wait_timeout => 2.0 - 修改后务必清空
runtime/container并重启,否则旧 Pool 实例残留导致新配置不生效
运行时切换与模型绑定方式不变
配置完成后,所有操作保持原有语法,无需改动业务逻辑:
- 查询:
Db::connection('mysql_v57_rds')->table('users')->get() - 事务:
Db::connection('pgsql_v14_cloud')->transaction(...) - Eloquent 模型内指定:
protected $connection = 'log_db'; - Redis 多实例同理:键名、
$poolName、DI 注册三者必须严格一致,推荐用RedisFactory::get('notify')显式获取,避免静默 fallback 到 default


















