class S3MysqlBackup
Public Class Methods
new(db_name, path_to_config)
click to toggle source
# File lib/s3_mysql_backup.rb, line 11 def initialize(db_name, path_to_config) @db_name = db_name @path_to_config = path_to_config self end
Public Instance Methods
run()
click to toggle source
# File lib/s3_mysql_backup.rb, line 18 def run ensure_backup_dir_exists connect_to_s3 remove_old_backups mail_notification(dump_db) end
Protected Instance Methods
config()
click to toggle source
# File lib/s3_mysql_backup.rb, line 28 def config defaults = { "dump_host" => "localhost", "mail_domain" => "smtp.gmail.com", "mail_port" => "587", "mail_authentication" => :login, "backup_dir" => "~/s3_mysql_backups", } if @s3config.nil? @s3config = @path_to_config.is_a?(Hash) ? defaults.merge(stringify_keys(@path_to_config)) : defaults.merge(YAML::load_file(@path_to_config)) # Backcompat for gmail_* keys @s3config.keys.each do |key| @s3config[key.sub(/^gmail/, "mail")] = @s3config.delete(key) end end @s3config end
connect_to_s3()
click to toggle source
# File lib/s3_mysql_backup.rb, line 49 def connect_to_s3 @s3utils ||= S3Utils.new(config['s3_access_key_id'], config['s3_secret_access_key'], config['s3_bucket'], config['s3_server'], config['s3_region']) end
dump_db()
click to toggle source
make the DB backup file
# File lib/s3_mysql_backup.rb, line 54 def dump_db filename = Time.now.strftime("#{@backup_dir}/#{@db_name}.%Y%m%d.%H%M%S.sql.gz") mysqldump = `which mysqldump`.to_s.strip `#{mysqldump} --host='#{config['dump_host']}' --user='#{config['dump_user']}' --password='#{config['dump_pass']}' '#{@db_name}' | gzip > #{filename}` @s3utils.store(filename, config['remote_dir']) filename end
ensure_backup_dir_exists()
click to toggle source
# File lib/s3_mysql_backup.rb, line 62 def ensure_backup_dir_exists @backup_dir = File.expand_path(config['backup_dir']) FileUtils.mkdir_p @backup_dir end
human_size(num, unit='bytes')
click to toggle source
# File lib/s3_mysql_backup.rb, line 67 def human_size(num, unit='bytes') units = %w(bytes KB MB GB TB PB EB ZB YB) if num <= 1024 "#{"%0.2f"%num} #{unit}" else human_size(num/1024.0, units[units.index(unit)+1]) end end
mail_notification(filename)
click to toggle source
# File lib/s3_mysql_backup.rb, line 76 def mail_notification(filename) return unless config['mail_to'] stats = File.stat(filename) subject = "sql backup: #{@db_name}: #{human_size(stats.size)}" mail_from = config['mail_from'] ? config['mail_from'] : config['mail_user'] content = [] content << "From: #{mail_from}" content << "To: #{config['mail_to']}" content << "Subject: #{subject}" content << "Date: #{Time.now.rfc2822}" content << "\n#{File.basename(filename)}\n" # body content = content.join("\n") smtp = Net::SMTP.new(config["mail_domain"], config["mail_port"]) smtp.enable_starttls unless config["mail_start_tls"] == false smtp.start( config["mail_domain"].to_s, config['mail_user'], (config['mail_pass'].nil? ? nil : config[:mail_pass].to_s), config['mail_authentication'] ) do smtp.send_message(content, mail_from, config['mail_to']) end end
remove_old_backups()
click to toggle source
remove old backups
- keep 30 days complete - keep 90 days weekly beyond that - keep only monthly after that
# File lib/s3_mysql_backup.rb, line 106 def remove_old_backups today = Date.today weekly = (today - 30) monthly = (today - 120) path = File.expand_path(config['backup_dir']) Dir["#{path}/*.sql.gz"].each do |name| date = name.split('.')[1] filedate = Date.strptime(date, '%Y%m%d') if filedate < weekly && filedate >= monthly # keep weeklies and also first of month unless filedate.wday == 0 || filedate.day == 1 FileUtils.rm_f(name) @s3utils.delete(name) end elsif filedate < monthly # delete all old local files FileUtils.rm_f(name) # keep just first of month in S3 unless filedate.day == 1 @s3utils.delete(name) end end end # Dir.each end
stringify_keys(hash)
click to toggle source
# File lib/s3_mysql_backup.rb, line 135 def stringify_keys(hash) hash.keys.each do |key| hash[key.to_s] = hash.delete(key) end hash end