6

我有一个提供陈旧内容的 Rails 3.2 应用程序。一个典型的场景:

  1. 管理员在后端添加了一些新记录
  2. 用户去查看那些资源的索引页面
  3. 他们没有出现在页面上
  4. 他们刷新;资源现在在那里
  5. 他们刷新;资源不存在
  6. 等等

我创建了一个模型/控制器/视图,所以我可以测试一下:

# app/models/cache_query_test.rb

class CacheQueryTest < ActiveRecord::Base
end

# app/controllers/cache_query_tests_controller.rb

class CacheQueryTestsController < ApplicationController
  def count
    @count = CacheQueryTest.count
    @mysql_time = CacheQueryTest.find_by_sql("SELECT NOW() AS mysql_time")

    respond_to do |wants|
      wants.text { render :layout => false }
    end
  end
end

# app/views/cache_query_tests/count.text.erb

==============
Rails MySQL Time: <%= @mysql_time.first.mysql_time %>
Ruby Time:        <%= Time.now.strftime "%Y-%m-%d %H:%M:%S" %>
Rails MySQL Count: <%= @count %>

我还运行了一个小的 shell 脚本,它会定期将记录添加到应用程序的 MySQL 数据库中的 cache_query_tests 表中,这样理论上数据库不会缓存查询。

当我点击显示我的测试页面的 URL 时,我得到了好坏参半的结果,例如:

==============
Rails MySQL Time: Mon Sep 16 10:40:57 UTC 2013
Ruby Time:        2013-09-16 10:40:58
Rails MySQL Count: 177

或者:

==============
Rails MySQL Time: Mon Sep 16 09:47:46 UTC 2013
Ruby Time:        2013-09-16 10:16:32
Rails MySQL Count: 165

或者:

==============
Rails MySQL Time: Mon Sep 16 09:50:02 UTC 2013
Ruby Time:        2013-09-16 10:41:32
Rails MySQL Count: 167

等等...

在所有情况下,“Ruby Time”都是最新且正确的,因此页面本身不会被缓存。但是,如您所见,“Rails MySQL Time”通常与 Ruby Time 不同步。同样,“Rails MySQL Count”也经常出错,尽管我正在向数据库添加记录,所以这就是为什么我认为 Rails 堆栈中的某些东西正在执行查询缓存。

据我所知,Rails 只应该在 request 中进行查询缓存。在这里,某些东西(可能是 MySQL?可能是 Rack?可能是 Rails?)正在跨请求执行。坦率地说,我很困惑从这里去哪里。虽然我想要一个解决方案:),但我也想对问题所在的位置提出更多意见。

谢谢。

4

2 回答 2

0

虽然很难确定(因为这取决于您的 MySQL 配置,而不是您的 Rails 配置),但最可能的答案是您的 MySQL 服务器正在使用query cache。从文档中:

查询缓存存储 SELECT 语句的文本以及发送到客户端的相应结果。如果稍后收到相同的语句,则服务器从查询缓存中检索结果,而不是再次解析和执行该语句。查询缓存在会话之间共享,因此可以发送一个客户端生成的结果集以响应另一个客户端发出的相同查询。

您可以使用查询缓存选择选项来验证这是否发生在数据库层。尝试将您的 SQL 语句更改为如下内容:

@mysql_time = CacheQueryTest.find_by_sql("SELECT SQL_NO_CACHE NOW() AS mysql_time")

我打赌之后你会发现每次检索它时时间都会改变。

于 2013-09-16T15:59:15.510 回答
0

为了帮助遇到同样问题的不幸 SOB,我们最终将其追溯到 Octopus gem ( https://github.com/tchandy/octopus )。请注意,我不确定这种行为是有意的还是可配置的,所以我不想责怪 Octopus,而只是注意到这是原因。

于 2013-09-23T13:10:40.440 回答