mys3ql 1.0.1 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 45f85278cadc72fb6e195a38f152bdf4540b084ecd51d328c73edada8528ec17
4
+ data.tar.gz: 33527921e258fba6bd9b3de255c6e4e9105030283164898777b2593d04b887d1
5
+ SHA512:
6
+ metadata.gz: 9201515cf1d9cc6ae53cfd0079622f09549c2026f1e86759179e32aa42fcf65699cc4f100ea621c59ae22ee018fc3bcdd3de0e931df0d3e257e3629e3e852952
7
+ data.tar.gz: 051301e9ee660ca95ac3045d78739f2c9a17d988e5433f90987595730c4b69d065a31bd05d7f4510c0bf8998c425308575c4c6f3e9c09e446bbd1c4e443fc0d9
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)') { |v| params[:config] = v }
12
+ opts.on_tail('-d', '--debug', 'Be verbose') { |v| params[:debug] = v }
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! ARGV
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,8 +13,10 @@ 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
- cmd += ' --quick --single-transaction --create-options'
19
+ cmd += ' --quick --single-transaction --create-options --no-tablespaces'
18
20
  cmd += ' --flush-logs --master-data=2 --delete-master-logs' if binary_logging?
19
21
  cmd += cli_options
20
22
  cmd += " | gzip > #{dump_file}"
@@ -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 'aws-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,24 +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
- unless bucket.files.head(s3_key)
54
- s3_file = bucket.files.create(
55
- :key => s3_key,
56
- :body => File.open(local_file_name),
57
- :public => false
58
- )
59
- log "s3: pushed #{local_file_name} to #{s3_key}"
60
- s3_file
54
+ if bucket.object(s3_key).exists?
55
+ log "s3: skipped #{local_file_name} - #{s3_key} exists"
56
+ return
61
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
62
67
  end
63
68
 
64
69
  def key_for(kind, file = nil)
@@ -72,23 +77,22 @@ module Mys3ql
72
77
 
73
78
  def s3
74
79
  @s3 ||= begin
75
- s = Fog::Storage.new(
76
- :provider => 'AWS',
77
- :aws_secret_access_key => @config.secret_access_key,
78
- :aws_access_key_id => @config.access_key_id,
79
- :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
80
84
  )
81
85
  log 's3: connected'
82
- s
86
+ client
83
87
  end
84
88
  end
85
89
 
86
90
  def bucket
87
- @directory ||= begin
88
- d = s3.directories.get @config.bucket
89
- 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?
90
94
  log "s3: opened bucket #{@config.bucket}"
91
- d
95
+ b
92
96
  end
93
97
  end
94
98
 
@@ -103,6 +107,5 @@ module Mys3ql
103
107
  def bin_logs_exist?
104
108
  @config.bin_log && @config.bin_log.length > 0 && File.exist?(@config.bin_log)
105
109
  end
106
-
107
110
  end
108
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.0.1'
2
+ VERSION = '1.2.1'
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.0.0'
19
+ s.add_dependency 'aws-sdk-s3', '~> 1'
23
20
  s.add_development_dependency 'rake'
24
21
  end
metadata CHANGED
@@ -1,81 +1,52 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mys3ql
3
- version: !ruby/object:Gem::Version
4
- hash: 21
5
- prerelease:
6
- segments:
7
- - 1
8
- - 0
9
- - 1
10
- version: 1.0.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.1
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Andy Stewart
14
- autorequire:
8
+ autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2011-11-04 00:00:00 +01:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- name: main
23
- prerelease: false
24
- version_requirements: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ~>
28
- - !ruby/object:Gem::Version
29
- hash: 31
30
- segments:
31
- - 4
32
- - 8
33
- - 0
34
- version: 4.8.0
11
+ date: 2021-02-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-s3
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1'
35
20
  type: :runtime
36
- requirement: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: fog
39
21
  prerelease: false
40
- version_requirements: &id002 !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- hash: 23
46
- segments:
47
- - 1
48
- - 0
49
- - 0
50
- version: 1.0.0
51
- type: :runtime
52
- requirement: *id002
53
- - !ruby/object:Gem::Dependency
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1'
27
+ - !ruby/object:Gem::Dependency
54
28
  name: rake
55
- prerelease: false
56
- version_requirements: &id003 !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
59
31
  - - ">="
60
- - !ruby/object:Gem::Version
61
- hash: 3
62
- segments:
63
- - 0
64
- version: "0"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
65
34
  type: :development
66
- requirement: *id003
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
67
41
  description: Simple backup of your MySql database onto Amazon S3.
68
- email:
42
+ email:
69
43
  - boss@airbladesoftware.com
70
- executables:
44
+ executables:
71
45
  - mys3ql
72
46
  extensions: []
73
-
74
47
  extra_rdoc_files: []
75
-
76
- files:
77
- - .gitignore
78
- - CHANGELOG.md
48
+ files:
49
+ - ".gitignore"
79
50
  - Gemfile
80
51
  - README.md
81
52
  - Rakefile
@@ -88,39 +59,26 @@ files:
88
59
  - lib/mys3ql/shell.rb
89
60
  - lib/mys3ql/version.rb
90
61
  - mys3ql.gemspec
91
- has_rdoc: true
92
62
  homepage: https://github.com/airblade/mys3ql
93
63
  licenses: []
94
-
95
- post_install_message:
64
+ metadata: {}
65
+ post_install_message:
96
66
  rdoc_options: []
97
-
98
- require_paths:
67
+ require_paths:
99
68
  - lib
100
- required_ruby_version: !ruby/object:Gem::Requirement
101
- none: false
102
- requirements:
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
103
71
  - - ">="
104
- - !ruby/object:Gem::Version
105
- hash: 3
106
- segments:
107
- - 0
108
- version: "0"
109
- required_rubygems_version: !ruby/object:Gem::Requirement
110
- none: false
111
- requirements:
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
112
76
  - - ">="
113
- - !ruby/object:Gem::Version
114
- hash: 3
115
- segments:
116
- - 0
117
- version: "0"
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
118
79
  requirements: []
119
-
120
- rubyforge_project: mys3ql
121
- rubygems_version: 1.6.2
122
- signing_key:
123
- specification_version: 3
80
+ rubygems_version: 3.1.2
81
+ signing_key:
82
+ specification_version: 4
124
83
  summary: Simple backup of your MySql database onto Amazon S3.
125
84
  test_files: []
126
-
data/CHANGELOG.md DELETED
@@ -1,3 +0,0 @@
1
- # Changelog
2
-
3
- [awaiting v1.0.0]