airblade-mysql_s3_backup 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/config/sample.yml +2 -1
- data/lib/mysql_s3_backup/backup.rb +51 -34
- data/lib/mysql_s3_backup/config.rb +8 -7
- data/mysql_s3_backup.gemspec +2 -1
- metadata +28 -4
data/config/sample.yml
CHANGED
@@ -1,61 +1,78 @@
|
|
1
1
|
require 'tempfile'
|
2
2
|
require 'lockfile'
|
3
|
+
require 'terminator'
|
3
4
|
|
4
5
|
module MysqlS3Backup
|
5
6
|
class Backup
|
6
|
-
attr_reader :mysql, :bucket
|
7
|
-
|
8
|
-
def initialize(mysql, bucket)
|
7
|
+
attr_reader :mysql, :bucket, :timeout
|
8
|
+
|
9
|
+
def initialize(mysql, bucket, timeout=30)
|
9
10
|
@mysql = mysql
|
10
11
|
@bucket = bucket
|
12
|
+
@timeout = timeout
|
11
13
|
@bin_log_prefix = "#{@mysql.database}/bin_logs"
|
12
14
|
end
|
13
|
-
|
15
|
+
|
14
16
|
def full(name=make_new_name)
|
15
17
|
lock do
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
timeout do
|
19
|
+
# When the full backup runs it delete any binary log files that might already exist
|
20
|
+
# in the bucket. Otherwise the restore will try to restore them even though they’re
|
21
|
+
# older than the full backup.
|
22
|
+
@bucket.delete_all @bin_log_prefix
|
23
|
+
|
24
|
+
with_temp_file do |file|
|
25
|
+
@mysql.dump(file)
|
26
|
+
@bucket.store(dump_file_name(name), file)
|
27
|
+
@bucket.copy(dump_file_name(name), dump_file_name("latest"))
|
28
|
+
end
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
28
|
-
|
32
|
+
|
29
33
|
def incremental
|
30
34
|
lock do
|
31
|
-
|
32
|
-
@
|
35
|
+
timeout do
|
36
|
+
@mysql.each_bin_log do |log|
|
37
|
+
@bucket.store "#{@bin_log_prefix}/#{File.basename(log)}", log
|
38
|
+
end
|
33
39
|
end
|
34
40
|
end
|
35
41
|
end
|
36
42
|
alias :inc :incremental
|
37
|
-
|
43
|
+
|
38
44
|
def restore(name="latest")
|
39
45
|
lock do
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
46
|
+
timeout do
|
47
|
+
# restore from the dump file
|
48
|
+
with_temp_file do |file|
|
49
|
+
@bucket.fetch(dump_file_name(name), file)
|
50
|
+
@mysql.restore(file)
|
51
|
+
end
|
52
|
+
|
53
|
+
if name == "latest"
|
54
|
+
# Restoring binary log files
|
55
|
+
@bucket.find("#{@bin_log_prefix}/").sort.each do |log|
|
56
|
+
with_temp_file do |file|
|
57
|
+
@bucket.fetch log, file
|
58
|
+
@mysql.apply_bin_log file
|
59
|
+
end
|
52
60
|
end
|
53
61
|
end
|
54
62
|
end
|
55
63
|
end
|
56
64
|
end
|
57
|
-
|
65
|
+
|
58
66
|
private
|
67
|
+
|
68
|
+
def timeout
|
69
|
+
result = nil
|
70
|
+
Terminator.terminate @timeout do
|
71
|
+
result = yield
|
72
|
+
end
|
73
|
+
result
|
74
|
+
end
|
75
|
+
|
59
76
|
def lock
|
60
77
|
result = nil
|
61
78
|
Lockfile("mysql_s3_backup_lock", :retries => 0) do
|
@@ -63,16 +80,16 @@ module MysqlS3Backup
|
|
63
80
|
end
|
64
81
|
result
|
65
82
|
end
|
66
|
-
|
83
|
+
|
67
84
|
def dump_file_name(name)
|
68
85
|
raise ArgumentError, "Need a backup name" unless name.is_a?(String)
|
69
86
|
"#{@mysql.database}/dumps/#{name}.sql.gz"
|
70
87
|
end
|
71
|
-
|
88
|
+
|
72
89
|
def make_new_name
|
73
90
|
Time.now.utc.strftime("%Y%m%d%H%M")
|
74
91
|
end
|
75
|
-
|
92
|
+
|
76
93
|
def with_temp_file
|
77
94
|
dump_file = Tempfile.new("mysql-dump")
|
78
95
|
yield dump_file.path
|
@@ -81,4 +98,4 @@ module MysqlS3Backup
|
|
81
98
|
dump_file.close!
|
82
99
|
end
|
83
100
|
end
|
84
|
-
end
|
101
|
+
end
|
@@ -3,28 +3,29 @@ require "yaml"
|
|
3
3
|
module MysqlS3Backup
|
4
4
|
class Config
|
5
5
|
attr_reader :mysql_config, :s3_config, :bucket
|
6
|
-
|
6
|
+
|
7
7
|
def initialize(config)
|
8
8
|
config = config.symbolize_keys
|
9
9
|
@mysql_config = config[:mysql].symbolize_keys
|
10
10
|
@s3_config = config[:s3].symbolize_keys
|
11
11
|
@bucket = @s3_config.delete(:bucket)
|
12
|
+
@timeout = @s3_config.delete(:timeout)
|
12
13
|
end
|
13
|
-
|
14
|
+
|
14
15
|
def mysql
|
15
16
|
MysqlS3Backup::Mysql.new(@mysql_config)
|
16
17
|
end
|
17
|
-
|
18
|
+
|
18
19
|
def bucket
|
19
20
|
MysqlS3Backup::Bucket.new(@bucket, @s3_config)
|
20
21
|
end
|
21
|
-
|
22
|
+
|
22
23
|
def backup
|
23
|
-
MysqlS3Backup::Backup.new(mysql, bucket)
|
24
|
+
MysqlS3Backup::Backup.new(mysql, bucket, @timeout)
|
24
25
|
end
|
25
|
-
|
26
|
+
|
26
27
|
def self.from_yaml_file(file)
|
27
28
|
new YAML.load_file(file)
|
28
29
|
end
|
29
30
|
end
|
30
|
-
end
|
31
|
+
end
|
data/mysql_s3_backup.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "airblade-mysql_s3_backup"
|
3
|
-
s.version = "0.0.
|
3
|
+
s.version = "0.0.3"
|
4
4
|
|
5
5
|
s.authors = ["Marc-Andre Cournoyer", "Andrew Stewart"]
|
6
6
|
s.email = "boss@airbladesoftware.com"
|
@@ -14,4 +14,5 @@ Gem::Specification.new do |s|
|
|
14
14
|
|
15
15
|
s.add_dependency "aws-s3"
|
16
16
|
s.add_dependency "lockfile"
|
17
|
+
s.add_dependency "terminator"
|
17
18
|
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: airblade-mysql_s3_backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Marc-Andre Cournoyer
|
@@ -15,16 +16,18 @@ autorequire:
|
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2010-
|
19
|
+
date: 2010-08-18 00:00:00 +01:00
|
19
20
|
default_executable:
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
22
23
|
name: aws-s3
|
23
24
|
prerelease: false
|
24
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
25
27
|
requirements:
|
26
28
|
- - ">="
|
27
29
|
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
28
31
|
segments:
|
29
32
|
- 0
|
30
33
|
version: "0"
|
@@ -34,14 +37,30 @@ dependencies:
|
|
34
37
|
name: lockfile
|
35
38
|
prerelease: false
|
36
39
|
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
37
41
|
requirements:
|
38
42
|
- - ">="
|
39
43
|
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
40
45
|
segments:
|
41
46
|
- 0
|
42
47
|
version: "0"
|
43
48
|
type: :runtime
|
44
49
|
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: terminator
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
type: :runtime
|
63
|
+
version_requirements: *id003
|
45
64
|
description:
|
46
65
|
email: boss@airbladesoftware.com
|
47
66
|
executables:
|
@@ -51,6 +70,7 @@ extensions: []
|
|
51
70
|
extra_rdoc_files: []
|
52
71
|
|
53
72
|
files:
|
73
|
+
- airblade-mysql_s3_backup-0.0.3.gem
|
54
74
|
- bin/mysql_s3_backup
|
55
75
|
- config/sample.yml
|
56
76
|
- lib/mysql_s3_backup/backup.rb
|
@@ -78,23 +98,27 @@ rdoc_options: []
|
|
78
98
|
require_paths:
|
79
99
|
- lib
|
80
100
|
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
81
102
|
requirements:
|
82
103
|
- - ">="
|
83
104
|
- !ruby/object:Gem::Version
|
105
|
+
hash: 3
|
84
106
|
segments:
|
85
107
|
- 0
|
86
108
|
version: "0"
|
87
109
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
88
111
|
requirements:
|
89
112
|
- - ">="
|
90
113
|
- !ruby/object:Gem::Version
|
114
|
+
hash: 3
|
91
115
|
segments:
|
92
116
|
- 0
|
93
117
|
version: "0"
|
94
118
|
requirements: []
|
95
119
|
|
96
120
|
rubyforge_project:
|
97
|
-
rubygems_version: 1.3.
|
121
|
+
rubygems_version: 1.3.7
|
98
122
|
signing_key:
|
99
123
|
specification_version: 3
|
100
124
|
summary: A simple backup script for Mysql and S3 with incremental backups.
|