mys3ql 1.1.0 → 1.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e54e18bc02f3e450ff0b3bbcf538d110740f7656
4
- data.tar.gz: d9a68227ab366c3cfae81f56116c723c0ccb4bb4
2
+ SHA256:
3
+ metadata.gz: 5c654cea5796fd8510c97cadadfd2eec223711f0b9c67c71b6050af4a79e7223
4
+ data.tar.gz: 621782acd4a75e1be1c292621bae70aeecfc758a95a364de5201ed5f42c1b79a
5
5
  SHA512:
6
- metadata.gz: cec4e35514acad343828bfbd6c726db0a0ca3654ce54906e1cb047d242a68d3b4fb7c47bde63287b8fda3a5fe6a0c01ecec19954f92be10a523ea954fce24261
7
- data.tar.gz: e62c4784ea4161dd939f659ffa8f80d765976059149185adbf724d9eb4ffce6e2445296051cba0040d6369f9a24a028d8a0185bd12f66d4d16d259b17ac12d31
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-local-exec
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 'main'
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
- option 'config', 'c' do
17
- argument :required
18
- description 'load configuration from YAML file'
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
- option 'debug', 'd' do
23
- description 'be verbose'
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
- option 'version', 'v'
27
-
28
- def run
29
- if params[:version].given?
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]
@@ -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
- # for now only restore from latest
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 in use
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 'fog'
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.copy @config.bucket, copy_key
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.destroy
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.files.all(:prefix => "#{bin_logs_prefix}").sort_by { |file| file.key[/\d+/].to_i }.each do |file|
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
- s3_file = bucket.files.get s3_key
45
- File.open(local_file_name, 'wb') do |file|
46
- file.write s3_file.body
47
- end
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
- s3.sync_clock
54
- unless bucket.files.head(s3_key)
55
- s3_file = bucket.files.create(
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
- s = Fog::Storage.new(
78
- :provider => 'AWS',
79
- :aws_secret_access_key => @config.secret_access_key,
80
- :aws_access_key_id => @config.access_key_id,
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
- s
86
+ client
85
87
  end
86
88
  end
87
89
 
88
90
  def bucket
89
- @directory ||= begin
90
- d = s3.directories.get @config.bucket
91
- raise "S3 bucket #{@config.bucket} not found" unless d # create bucket instead (n.b. region/location)?
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
- d
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
@@ -1,5 +1,5 @@
1
1
  module Mys3ql
2
- class ShellCommandError < RuntimeError ; end
2
+ ShellCommandError = Class.new RuntimeError
3
3
 
4
4
  module Shell
5
5
  def run(command)
@@ -1,3 +1,3 @@
1
1
  module Mys3ql
2
- VERSION = '1.1.0'
2
+ VERSION = '1.2.0'
3
3
  end
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 'main', '~> 4.8.0'
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.1.0
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: 2020-12-22 00:00:00.000000000 Z
11
+ date: 2021-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: main
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: 4.8.0
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: 4.8.0
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
- rubyforge_project: mys3ql
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
@@ -1,3 +0,0 @@
1
- # Changelog
2
-
3
- [awaiting v1.0.0]