Active Record YAML Backup Solution - Drop In Rake Task And Config File To Backup Db And Directorys Of Your Choice (user Uploaded Files)
Join the DZone community and get the full member experience.
Join For FreeEZ drop in backup rake task for your rails projects - works well - 5 - 10 min set up, one rake file and one config file
backs up db and any directory's to any number of servers with rsync
BSD License or whatever, but it would be cool if you told me your using it
2007 ISS http://industrialstrengthinc.com
this is a sample config file and a rake task you can drop into any rails project to do backups, easy to automate.
Backs up your specified environment db to activerecord yml files (one per table) and zips them up in a human readable timestamped file
syncs that and any other set of arbitrary directory's to any number of arbitrary servers with rsync
be sure to set ssh key based logins
to run: rake backup
also: rake backup:db, rake backup:restoredb (promts for a file created by backup:db), rake backup:push (to push out what u got)
note: this uses something like 30 lines of code from some blog site I got it from that I cant recall, yay for that guy, thanks
## example crontab entry:
3 * * * * cd /rails_deployment_dir/current && nice rake backup RAILS_ENV=production >> /rails_deployment_dir/production_backup_system.log
## config file - goes in config/backup.yml
production:
dirs:
- db/backups
- public/uploaded_images
servers:
- name: backup server number 1
host: gridserver.com
port: 22
user: blah@whatever.com
dir: /home/blah/backups
- name: backup server two
host: kradradio.com
port: 22
user: kraduser
dir: /home/kraduser/backups_from_my_rails_proj
development:
dirs:
- db/backups
- public/uploaded_images
servers:
- name: local self
host: localhost
port: 5222
user: oneman
dir: /home/oneman/Documents/development_backup
## rake file lib/tasks/backup.rake
desc "Backup Everything Specified in config/backup.yml"
task :backup => [ "backup:db", "backup:push"]
namespace :backup do
RAILS_APPDIR = RAILS_ROOT.sub("/config/..","")
def interesting_tables
ActiveRecord::Base.connection.tables.sort.reject! do |tbl|
['schema_info', 'sessions', 'public_exceptions'].include?(tbl)
end
end
desc "Push backup to remote server"
task :push => [:environment] do
FileUtils.chdir(RAILS_APPDIR)
backup_config = YAML::load( File.open( 'config/backup.yml' ) )[RAILS_ENV]
for server in backup_config["servers"]
puts "Backing up #{RAILS_ENV} directorys #{backup_config['dirs'].join(', ')} to #{server['name']}"
puts "Time is " + Time.now.rfc2822 + "\n\n"
for dir in backup_config["dirs"]
local_dir = RAILS_APPDIR + "/" + dir + "/"
remote_dir = server['dir'] + "/" + dir.split("/").last + "/"
puts "Syncing #{local_dir} to #{server['host']}#{remote_dir}"
sh "/usr/bin/rsync -avz -e 'ssh -p#{server['port']} ' #{local_dir} #{server['user']}@#{server['host']}:#{remote_dir}"
end
puts "Completed backup to #{server['name']}\n\n"
end
end
task :storedb => :environment do
backupdir = RAILS_APPDIR + '/db/backup'
FileUtils.mkdir_p(backupdir)
FileUtils.chdir(backupdir)
puts "Dumping database to activerecord yaml files in #{backupdir}"
interesting_tables.each do |tbl|
klass = tbl.classify.constantize
puts "Writing #{tbl}..."
File.open("#{tbl}.yml", 'w+') { |f| YAML.dump klass.find(:all).collect(&:attributes), f }
end
puts "Database Dumped.\n\n"
end
desc "Dump Current Environment Db to file"
task :db => [:environment, :storedb ] do
backupdir = RAILS_APPDIR + '/db/backup'
archivedir = RAILS_APPDIR + '/db/backups'
backup_filename = "#{RAILS_ENV}_db_backup_#{Time.now.strftime("%B.%d.%Y_at_%I.%M.%S%p_%Z")}.tar.bz2"
FileUtils.mkdir_p(archivedir)
puts "Archiving #{backupdir} yaml files to #{backup_filename}\n\n"
`tar -C #{backupdir} -cjf #{backup_filename} *`
`mv #{backup_filename} #{archivedir}`
end
desc "Restore Current Environment Db from a file"
task :restoredb => [:environment] do
backupdir = RAILS_APPDIR + '/db/backup'
archivedir = RAILS_APPDIR + '/db/backups'
print "Input a file to load into the db: #{archivedir}/"
backup_filename = STDIN.gets.chomp
puts "Loading backup file: #{backup_filename}"
FileUtils.chdir(archivedir)
`tar -xjf #{backup_filename}`
`mv *.yml #{backupdir}`
FileUtils.mkdir_p(backupdir)
FileUtils.chdir(backupdir)
interesting_tables.each do |tbl|
puts "Clearing #{tbl} table.."
ActiveRecord::Base.connection.execute "TRUNCATE #{tbl}"
puts "Loading #{tbl} backup file..."
table = YAML.load_file("#{tbl}.yml")
if table.length > 0 && table.first.key?("id")
highestid = 0
table.each do |fixture|
if fixture["id"] > highestid
highestid = fixture["id"]
end
end
ActiveRecord::Base.connection.execute "SELECT setval('#{tbl}_id_seq',#{highestid})"
puts "Setting #{tbl}_id sequence to #{highestid}"
end
#klass = tbl.classify.constantize
ActiveRecord::Base.transaction do
puts "Inserting #{table.length} values into #{tbl}"
table.each do |fixture|
ActiveRecord::Base.connection.execute "INSERT INTO #{tbl} (#{fixture.keys.join(",")}) VALUES (#{fixture.values.collect { |value| ActiveRecord::Base.connection.quote(value) }.join(",")})", 'Fixture Insert'
end
puts "#{tbl} table restored.\n\n"
end
end
end
end
YAML
Backup
Task (computing)
Record (computer science)
Opinions expressed by DZone contributors are their own.
Comments