如何为 rails 5 个应用配置模式缓存?
How to configure schema cache for rails 5 app?
所以,我目前在项目中使用 Rails 5 和 mysql 数据库。我正在尝试使用 ActiveRecord 模式缓存在我的 rails 应用程序上预先加载表,而无需查询 show full fields
。这个选项是 enabled by default,要让它工作,你唯一需要做的就是使用 rake db:schema:cache:dump(它将在 db 文件夹中生成缓存文件)。虽然,我一直看到 show full fields
查询是通过 newrelic 触发的,并决定 运行 一些睾丸来评估缓存是否正常工作。
经过几次测试后,我说缓存确实无法正常工作,并且对发生的事情一无所知。我尝试在配置中将 active_record.use_schema_cache_dump
选项设置为 true 并确保架构缓存文件存在于应用程序文件夹中。之后,我决定在我的应用程序中手动初始化缓存,并使用 binding.pry
来查看它的运行情况。有趣的是,加载缓存并建立连接而无需查询上下文,但当我离开 pry 和服务器启动时,缓存已卸载。
我注意到另一件奇怪的事情,问题不是缓存已被清理,而是 ActiveRecord 使用的连接在两个步骤中都是不同的对象。
这是我的自定义初始化程序(改编自 here):
ActiveSupport.on_load(:active_record) do
filename = File.join(Rails.application.config.paths["db"].first, "schema_cache.yml")
if File.file?(filename)
current_version = ActiveRecord::Migrator.current_version
next if current_version.nil?
cache = YAML.load(File.read(filename))
if cache.version == current_version
ActiveRecord::Base.connection.schema_cache = cache
ActiveRecord::Base.connection_pool.schema_cache = cache.dup
binding.pry
else
warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
end
end
end
在我使用的控制台上:
[1] pry(ActiveRecord::Base)> ActiveRecord::Base.connection.object_id
=> 70357693731960
Running via Spring preloader in process 21185
Loading development environment (Rails 5.2.2.1)
Frame number: 0/25
[1] pry(main)> ActiveRecord::Base.connection.object_id
(4.3ms) SET NAMES utf8, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
=> 70357724355600
如上所示,连接对象与初始化和控制台本身不同,服务器也是如此。因此 connection
中的 schema_cache
是空的。
任何人都可以向我澄清我的假设有什么问题或指出执行模式缓存的正确方向吗?
我找到了解决方案。彪马是罪魁祸首,而不是 Rails。在 puma fork 一个 worker 后,ActiveRecord 连接丢失。
Pull request on Rails stating that the puma configuration was no longer necessary
所以,我目前在项目中使用 Rails 5 和 mysql 数据库。我正在尝试使用 ActiveRecord 模式缓存在我的 rails 应用程序上预先加载表,而无需查询 show full fields
。这个选项是 enabled by default,要让它工作,你唯一需要做的就是使用 rake db:schema:cache:dump(它将在 db 文件夹中生成缓存文件)。虽然,我一直看到 show full fields
查询是通过 newrelic 触发的,并决定 运行 一些睾丸来评估缓存是否正常工作。
经过几次测试后,我说缓存确实无法正常工作,并且对发生的事情一无所知。我尝试在配置中将 active_record.use_schema_cache_dump
选项设置为 true 并确保架构缓存文件存在于应用程序文件夹中。之后,我决定在我的应用程序中手动初始化缓存,并使用 binding.pry
来查看它的运行情况。有趣的是,加载缓存并建立连接而无需查询上下文,但当我离开 pry 和服务器启动时,缓存已卸载。
我注意到另一件奇怪的事情,问题不是缓存已被清理,而是 ActiveRecord 使用的连接在两个步骤中都是不同的对象。
这是我的自定义初始化程序(改编自 here):
ActiveSupport.on_load(:active_record) do
filename = File.join(Rails.application.config.paths["db"].first, "schema_cache.yml")
if File.file?(filename)
current_version = ActiveRecord::Migrator.current_version
next if current_version.nil?
cache = YAML.load(File.read(filename))
if cache.version == current_version
ActiveRecord::Base.connection.schema_cache = cache
ActiveRecord::Base.connection_pool.schema_cache = cache.dup
binding.pry
else
warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
end
end
end
在我使用的控制台上:
[1] pry(ActiveRecord::Base)> ActiveRecord::Base.connection.object_id
=> 70357693731960
Running via Spring preloader in process 21185
Loading development environment (Rails 5.2.2.1)
Frame number: 0/25
[1] pry(main)> ActiveRecord::Base.connection.object_id
(4.3ms) SET NAMES utf8, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
=> 70357724355600
如上所示,连接对象与初始化和控制台本身不同,服务器也是如此。因此 connection
中的 schema_cache
是空的。
任何人都可以向我澄清我的假设有什么问题或指出执行模式缓存的正确方向吗?
我找到了解决方案。彪马是罪魁祸首,而不是 Rails。在 puma fork 一个 worker 后,ActiveRecord 连接丢失。
Pull request on Rails stating that the puma configuration was no longer necessary