在Ruby on Rails 3.2中使用Mongo DB会话存储时如何清除旧/陈旧会话

我inheritance的Ruby on Rails应用程序运行良好,但使用MongoDB进行会话存储。 会话收集表尚未在2年多的时间内被清除(!!!),这意味着它有超过200万个条目,占用大约4GB(!!!)的空间。 对于数据库而言,这并不是一件好事,也不是必需的,并且是一个令人难以置信的误用空间 – 整体而言 – 远小于4GB。

所以调查如何清理这些东西我在各种网站上发现了很多post – Stack Overflow和其他 – 解释了一般过程:

  • 使用Rails中的rake任务清理会话数据库存储
  • 清除Rails会话
  • 如何清除rails会话表
  • Rails:清除存储在数据库中的旧会话

这是有道理的:创建一个连接到sessionsrake任务,并根据updated_at条件删除条目。 都好!

我的问题是这个Ruby on Rails应用程序使用MongoDB和Mongoid,所以这些页面上提供的示例实际上都没有用。 所以像这样的东西不起作用:

 namespace :sessions do desc "Clear expired sessions (more than 7 days old)" task :cleanup => :environment do ActiveRecord::SessionStore::Session.delete_all(["updated_at < ?", 7.days.ago]) end end 

该应用程序不使用ActiveRecord,因此没有骰子。 rake任务因ActiveRecord不存在而死亡,如果包含ActiveRecord则死亡,因为核心DB逻辑不依赖于ActiveRecord模型; 这都是Mongoid。

还使用所谓的烘焙rake db:sessions:clear一些人推荐似乎没有工作,我相信连接到不使用ActiveRecord的应用程序,因此该任务甚至不存在。

我如何能够使用Rails 3中的Mongoid创建一个等效查询来清除数据库会话存储中的死,旧和陈旧会话?

解决这个问题的关键是理解当Rails 3应用程序的session_store设置为mongoid_store时使用直接Mongoid方法永远不会允许这种直接数据库交互发生。

因此,通过将Mongoid用于基本数据库连接,然后实际上直接在驱动程序操作级别上与Mongoid的Moped核心进行交互,可以轻松实现相同的function! 这是我提出的Mongoid / Moped rake任务,效果很好:

 namespace :sessions do stale_window = 7 desc "Clear stale DB sessions older than #{ stale_window } days." task :cleanup => :environment do db = Mongoid::Sessions.default begin db[:sessions].where('updated_at' => { '$lt' => stale_window.days.ago }).sort(updated_at: 1).no_timeout.remove_all rescue Moped::Errors::SocketError => e # Rescue here if needed. If not, the screwed up process dies silently. end end end 

连接是通过db = Mongoid::Sessions.default ,并且魔法发生在行中:

 db[:sessions].where('updated_at' => { '$lt' => stale_window.days.ago }).sort(updated_at: 1).no_timeout.remove_all 

我已经设置了stale_window变量,因此我可以轻松调整此任务的范围; 设置DB值以及描述。 要使用它,我从代码库路径运行它:

 RAILS_ENV=production bundle exec rake sessions:cleanup 

当然,只需更改RAILS_ENV值即可匹配您希望此任务执行的环境; 例如stagingdevelopment或其他任何你可能为你的环境命名的东西。 在运行该rake任务之后, sessions集合表将被修剪为更实际的实际使用情况,并且整个数据库大小更合理。