mys3ql 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +3 -13
- data/bin/mys3ql +19 -28
- data/lib/mys3ql/conductor.rb +11 -2
- data/lib/mys3ql/mysql.rb +9 -3
- data/lib/mys3ql/s3.rb +32 -31
- data/lib/mys3ql/shell.rb +1 -1
- data/lib/mys3ql/version.rb +1 -1
- data/mys3ql.gemspec +1 -4
- metadata +6 -22
- data/CHANGELOG.md +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5c654cea5796fd8510c97cadadfd2eec223711f0b9c67c71b6050af4a79e7223
|
4
|
+
data.tar.gz: 621782acd4a75e1be1c292621bae70aeecfc758a95a364de5201ed5f42c1b79a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7288bf4d3b1f9a208d19486ca5e7d8515fb3a97b1a66dee603f44c4571e8937c1a743a66963610f3dd744136aaa7fa506b44171c94bb9272253c69e09e50aa2c
|
7
|
+
data.tar.gz: 01a4dc81218fd10dd69f4770e6aeb933e634360033d6adcb85ca4a48528e8c101e60f25ec29223506b96dfb321f91cc5fdbe7999e12fde8458f5a22fbbb9c6cb
|
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
Simple backup of your MySQL database onto Amazon S3.
|
4
4
|
|
5
|
+
See [Example: mysqldump + mysqlbinlog for Backup and Restore](https://dev.mysql.com/doc/refman/5.7/en/mysqlbinlog-backup.html#mysqlbinlog-backup-example).
|
6
|
+
|
5
7
|
|
6
8
|
## Quick start
|
7
9
|
|
@@ -79,20 +81,8 @@ N.B. the binary logs contain updates to all the databases on the server. This m
|
|
79
81
|
Marc-André Cournoyer's [mysql_s3_backup](https://github.com/macournoyer/mysql_s3_backup).
|
80
82
|
|
81
83
|
|
82
|
-
## To Do
|
83
|
-
|
84
|
-
- tests ;)
|
85
|
-
- remove old dump files (s3)
|
86
|
-
- (restore from non-latest dump)
|
87
|
-
|
88
|
-
|
89
|
-
## Questions, Problems, Feedback
|
90
|
-
|
91
|
-
Please use the GitHub [issue tracker](https://github.com/airblade/mys3ql/issues) or email me.
|
92
|
-
|
93
|
-
|
94
84
|
## Intellectual property
|
95
85
|
|
96
|
-
Copyright 2011 Andy Stewart (boss@airbladesoftware.com).
|
86
|
+
Copyright 2011-2021 Andy Stewart (boss@airbladesoftware.com).
|
97
87
|
|
98
88
|
Released under the MIT licence.
|
data/bin/mys3ql
CHANGED
@@ -1,35 +1,26 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
lib_dir = File.join(File.dirname(__FILE__), '..', 'lib')
|
4
|
-
$LOAD_PATH.unshift lib_dir if File.directory?(lib_dir)
|
1
|
+
#!/usr/bin/env ruby
|
5
2
|
|
3
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
6
4
|
require 'mys3ql'
|
7
|
-
require '
|
8
|
-
|
9
|
-
Main do
|
10
|
-
# consider using modes as/when we need command-specific arguments (e.g. restore specific backup)
|
11
|
-
argument 'command' do
|
12
|
-
validate { |command| %w[ full incremental restore ].include? command }
|
13
|
-
description 'specifies the operation to perform [full | incremental | restore]'
|
14
|
-
end
|
5
|
+
require 'optparse'
|
15
6
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
defaults '~/.mys3ql'
|
20
|
-
end
|
7
|
+
params = {}
|
8
|
+
op = OptionParser.new do |opts|
|
9
|
+
opts.banner = 'Usage: mys3ql <full|incremental|restore> <[args]>'
|
21
10
|
|
22
|
-
|
23
|
-
|
11
|
+
opts.on '-c', '--config CONFIG', 'Load configuration from YAML file (default ~/.mys3ql)'
|
12
|
+
opts.on_tail '-d', '--debug', 'Be verbose'
|
13
|
+
opts.on_tail '-v', '--version', 'Print version' do
|
14
|
+
puts "mys3ql v#{Mys3ql::VERSION}"
|
15
|
+
exit
|
24
16
|
end
|
17
|
+
end
|
18
|
+
op.parse!(into: params)
|
25
19
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
puts "mys3ql v#{Mys3ql::VERSION}"
|
31
|
-
exit
|
32
|
-
end
|
33
|
-
Mys3ql::Conductor.run params[:command].value, params[:config].value, params[:debug].given?
|
34
|
-
end
|
20
|
+
params[:command] = ARGV[0]
|
21
|
+
unless %w[full incremental restore].include? params[:command]
|
22
|
+
puts op.help
|
23
|
+
exit 1
|
35
24
|
end
|
25
|
+
|
26
|
+
Mys3ql::Conductor.run params[:command], params[:config], params[:debug]
|
data/lib/mys3ql/conductor.rb
CHANGED
@@ -18,6 +18,10 @@ module Mys3ql
|
|
18
18
|
@s3 = S3.new @config
|
19
19
|
end
|
20
20
|
|
21
|
+
# Dumps the database and uploads it to S3.
|
22
|
+
# Copies the uploaded file to the key :latest.
|
23
|
+
# Deletes binary logs from the file system.
|
24
|
+
# Deletes binary logs from S3.
|
21
25
|
def full
|
22
26
|
@mysql.dump
|
23
27
|
@s3.store @mysql.dump_file
|
@@ -25,13 +29,18 @@ module Mys3ql
|
|
25
29
|
@s3.delete_bin_logs
|
26
30
|
end
|
27
31
|
|
32
|
+
# Uploads mysql's binary logs to S3.
|
33
|
+
# The binary logs are left on the file system.
|
34
|
+
# Log files already on S3 are not re-uploaded.
|
28
35
|
def incremental
|
29
36
|
@mysql.each_bin_log do |log|
|
30
37
|
@s3.store log, false
|
31
38
|
end
|
32
39
|
end
|
33
40
|
|
34
|
-
#
|
41
|
+
# Downloads the latest dump from S3 and loads it into the database.
|
42
|
+
# Downloads each binary log from S3 and loads it into the database.
|
43
|
+
# Downloaded files are removed from the file system.
|
35
44
|
def restore
|
36
45
|
# get latest dump
|
37
46
|
with_temp_file do |file|
|
@@ -48,7 +57,7 @@ module Mys3ql
|
|
48
57
|
end
|
49
58
|
|
50
59
|
# NOTE: not sure about this:
|
51
|
-
puts "You might want to flush mysql's logs..."
|
60
|
+
# puts "You might want to flush mysql's logs..."
|
52
61
|
end
|
53
62
|
|
54
63
|
def debug=(val)
|
data/lib/mys3ql/mysql.rb
CHANGED
@@ -13,6 +13,8 @@ module Mys3ql
|
|
13
13
|
#
|
14
14
|
|
15
15
|
def dump
|
16
|
+
# --master-data=2 include the current binary log coordinates in the log file
|
17
|
+
# --delete-master-logs delete binary log files
|
16
18
|
cmd = "#{@config.bin_path}mysqldump"
|
17
19
|
cmd += ' --quick --single-transaction --create-options --no-tablespaces'
|
18
20
|
cmd += ' --flush-logs --master-data=2 --delete-master-logs' if binary_logging?
|
@@ -36,14 +38,18 @@ module Mys3ql
|
|
36
38
|
|
37
39
|
# flushes logs, yields each bar the last to the block
|
38
40
|
def each_bin_log(&block)
|
41
|
+
# FLUSH LOGS Closes and reopens any log file, including binary logs,
|
42
|
+
# to which the server is writing. For binary logs, the sequence
|
43
|
+
# number of the binary log file is incremented by one relative to
|
44
|
+
# the previous file.
|
45
|
+
# https://dev.mysql.com/doc/refman/5.7/en/flush.html#flush-logs
|
46
|
+
# https://dev.mysql.com/doc/refman/5.7/en/flush.html#flush-binary-logs
|
39
47
|
execute 'flush logs'
|
40
48
|
logs = Dir.glob("#{@config.bin_log}.[0-9]*").sort_by { |f| f[/\d+/].to_i }
|
41
|
-
logs_to_backup = logs[0..-2] # all logs except the last, which is
|
49
|
+
logs_to_backup = logs[0..-2] # all logs except the last, which is newly created
|
42
50
|
logs_to_backup.each do |log_file|
|
43
51
|
yield log_file
|
44
52
|
end
|
45
|
-
# delete binlogs from file system
|
46
|
-
#execute "purge master logs to '#{File.basename(logs[-1])}'"
|
47
53
|
end
|
48
54
|
|
49
55
|
#
|
data/lib/mys3ql/s3.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'mys3ql/shell'
|
2
|
-
require '
|
2
|
+
require 'awd-sdk-s3'
|
3
3
|
|
4
4
|
module Mys3ql
|
5
5
|
class S3
|
@@ -7,7 +7,6 @@ module Mys3ql
|
|
7
7
|
|
8
8
|
def initialize(config)
|
9
9
|
@config = config
|
10
|
-
Fog::Logger[:warning] = nil
|
11
10
|
end
|
12
11
|
|
13
12
|
def store(file, dump = true)
|
@@ -15,20 +14,22 @@ module Mys3ql
|
|
15
14
|
s3_file = save file, key
|
16
15
|
if dump && s3_file
|
17
16
|
copy_key = key_for :latest
|
18
|
-
s3_file.
|
17
|
+
s3_file.copy_to key: copy_key
|
19
18
|
log "s3: copied #{key} to #{copy_key}"
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
23
22
|
def delete_bin_logs
|
24
23
|
each_bin_log do |file|
|
25
|
-
file.
|
24
|
+
file.delete
|
26
25
|
log "s3: deleted #{file.key}"
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
29
|
def each_bin_log(&block)
|
31
|
-
bucket.
|
30
|
+
bucket.objects(prefix: bin_logs_prefix)
|
31
|
+
.sort_by { |file| file.key[/\d+/].to_i }
|
32
|
+
.each do |file|
|
32
33
|
yield file
|
33
34
|
end
|
34
35
|
end
|
@@ -41,26 +42,28 @@ module Mys3ql
|
|
41
42
|
private
|
42
43
|
|
43
44
|
def get(s3_key, local_file_name)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
s3.get_object(
|
46
|
+
response_target: local_file_name,
|
47
|
+
bucket: @config.bucket,
|
48
|
+
key: s3_key
|
49
|
+
)
|
48
50
|
log "s3: pulled #{s3_key} to #{local_file_name}"
|
49
51
|
end
|
50
52
|
|
51
|
-
# returns Fog::Storage::AWS::File if we pushed, nil otherwise.
|
52
53
|
def save(local_file_name, s3_key)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
:key => s3_key,
|
57
|
-
:body => File.open(local_file_name),
|
58
|
-
:storage_class => 'STANDARD_IA',
|
59
|
-
:public => false
|
60
|
-
)
|
61
|
-
log "s3: pushed #{local_file_name} to #{s3_key}"
|
62
|
-
s3_file
|
54
|
+
if bucket.object(s3_key).exists?
|
55
|
+
log "s3: skipped #{local_file_name} - #{s3_key} exists"
|
56
|
+
return
|
63
57
|
end
|
58
|
+
|
59
|
+
s3_file = bucket.put_object(
|
60
|
+
key: s3_key,
|
61
|
+
body: File.open(local_file_name),
|
62
|
+
storage_class: 'STANDARD_IA',
|
63
|
+
acl: 'private'
|
64
|
+
)
|
65
|
+
log "s3: pushed #{local_file_name} to #{s3_key}"
|
66
|
+
s3_file
|
64
67
|
end
|
65
68
|
|
66
69
|
def key_for(kind, file = nil)
|
@@ -74,23 +77,22 @@ module Mys3ql
|
|
74
77
|
|
75
78
|
def s3
|
76
79
|
@s3 ||= begin
|
77
|
-
|
78
|
-
:
|
79
|
-
:
|
80
|
-
:
|
81
|
-
:region => @config.region
|
80
|
+
client = Aws::S3::Client.new(
|
81
|
+
secret_access_key: @config.secret_access_key,
|
82
|
+
access_key_id: @config.access_key_id,
|
83
|
+
region: @config.region
|
82
84
|
)
|
83
85
|
log 's3: connected'
|
84
|
-
|
86
|
+
client
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
88
90
|
def bucket
|
89
|
-
@
|
90
|
-
|
91
|
-
raise "S3 bucket #{@config.bucket} not found" unless
|
91
|
+
@bucket ||= begin
|
92
|
+
b = Aws::S3::Bucket.new @config.bucket, client: s3
|
93
|
+
raise "S3 bucket #{@config.bucket} not found" unless b.exists?
|
92
94
|
log "s3: opened bucket #{@config.bucket}"
|
93
|
-
|
95
|
+
b
|
94
96
|
end
|
95
97
|
end
|
96
98
|
|
@@ -105,6 +107,5 @@ module Mys3ql
|
|
105
107
|
def bin_logs_exist?
|
106
108
|
@config.bin_log && @config.bin_log.length > 0 && File.exist?(@config.bin_log)
|
107
109
|
end
|
108
|
-
|
109
110
|
end
|
110
111
|
end
|
data/lib/mys3ql/shell.rb
CHANGED
data/lib/mys3ql/version.rb
CHANGED
data/mys3ql.gemspec
CHANGED
@@ -11,14 +11,11 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.summary = 'Simple backup of your MySql database onto Amazon S3.'
|
12
12
|
s.description = s.summary
|
13
13
|
|
14
|
-
s.rubyforge_project = "mys3ql"
|
15
|
-
|
16
14
|
s.files = `git ls-files`.split("\n")
|
17
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
16
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
17
|
s.require_paths = ["lib"]
|
20
18
|
|
21
|
-
s.add_dependency '
|
22
|
-
s.add_dependency 'fog', '~> 1.19.0'
|
19
|
+
s.add_dependency 'aws-sdk-s3', '~> 1'
|
23
20
|
s.add_development_dependency 'rake'
|
24
21
|
end
|
metadata
CHANGED
@@ -1,43 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mys3ql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Stewart
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: aws-sdk-s3
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: fog
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 1.19.0
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 1.19.0
|
26
|
+
version: '1'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: rake
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -61,7 +47,6 @@ extensions: []
|
|
61
47
|
extra_rdoc_files: []
|
62
48
|
files:
|
63
49
|
- ".gitignore"
|
64
|
-
- CHANGELOG.md
|
65
50
|
- Gemfile
|
66
51
|
- README.md
|
67
52
|
- Rakefile
|
@@ -92,8 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
77
|
- !ruby/object:Gem::Version
|
93
78
|
version: '0'
|
94
79
|
requirements: []
|
95
|
-
|
96
|
-
rubygems_version: 2.5.2.3
|
80
|
+
rubygems_version: 3.1.2
|
97
81
|
signing_key:
|
98
82
|
specification_version: 4
|
99
83
|
summary: Simple backup of your MySql database onto Amazon S3.
|
data/CHANGELOG.md
DELETED