线程安全的更改连接搜索路径的方法

3

我希望能够在Rails 4应用程序中切换不同的DB模式。

计划是在栈的最开始添加一个新的中间件来为我完成此操作。

唯一的方法是通过设置ActiveRecord::Base.connection.schema_search_path = '"$user",my_schema'来实现。

我对此的问题是,这个连接将进入连接池,并且所有后续请求都将使用第一个设置的模式(基本上泄漏了)。

因此,我认为解决方案是始终将搜索路径重置为之前的值,并在每个请求上始终进行设置。

但是,我不想这样做,因为:

  • 99%的请求将转到默认(public)模式,执行 set search_path to '$user$,my_schema'将是可以避免的额外查询
  • 泄漏风险更高(其他中间件可能会更早地建立连接,或者在我的控制范围之外对Rails或宝石进行一些更改)

所有这些都特别适用于像Puma这样的线程服务器。

那么有没有比我的中间件解决方案更好的替代方案呢?

谢谢。

1个回答

3
当您将连接返回到池中时,必须确保池运行DISCARD ALL; 以重置连接状态。
这将清除任何SET ROLESET SESSION AUTHORIZATION,会话变量,search_path设置等。

这听起来像是Rails连接池的职责。它似乎并没有实际调用它,因为连接在后续请求中保留了“search_path”。 - Dmytrii Nagirniak
@DmytriiNagirniak Rails的连接池不足和有bug?不是吧?:p 我想你必须要重写ConnectionPool.checkin和/或ConnectionPool.release_connection - Craig Ringer
不确定Rails如何重置连接,但它绝对不会调用DISCARD ALL,请参见https://github.com/rails/rails/issues/14037。您能指出关于使用DISCARD ALL(与连接池相关)的文档/指南,以为上述Rails问题提供更多信息吗? - Dmytrii Nagirniak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接