backups-cli 1.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +3 -0
- data/LICENSE +7 -0
- data/README.md +256 -0
- data/Rakefile +6 -0
- data/backups-cli.gemspec +25 -0
- data/bin/backups +47 -0
- data/lib/backups.rb +19 -0
- data/lib/backups/adapter/mysql.rb +202 -0
- data/lib/backups/base.rb +70 -0
- data/lib/backups/cli.rb +51 -0
- data/lib/backups/crontab.rb +200 -0
- data/lib/backups/driver/mysql.rb +35 -0
- data/lib/backups/events.rb +40 -0
- data/lib/backups/ext/fixnum.rb +21 -0
- data/lib/backups/ext/hash.rb +8 -0
- data/lib/backups/ext/nil_class.rb +7 -0
- data/lib/backups/ext/ordered_hash.rb +11 -0
- data/lib/backups/ext/string.rb +20 -0
- data/lib/backups/listener.rb +19 -0
- data/lib/backups/listeners/notify/datadog.rb +44 -0
- data/lib/backups/listeners/notify/slack.rb +121 -0
- data/lib/backups/loader.rb +55 -0
- data/lib/backups/logger.rb +8 -0
- data/lib/backups/runner.rb +137 -0
- data/lib/backups/stats/mysql.rb +80 -0
- data/lib/backups/system.rb +54 -0
- data/lib/backups/verify/mysql.rb +180 -0
- data/lib/backups/version.rb +4 -0
- metadata +173 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3828b34e41c40252925145a874a3e7fd6532c840
|
4
|
+
data.tar.gz: 80c63eadf29e7635ae6f915e201778cd5d73a2a9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 82e51cd0ca2024470f35921864970bbb356208bbf0589a4d4dcb1f931bffeb51aca6be019f4da551c75abb1628d651ad147a06814048377969b13a11d58fefd1
|
7
|
+
data.tar.gz: 3a373562b5c61e704b8146173cd595d51de6b6f3848a100075913323e1d4f43b06271fdb4e1b7bc362656f99dad021666157169361ca9e490b0fbb12b3fcd286
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright 2016 Schibsted Products & Technology AS.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,256 @@
|
|
1
|
+
# backups-cli
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/schibsted/backups-cli.svg?branch=master)](https://travis-ci.org/schibsted/backups-cli)
|
4
|
+
|
5
|
+
This tool backups different data sources to S3.
|
6
|
+
|
7
|
+
|
8
|
+
# Usage
|
9
|
+
|
10
|
+
To see all available commands run the tool with no options:
|
11
|
+
|
12
|
+
```
|
13
|
+
% ./bin/backups
|
14
|
+
Commands:
|
15
|
+
backups crontab # Shows the crontab config
|
16
|
+
backups help [COMMAND] # Describe available commands or one specific command
|
17
|
+
backups install # Sets up the crontab for all jobs
|
18
|
+
backups ls # Lists all the configured jobs
|
19
|
+
backups show [JOB] # Shows the merged config (for a JOB or them all)
|
20
|
+
backups start [JOB] # Starts a backup JOB or all of them
|
21
|
+
backups verify JOB # Restores and verifies a backup JOB
|
22
|
+
backups version # Show current version
|
23
|
+
|
24
|
+
```
|
25
|
+
|
26
|
+
### Configuration
|
27
|
+
|
28
|
+
The look up directories for the configs are, in order:
|
29
|
+
|
30
|
+
- The value in the `BACKUPS_CONFIG_DIR` env variable
|
31
|
+
- `${HOME}/.backups-cli`
|
32
|
+
- `/etc/backups-cli`
|
33
|
+
|
34
|
+
The config directory will be the first it can find. All `*.yaml` files under
|
35
|
+
that directory will be loaded. You might find useful to organise backups into
|
36
|
+
subfolders. You can inline `BACKUPS_CONFIG_DIR` to override existing file system
|
37
|
+
directories:
|
38
|
+
|
39
|
+
BACKUPS_CONFIG_DIR="/opt/my-backups" ./bin/backups start local-mysql
|
40
|
+
|
41
|
+
|
42
|
+
### List all jobs
|
43
|
+
|
44
|
+
To list all defined jobs call the `ls` command:
|
45
|
+
|
46
|
+
```
|
47
|
+
$ ./bin/backups ls
|
48
|
+
JOB CRONTAB INSTALL ENABLED
|
49
|
+
local-mysql 0 4 * * * true true
|
50
|
+
minimal 0 4 * * * true true
|
51
|
+
```
|
52
|
+
|
53
|
+
`INSTALL` refers if a job will be installed on the crontab and `ENABLED` if it
|
54
|
+
can be run. You can run manually not installed jobs but the script will refuse
|
55
|
+
to start disabled jobs.
|
56
|
+
|
57
|
+
|
58
|
+
### Show one job details
|
59
|
+
|
60
|
+
Use the command `show` to print out json details about all the details for a
|
61
|
+
job. Note that the details presented here show the job as perceived from the
|
62
|
+
script, meaning when all the defaults have been merged. Leave the `job` argument
|
63
|
+
out to show the whole config after the app has processed all yaml files and
|
64
|
+
applied the defaults. The merge pattern is:
|
65
|
+
|
66
|
+
- Deep merge any local `default` settings into all jobs entries in the same file
|
67
|
+
- Finally deep merge the top `default` entry (in the `main.yaml` file)
|
68
|
+
|
69
|
+
These merges mean you can provide global and file fallbacks (local settings
|
70
|
+
prevail), which means you can organise the backup config files by env/adapter
|
71
|
+
type or any way you fancy.
|
72
|
+
|
73
|
+
|
74
|
+
```json
|
75
|
+
$ ./bin/backups show local-mysql | jq .
|
76
|
+
{
|
77
|
+
"s3": {
|
78
|
+
"bucket": "acme-productions-backups",
|
79
|
+
"path": "local/mysql"
|
80
|
+
},
|
81
|
+
"encryption": {
|
82
|
+
"secret": "pass"
|
83
|
+
},
|
84
|
+
"tags": {
|
85
|
+
"env": "local",
|
86
|
+
"new": null
|
87
|
+
},
|
88
|
+
"type": "mysql",
|
89
|
+
"backup": {
|
90
|
+
"connection": {
|
91
|
+
"username": "root",
|
92
|
+
"password": "root"
|
93
|
+
}
|
94
|
+
},
|
95
|
+
"_name": "mysql-local",
|
96
|
+
"_file": "/Users/pedro/.backups-cli/local/mysql.yaml"
|
97
|
+
}
|
98
|
+
```
|
99
|
+
|
100
|
+
### Add a new job
|
101
|
+
|
102
|
+
Here's the minimal backup config needed:
|
103
|
+
|
104
|
+
```yaml
|
105
|
+
---
|
106
|
+
jobs:
|
107
|
+
my-fancy-backup:
|
108
|
+
type: mysql
|
109
|
+
```
|
110
|
+
|
111
|
+
Here's a more reasonable example of job (they go under the tops `jobs` entry):
|
112
|
+
|
113
|
+
```yaml
|
114
|
+
---
|
115
|
+
jobs:
|
116
|
+
acme-productions:
|
117
|
+
type: mysql
|
118
|
+
tags:
|
119
|
+
env: local
|
120
|
+
type: test
|
121
|
+
s3:
|
122
|
+
bucket: acme-dumps
|
123
|
+
path: production/mysql
|
124
|
+
backup:
|
125
|
+
connection:
|
126
|
+
host: localhost
|
127
|
+
username: backup
|
128
|
+
password: password
|
129
|
+
crontab:
|
130
|
+
hour: "*/4"
|
131
|
+
```
|
132
|
+
|
133
|
+
Note the lack of the leading and trailing slashes in the S3 path configs. The
|
134
|
+
only required parameter is the `type`. All others parameters depend either on
|
135
|
+
the adapter itself or are defaulted from the `backups.defaults` entry.
|
136
|
+
|
137
|
+
Tags are metadata associated with a job and are passed to listeners, like
|
138
|
+
Datadog or Slack. To remove a defaulted tag simply set it to `null`.
|
139
|
+
|
140
|
+
|
141
|
+
### Run a job
|
142
|
+
|
143
|
+
Run `./bin/backup` with the command `start` and pass a job name:
|
144
|
+
|
145
|
+
./bin/backups start <job>
|
146
|
+
|
147
|
+
The `<job>` parameter should exist somewhere on some yaml file within
|
148
|
+
config directory under the entry `jobs`. Look into `config/jobs-example.yaml`
|
149
|
+
for inspiration. For our example:
|
150
|
+
|
151
|
+
./bin/backups start local-mysql
|
152
|
+
|
153
|
+
The backups comes with a dry-run mode that you can use to preview what it would
|
154
|
+
execute in a real run:
|
155
|
+
|
156
|
+
./bin/backups start local-mysql --dry-run
|
157
|
+
|
158
|
+
Backups are encrypted if you set the `encryption.secret` setting.
|
159
|
+
|
160
|
+
Sending to S3 is done when the `s3.bucket` setting is set and the setting
|
161
|
+
`s3.active` is not explicitly set to `false`.
|
162
|
+
|
163
|
+
|
164
|
+
### Install the crontab
|
165
|
+
|
166
|
+
Run the command `install` to loop through the configured job and set a crontab
|
167
|
+
job for each of them
|
168
|
+
|
169
|
+
./bin/backups install
|
170
|
+
|
171
|
+
If you want to add a custom job but not install it you need to set the field
|
172
|
+
`backup.crontan.install` to `false` in the crontab settings for that backup job:
|
173
|
+
|
174
|
+
```yaml
|
175
|
+
acme-productions:
|
176
|
+
type: mysql
|
177
|
+
enabled: false
|
178
|
+
backup:
|
179
|
+
crontab:
|
180
|
+
install: false
|
181
|
+
hour: 0
|
182
|
+
```
|
183
|
+
|
184
|
+
This config shows also where to disable the job. It's the `enabled` setting
|
185
|
+
directly under the job.
|
186
|
+
|
187
|
+
### Development
|
188
|
+
|
189
|
+
Create the file `/etc/backups-cli/main.yaml`
|
190
|
+
|
191
|
+
```yaml
|
192
|
+
---
|
193
|
+
backups:
|
194
|
+
paths:
|
195
|
+
backups: /tmp/backups
|
196
|
+
verify: /tmp/verify
|
197
|
+
listeners:
|
198
|
+
slack:
|
199
|
+
webhook: https://hooks.slack.com/services/X/Y/Z
|
200
|
+
channel: spt-payment-backups
|
201
|
+
_active: false
|
202
|
+
_events:
|
203
|
+
- _start
|
204
|
+
- error
|
205
|
+
datadog:
|
206
|
+
api_key: x
|
207
|
+
app_key: y
|
208
|
+
crontab:
|
209
|
+
header: "MAILTO=backups@spid.no\nPATH=/usr/bin:/bin:/usr/local/bin"
|
210
|
+
|
211
|
+
defaults:
|
212
|
+
# options:
|
213
|
+
# cleanup: false
|
214
|
+
# silent: false
|
215
|
+
s3:
|
216
|
+
bucket: 740872874188-database-backups
|
217
|
+
path: test/mysql
|
218
|
+
# active: false
|
219
|
+
encryption:
|
220
|
+
secret: x
|
221
|
+
backup:
|
222
|
+
crontab:
|
223
|
+
prefix: ". /etc/profile.d/proxy.sh &&"
|
224
|
+
postfix: "2>/dev/null"
|
225
|
+
```
|
226
|
+
|
227
|
+
|
228
|
+
### Release procedure
|
229
|
+
|
230
|
+
To release a new version of this gem you need to have the Ryubygems credentials
|
231
|
+
in place. Start with going into https://rubygems.org/profile/edit and run the
|
232
|
+
`curl -u schibsted https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials`
|
233
|
+
command they recommend there. This is the *only* step required to release a new
|
234
|
+
gem version to rubygems.
|
235
|
+
|
236
|
+
On this repo, just update the file `lib/backups/version.rb` with a bumped version
|
237
|
+
and commit all changes to the git repo. Then run:
|
238
|
+
|
239
|
+
rake
|
240
|
+
|
241
|
+
If you need to revoke an older gem version just run:
|
242
|
+
|
243
|
+
gem yank -v 0.5.14 backups-cli
|
244
|
+
|
245
|
+
### Known issues
|
246
|
+
|
247
|
+
The verify code runs two checks per table:
|
248
|
+
|
249
|
+
- A `CHECK TABLE <table>`
|
250
|
+
- A `SELECT COUNT(*) FROM <table>` on the table
|
251
|
+
|
252
|
+
The problem with the second is that the count is run after the dump and these
|
253
|
+
stats can be skewed in inserts are done after the dump. If you start to get
|
254
|
+
mismatches in this last one I suggest you use a float comparision, that is, one
|
255
|
+
that only reports if the stats are more than say 1% different.
|
256
|
+
|
data/Rakefile
ADDED
data/backups-cli.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
require "backups/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "backups-cli"
|
7
|
+
spec.version = Backups::VERSION
|
8
|
+
spec.description = "This tool backups different data sources to S3."
|
9
|
+
spec.summary = "This tool backups different data sources to S3"
|
10
|
+
spec.authors = ["Schibsted"]
|
11
|
+
spec.email = ["spt@schibsted.com"]
|
12
|
+
spec.homepage = "https://github.com/schibsted/backups-cli"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split $/
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename f }
|
17
|
+
|
18
|
+
spec.add_dependency "thor"
|
19
|
+
spec.add_dependency "json"
|
20
|
+
spec.add_dependency "mysql2"
|
21
|
+
spec.add_dependency "dogapi"
|
22
|
+
spec.add_dependency "slack-notifier"
|
23
|
+
spec.add_dependency "tablelize"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
end
|
data/bin/backups
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright 2016 Schibsted Products & Technology AS.
|
3
|
+
# Licensed under the terms of the MIT license. See LICENSE in the project root.
|
4
|
+
$:.push File.expand_path("../../lib", __FILE__)
|
5
|
+
|
6
|
+
require "logger"
|
7
|
+
require "backups"
|
8
|
+
|
9
|
+
log_level = ENV.fetch("BACKUPS_LOG_LEVEL", "info").upcase
|
10
|
+
DRY_RUN = ENV.fetch("BACKUPS_DRY_RUN", "0") == "1"
|
11
|
+
log_file = ENV.fetch("BACKUPS_LOG_FILE", "/var/log/backups-cli.log")
|
12
|
+
|
13
|
+
# Accept --debug or -x flags for stdout debug logging
|
14
|
+
if ARGV.include? "--debug" or ARGV.include? "-x"
|
15
|
+
log_file = STDOUT
|
16
|
+
log_level = "DEBUG"
|
17
|
+
ARGV.delete("--debug")
|
18
|
+
ARGV.delete("-x")
|
19
|
+
end
|
20
|
+
|
21
|
+
$LOG_ACTIVE = 1
|
22
|
+
$LOGGER = Logger.new(log_file)
|
23
|
+
$LOGGER.level = Object.const_get("Logger::#{log_level}")
|
24
|
+
# $LOGGER.progname = File.basename(__FILE__)
|
25
|
+
$LOGGER.progname = "main"
|
26
|
+
$LOGGER.formatter = proc do |type, time, name, message|
|
27
|
+
"[#{time}] #{name} #{type.ljust(6)} #{message}\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
$LOGGER.warn "Log level is #{log_level}"
|
31
|
+
|
32
|
+
|
33
|
+
begin
|
34
|
+
Backups::Cli.start ARGV
|
35
|
+
rescue => e
|
36
|
+
cmd = ARGV[0] || "undef"
|
37
|
+
db = ARGV[1] || "undef"
|
38
|
+
msg = e.to_s.encode!("UTF-8", {undef: :replace})
|
39
|
+
Backups::Events.fire :error, {
|
40
|
+
error: msg,
|
41
|
+
command: cmd,
|
42
|
+
db: db,
|
43
|
+
}
|
44
|
+
$LOGGER.error "Error: #{msg}."
|
45
|
+
|
46
|
+
raise e
|
47
|
+
end
|
data/lib/backups.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# $:.push File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
require "backups/cli"
|
4
|
+
require "backups/version"
|
5
|
+
require "backups/events"
|
6
|
+
require "backups/system"
|
7
|
+
require "backups/loader"
|
8
|
+
require "backups/runner"
|
9
|
+
require "backups/crontab"
|
10
|
+
require "backups/base"
|
11
|
+
require "backups/driver/mysql"
|
12
|
+
require "backups/stats/mysql"
|
13
|
+
require "backups/adapter/mysql"
|
14
|
+
require "backups/verify/mysql"
|
15
|
+
require "backups/listener"
|
16
|
+
require "backups/ext/hash"
|
17
|
+
require "backups/ext/string"
|
18
|
+
require "backups/ext/fixnum"
|
19
|
+
require "backups/ext/nil_class"
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
module Backups
|
4
|
+
module Adapter
|
5
|
+
class Mysql < Base
|
6
|
+
|
7
|
+
include ::Backups::Stats::Mysql
|
8
|
+
|
9
|
+
def run
|
10
|
+
setup
|
11
|
+
create_dump
|
12
|
+
compress @job_dir, @job_zip, @secret
|
13
|
+
|
14
|
+
@job_size = File.size(@job_zip) if not $DRY_RUN
|
15
|
+
$LOGGER.info "File #{@job_zip} created with #{@job_size} bytes"
|
16
|
+
|
17
|
+
send_to_s3 @s3_bucket, @s3_prefix, @job_zip, @config if @s3_active
|
18
|
+
clean_up if @cleanup
|
19
|
+
report
|
20
|
+
|
21
|
+
return @report
|
22
|
+
end
|
23
|
+
|
24
|
+
def verify
|
25
|
+
s3 = @config.fetch("s3", {})
|
26
|
+
@name = @config.fetch('_name')
|
27
|
+
bucket = s3.fetch("bucket", "")
|
28
|
+
path = s3.fetch("path", "")
|
29
|
+
date = get_date_path()
|
30
|
+
folder = "s3://#{bucket}/#{path}/#{@name}/#{date}/"
|
31
|
+
$LOGGER.warn "Latest s3 path is: " + get_latest_s3(folder)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
# If you are lost here's what the vars mean:
|
36
|
+
#
|
37
|
+
# Variable Value
|
38
|
+
# --------- ----------------------------------
|
39
|
+
# backup_dir /tmp/backups/
|
40
|
+
# source_dir <source>/
|
41
|
+
# job_zip <prefix>-<timestamp>.zip
|
42
|
+
# job_dir <prefix>-<timestamp>/
|
43
|
+
def setup
|
44
|
+
load_configs
|
45
|
+
|
46
|
+
backups = $GLOBAL.fetch('backups', {})
|
47
|
+
paths = backups.fetch('paths', {})
|
48
|
+
encryption = @config.fetch('encryption', {})
|
49
|
+
s3 = @config.fetch('s3', {})
|
50
|
+
prefix = get_prefix()
|
51
|
+
date_path = get_date_path()
|
52
|
+
timestamp = get_timestamp()
|
53
|
+
backup_dir = paths.fetch('backups', '/tmp/backups')
|
54
|
+
|
55
|
+
@backup = @config.fetch('backup', {})
|
56
|
+
@options = @config.fetch('options', {})
|
57
|
+
@connection = @backup.fetch('connection', {})
|
58
|
+
@secret = encryption.fetch('secret', nil)
|
59
|
+
@cleanup = @options.fetch('cleanup', true)
|
60
|
+
@name = @config.fetch('_name')
|
61
|
+
@group = @name.gsub(/[^0-9A-Za-z]/, '_')
|
62
|
+
|
63
|
+
job_name = "#{prefix}-#{timestamp}"
|
64
|
+
@source_dir = "#{backup_dir}/#{@name}"
|
65
|
+
@job_dir = "#{@source_dir}/#{job_name}"
|
66
|
+
@job_zip = "#{@source_dir}/#{job_name}.zip"
|
67
|
+
@job_size = nil
|
68
|
+
|
69
|
+
s3_path = s3.fetch('path', "")
|
70
|
+
@s3_region = s3.fetch('region', "eu-west-1")
|
71
|
+
@s3_bucket = s3.fetch('bucket', nil)
|
72
|
+
@s3_active = s3.fetch('active', @s3_bucket != nil)
|
73
|
+
@s3_prefix = "#{s3_path}/#{@name}/#{date_path}"
|
74
|
+
|
75
|
+
@report = {
|
76
|
+
started: Time.now,
|
77
|
+
completed: nil,
|
78
|
+
file: nil,
|
79
|
+
size: nil,
|
80
|
+
report: nil,
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
def get_dump_command database
|
86
|
+
host = @connection.fetch("host", "localhost")
|
87
|
+
username = @connection.fetch("username", nil)
|
88
|
+
password = @connection.fetch("password", nil)
|
89
|
+
silent = @options.fetch("silent", true)
|
90
|
+
master_data = @options.fetch("master-data", 0)
|
91
|
+
disable_keys = @options.fetch("disable-keys", true)
|
92
|
+
lock_tables = @options.fetch("lock-tables", false)
|
93
|
+
use_defaults = @group.size > 0 ? true : false
|
94
|
+
use_defaults = @options.fetch("use-defaults", use_defaults)
|
95
|
+
events = @options.fetch("events", false)
|
96
|
+
|
97
|
+
command = []
|
98
|
+
command << "mysqldump"
|
99
|
+
command << "--defaults-group-suffix=_#{@group}"
|
100
|
+
command << "--host=#{host}"
|
101
|
+
|
102
|
+
command << "--user='#{username}'" if username and !use_defaults
|
103
|
+
command << "--password='#{password}'" if password and !use_defaults
|
104
|
+
command << "--master-data=#{master_data}" if master_data
|
105
|
+
command << "--events" if events
|
106
|
+
command << "--skip-events" unless events
|
107
|
+
command << "--lock-tables" if lock_tables
|
108
|
+
command << "--single-transaction" unless lock_tables
|
109
|
+
command << "--disable-keys" if disable_keys
|
110
|
+
command << database
|
111
|
+
command << "> #{@job_dir}/#{database}.sql"
|
112
|
+
command << "2>/dev/null" if silent
|
113
|
+
|
114
|
+
command.join(" ")
|
115
|
+
end
|
116
|
+
|
117
|
+
def get_db_list
|
118
|
+
host = @connection.fetch("host", "localhost")
|
119
|
+
skip = [
|
120
|
+
"information_schema",
|
121
|
+
"performance_schema",
|
122
|
+
"sys",
|
123
|
+
]
|
124
|
+
|
125
|
+
command = "mysql --defaults-group-suffix=_#{@group}"
|
126
|
+
command << " --host #{host}"
|
127
|
+
command << " -e 'show databases' | awk 'NR>1'"
|
128
|
+
$LOGGER.debug command
|
129
|
+
|
130
|
+
`#{command}`.split().select do |db|
|
131
|
+
not skip.include? db
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def create_dump
|
136
|
+
$LOGGER.info "Creating #{@job_dir}"
|
137
|
+
mkdir @job_dir
|
138
|
+
|
139
|
+
database = @backup.fetch("database", nil)
|
140
|
+
databases = @backup.fetch("databases", [])
|
141
|
+
databases << database if database
|
142
|
+
|
143
|
+
# Are we dumping specific databases
|
144
|
+
if databases.size > 0
|
145
|
+
$LOGGER.info "Preparing databases dump"
|
146
|
+
databases.each do |db|
|
147
|
+
create_database_dump db
|
148
|
+
end
|
149
|
+
else
|
150
|
+
create_server_dump
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def create_server_dump
|
155
|
+
$LOGGER.info "Preparing server dump"
|
156
|
+
get_db_list().each do |db|
|
157
|
+
create_database_dump db
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def create_database_dump db
|
162
|
+
$LOGGER.info "Dumping database #{db}"
|
163
|
+
command = get_dump_command(db)
|
164
|
+
create_database_stats db
|
165
|
+
exec command
|
166
|
+
end
|
167
|
+
|
168
|
+
def create_database_stats db
|
169
|
+
$LOGGER.debug "Creating #{db} database stats"
|
170
|
+
file = "#{@job_dir}/#{db}-stats.yaml"
|
171
|
+
stats = get_database_stats(db)
|
172
|
+
write file, stats.to_yaml
|
173
|
+
end
|
174
|
+
|
175
|
+
def clean_up
|
176
|
+
$LOGGER.info "Cleaning #{@source_dir}"
|
177
|
+
delete @job_zip if File.exists? @job_zip
|
178
|
+
nuke_dir @job_dir
|
179
|
+
|
180
|
+
delete_dir @source_dir
|
181
|
+
end
|
182
|
+
|
183
|
+
def report
|
184
|
+
path = "#{@s3_bucket}/#{@s3_prefix}/#{File.basename(@job_zip)}"
|
185
|
+
|
186
|
+
@report[:completed] = Time.now
|
187
|
+
@report[:file] = @job_zip
|
188
|
+
@report[:size] = @job_size
|
189
|
+
@report[:url] = "s3://#{path}"
|
190
|
+
@report[:view] = "https://console.aws.amazon.com/s3/buckets" +
|
191
|
+
"#{path}?region=#{@s3_region}"
|
192
|
+
end
|
193
|
+
|
194
|
+
def get_latest_s3 folder
|
195
|
+
$LOGGER.info "Finding latest dump in folder #{folder}"
|
196
|
+
$LOGGER.info "aws s3 ls #{folder}/|awk '{ print $4 }'|tail -n 1"
|
197
|
+
exec "aws s3 ls #{folder}/|awk '{ print $4 }'|tail -n 1"
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|