yii2主从配置需在单个db组件中通过slaves数组定义从库、slaveconfig设置公共属性,读操作自动路由至从库,写操作及事务强制走主库;从库认证信息须独立填写,未连通时默认静默降级至主库。

Yii 框架连接主从库不是靠配两个独立的 db 和 db_slave 组件,而是让单个 db 组件自己知道“谁是主、谁是从”,并在执行 SQL 时自动路由——读走从库、写走主库。
主从配置必须用 slaves + slaveConfig,不能只加 db2
常见错误是把主库配成 db、从库配成 db2,然后手动在模型里切连接。这不算读写分离,只是多数据库,所有查询仍默认走 db,你得自己 everywhere 加 getDb() 切换,极易漏掉、难维护。
-
slaves是一个数组,每个元素是一个完整从库配置(含dsn、username、password),不能省略认证信息 -
slaveConfig只继承部分字段(如charset、attributes),但username和password必须显式写在每个slaves项里 - 主库配置写在
db顶层,建议显式加'master' => true;每个从库也建议加'master' => false,避免某些内部判断误判
SELECT 默认走从库,但事务/强制主库例外
Yii 的分发逻辑是硬编码在 yii\db\Command 和 yii\db\Connection::getSlave() 里的,不是靠 SQL 解析关键词。它只看操作类型和上下文:
- 普通
SELECT(包括ActiveRecord::find()->one()、->all())→ 自动调用getSlave()挑一个从库 -
INSERT/UPDATE/DELETE→ 固定走主库 - 任何在
transaction中的操作 → 全部走主库(哪怕里面只有SELECT) - 想绕过自动路由?用
->master()或->slave()显式声明,比如User::find()->master()->one()强制读主库
从库连不上会 fallback 到主库,但默认不报错
这是最容易被忽略的“静默降级”行为:当 getSlave() 尝试连接所有从库都失败时,如果参数 $fallbackToMaster === true(默认就是 true),它会自动退到主库执行查询,且不抛异常、不打 warning 日志。
- 后果:你以为查的是从库,实际流量全压到主库,读写分离形同虚设,直到主库扛不住才暴露问题
- 排查方法:打开
yii\db\Connection::$serverStatusCache,它默认缓存失败状态 600 秒;可临时关掉(设'enableSchemaCache' => false)或加日志监听afterOpen事件 - 生产环境建议:监控
Yii::getLogger()->getLogs()里是否有PDOException或Connection refused,并设置告警
负载均衡策略不可见,但影响真实可用性
Yii 对从库的选取是随机打乱后遍历(openFromPool()),没有轮询、权重、健康度探测等高级策略。这意味着:
- 如果某个从库响应慢但没断连,它会被持续选中,拖慢整体查询速度
- 没有自动剔除机制——只要 PDO 能 connect 上,就算“可用”,哪怕后续 query 全超时
- 若要控制顺序,可用
openFromPoolSequentially(),但需自己重写getSlave()方法,代价高
真正复杂的点不在配置语法,而在于从库的可用性、延迟、一致性边界——比如刚写完一条记录立刻去从库查,大概率查不到,得靠业务层加延迟或强制走主库兜底。











