A while ago I started setting up my websites to use ActiveRecord as a session store, this means that the session information for all the visitors to my website is placed in a table in my database. It may or may not be the best way to store sessions but it’s certainly faster than the filesystem and my VPS doesn’t really have the memory capacity for an ‘in memory’ store.
Anyway, one day I decided to perform some DB maintenance, check tables where okay etc, upon logging into the DB I noticed that my sessions table had grown quite large, almost 125,000 records, little did I realize that the sessions are persisted forever in the DB.
I didn’t think it was the best idea to keep all the session data so wrote the following script and put it in
namespace :session do desc "Prune old session data" task :prune => :environment do sql = ActiveRecord::Base.connection() sql.execute "SET autocommit=0" sql.begin_db_transaction response = sql.execute("DELETE FROM sessions WHERE `updated_at` < DATE_SUB(CURDATE(), INTERVAL 1 DAY)"); sql.commit_db_transaction end end
This gave me a ‘session:prune’ rake task. The task removes all sessions older than 1 day from the sessions table. I then added a CRON job for in the following format:
0 0 * * * cd /home/user/railsapp && rake RAILS_ENV=production session:prune > /dev/null 2>&1
The job above basically calls the
session:prune rake task at midnight every night.
The code in the task in MySQL specific but without a model representing the session table I couldn’t (or at least couldn’t think of a way) to make the code any more ruby-fied. In the event that you do have, or decide to create a session model the following code may work in your task (warning: untested):
Session.destroy_all("created_at" < (Time.now - 1.day))
Hope the above snippet solves at least one of your ActiveRecord session woes.
Check back soon.