Posted filed under Ruby on Rails.

Photo by mondopiccolo

 Capistranoではdeployしても、前のソースが残っているために、すぐに前のバージョンに戻せますが、データベースはそうはいきません。

 そこで、deploy:migrationsを実行する前に自動でDBのバックアップを取るようなタスクを探してみました。
MySQL専用ですが、これでローカルのbackupsというディレクトリに、migration実行前のダンプがダウンロードされます。

require 'yaml'

desc "Backup the remote production database"
task :backup, :roles => :db, :only => { :primary => true } do
  filename = "#{application}.dump.#{Time.now.to_i}.sql.bz2"
  file = "/tmp/#{filename}"
  on_rollback { delete file }
  db = YAML::load(ERB.new(IO.read(File.join(File.dirname(__FILE__), 'database.yml'))).result)['production']
  run "mysqldump -u #{db['username']} --password=#{db['password']} #{db['database']} | bzip2 -c > #{file}"  do |ch, stream, data|
    puts data
  end
  backup_dir = File.dirname(__FILE__) + "/../backups/"
  `mkdir -p #{backup_dir}` unless File.exists?(backup_dir)
  get file, "#{backup_dir}/#{filename}"
  run "rm #{file}"
end

desc "Backup the database before running migrations"
task :before_migrate do 
  backup
end

元ネタ