Rails 6迁移后多数据库访问异常:查询始终走主库排查
Rails 6原生多数据库查询仍走主库的排查方案
1. 模型未关联到SecondaryApplicationRecord
如果业务模型(如Post、User)仍继承自绑定主库的ApplicationRecord,即使在connected_to块内执行查询,模型依然会使用主库连接池——因为模型本身的连接配置已绑定到primary。
检查点:确认需从从库读取的模型继承关系:
# 错误写法(仍用主库) class Post < ApplicationRecord end # 正确写法(绑定从库) class Post < SecondaryApplicationRecord end
临时替代方案:若不想修改模型继承,可在查询时显式指定连接:
SecondaryApplicationRecord.connected_to(role: :secondary) do Post.connected_to(role: :secondary) { Post.all } end
2. connected_to用法或参数错误
Rails 6的connected_to方法需严格匹配数据库配置标识(role或数据库名),且块范围必须正确包裹查询逻辑。
常见错误点:
- 参数不匹配:若
database.yml配置的是secondary数据库(而非role),需用database: :secondary而非role: :secondary;反之若配置了role,需对应使用role: :secondary。 - around_action块范围错误:确保
yield在connected_to代码块内,否则请求逻辑不会进入从库上下文:
# 错误写法:yield在块外 def use_secondary_db SecondaryApplicationRecord.connected_to(role: :secondary) {} yield end # 正确写法 def use_secondary_db SecondaryApplicationRecord.connected_to(role: :secondary) do yield end end
3. database.yml配置不规范
Rails 6对多数据库配置有明确要求,缺失关键项会导致路由失效:
正确的production配置示例:
production: primary: url: <%= ENV['DATABASE_URL'] %> role: primary secondary: url: <%= ENV['SECONDARY_DATABASE_URL'] %> role: secondary replica: true # 标记为只读副本,Rails自动优化读写逻辑
检查点:
- 确认
secondary的url指向Heroku从库的环境变量(需在Heroku config vars中正确设置SECONDARY_DATABASE_URL) - 必须为每个数据库指定
role,且与SecondaryApplicationRecord的connects_to参数对应
4. SecondaryApplicationRecord定义错误
抽象类的连接配置必须正确绑定目标数据库,否则无法生效:
正确的抽象类定义:
class SecondaryApplicationRecord < ApplicationRecord self.abstract_class = true # 与database.yml中的数据库名对应 connects_to database: :secondary # 或与role对应:connects_to role: :secondary end
检查点:确保self.abstract_class = true已设置(否则Rails会将其视为普通模型生成对应表),且connects_to参数与database.yml配置一致。
5. 查询被强制路由到主库
Rails会自动将写操作路由到主库,若查询块内存在隐性写操作(如回调、缓存更新、计数器增量等),会触发主库切换:
检查点:
- 查看查询代码是否包含
save、update、destroy等写操作 - 检查模型是否在
after_find、after_initialize等回调中执行写逻辑 - 确认是否开启了Rails自动读写分离(
config.active_record.database_selector相关配置),可能覆盖手动connected_to的路由
6. Heroku环境配置问题
Heroku的数据库环境变量或插件配置异常可能导致从库连接未生效:
检查点:
- 执行
heroku config确认SECONDARY_DATABASE_URL已正确设置且指向从库地址 - 确认Heroku从库已正确创建并与主库同步(可通过Heroku Dashboard查看数据库状态)
- 检查Heroku的Rails日志,确认应用启动时是否加载了secondary数据库配置(无连接错误)
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

