-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdb-backup.rb
executable file
·86 lines (71 loc) · 2.3 KB
/
db-backup.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/env ruby
DAYS_TO_KEEP_HOURLY = ENV['DAYS_TO_KEEP_HOURLY'] ? ENV['DAYS_TO_KEEP_HOURLY'].to_i : 7
DAYS_TO_KEEP_DAILY = ENV['DAYS_TO_KEEP_DAILY'] ? ENV['DAYS_TO_KEEP_DAILY'].to_i : 30
require "date"
require "fileutils"
require "optparse"
OptionParser.new do |opts|
opts.banner = "Usage: db-backup.rb [options] target-dir [dump-command]"
opts.on("--dbms=DBMS", 'Database management system (if not given, second argument is required)') do |a|
@dbms = a
end
opts.on("-d", "--db=DATABASE", 'Name of database to backup') do |a|
@db = a
end
end.parse!
raise "Database required" if @dbms && !@db
@dir = ARGV[0] || raise("Target directory required")
@db_cmd = ARGV[1]
raise "Dump command required if DBMS not given" if !@dbms && !@db_cmd
def backup_dir_for_date(date)
"#{@dir}/#{date.strftime('%Y/%m/%d')}"
end
def backup_file_list(dir)
Dir["#{dir}/*.gz"].sort_by { |f| File.mtime(f) }
end
def timestamp
Time.now.strftime('%Y-%m-%d-%H%M%S')
end
def has_hourly_backups?(dir)
backup_file_list(dir).size > 1
end
def delete_old_hourly_backups
i = 1
while has_hourly_backups?(dir = backup_dir_for_date(Date.today - DAYS_TO_KEEP_HOURLY - i)) do
backup_file_list(dir)[1..-1].each{ |f| FileUtils.rm(f) }
i += 1
end
end
def delete_very_old_daily_backups
i = 1
while Dir.exist?(dir = backup_dir_for_date(Date.today - DAYS_TO_KEEP_DAILY - i)) &&
# keep one per month (parent dir) (ideally the first of the month)
dir.split('/')[-1] != '01' && Dir[File.expand_path('../*', dir)].size > 1 do
FileUtils.rm_rf(dir)
i += 1
end
end
def create_new_backup
FileUtils.mkdir_p(dir = backup_dir_for_date(Date.today))
FileUtils.cd dir
filename = "#{@db}-#{timestamp}"
case @dbms
when nil
full_filename = "#{timestamp}.sql"
`#{@db_cmd} > #{full_filename}`
`gzip #{full_filename}`
when 'mongo'
full_filename = "#{filename}.tar.gz"
`/usr/bin/env mongodump -h 127.0.0.1 -d #{@db} -o .`
# Mongodump names backup directory after db, no choice. Add timestamp before tar-ing.
FileUtils.mv @db, filename
`tar -czf #{full_filename} #{filename}`
FileUtils.rm_rf(filename)
else
raise "DBMS not implemented"
end
puts "Finished backup to #{FileUtils.pwd}/#{full_filename}"
end
delete_old_hourly_backups
delete_very_old_daily_backups
create_new_backup