postmodern 0.4.3 → 0.5.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 +4 -4
- data/README.md +30 -0
- data/lib/postmodern/backup/backup.rb +130 -0
- data/lib/postmodern/dummy.rb +1 -0
- data/lib/postmodern/runner.rb +3 -1
- data/lib/postmodern/version.rb +1 -1
- data/lib/postmodern/wal/restore.rb +1 -1
- data/spec/features/dummy_spec.rb +1 -0
- data/spec/postmodern/backup/backup_spec.rb +53 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 124f924267587d2aab3717d32850512d77af8451
|
4
|
+
data.tar.gz: b5af8d5ad7a974e415498571326bdb39700b0224
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f7a404c5c59c19dc7c1bb4cfdb55f475727badce1177a04b0d98e8a739f3d42737d3f706d54efb5de3cbc1165e96449a9f7ec71130df5191d5e398c3b72a08e
|
7
|
+
data.tar.gz: dc9a9175c931aabc5ad4446cbf8f8788bc0b25f3cfee9ebf41ef375094436fcad40961b6fa642f1be43fe93cc1da47154c901cae0a2f345674fd984f2083b1d7
|
data/README.md
CHANGED
@@ -24,6 +24,36 @@ the system's ruby, however that is installed.
|
|
24
24
|
|
25
25
|
## Usage
|
26
26
|
|
27
|
+
### Backup
|
28
|
+
|
29
|
+
Backup all databases in a Postgres instance using `pg_basebackup`. This assumes that
|
30
|
+
there are no additional tablespaces (see the documentation on
|
31
|
+
`pg_basebackup`).
|
32
|
+
|
33
|
+
```
|
34
|
+
Usage: postmodern backup <options>
|
35
|
+
|
36
|
+
Creates a gzipped archive of a pg_basebackup, with file name:
|
37
|
+
NAME.basebackup.CURRENTDATE.tar.gz
|
38
|
+
|
39
|
+
-U, --user USER Postgres user (default: "postgres")
|
40
|
+
-d, --directory DIRECTORY Local directory to put backups (required)
|
41
|
+
-H, --host HOST Host of database (eg: fqdn, IP) (required)
|
42
|
+
-p, --port PORT Port of database (default: 5432)
|
43
|
+
-n, --name NAME Name of backup (required)
|
44
|
+
--pigz CONCURRENCY Use pigz with concurrency CONCURRENCY
|
45
|
+
-h, --help Show this message
|
46
|
+
--version Show version
|
47
|
+
```
|
48
|
+
|
49
|
+
`CURRENTDATE` will be in the format `YYYYMMDD`, and will be the contents of the
|
50
|
+
Postgres data directory of the backed-up instance. When restoring from
|
51
|
+
these backups, note that it should be untarred directly into a new data
|
52
|
+
directory. For instance, if Postgres on the restored hosts is configured
|
53
|
+
with a data directory of `/var/pgsql/data94`, then the archive should be
|
54
|
+
untarred within `/var/pgsql/data94`, not in the parent directory.
|
55
|
+
|
56
|
+
|
27
57
|
### Vacuuming and Vacuum Freezing
|
28
58
|
|
29
59
|
Postmodern's vacuum scripts run table by table, with various constraints
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'postmodern/command'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'open3'
|
4
|
+
|
5
|
+
module Postmodern
|
6
|
+
module Backup
|
7
|
+
class Backup < Postmodern::Command
|
8
|
+
required_option :directory, :host, :name
|
9
|
+
default_option :user, 'postgres'
|
10
|
+
default_option :port, 5432
|
11
|
+
default_option :pigz, false
|
12
|
+
default_option :concurrency, 4
|
13
|
+
|
14
|
+
def parser
|
15
|
+
@parser ||= OptionParser.new do |opts|
|
16
|
+
opts.banner = 'Usage: postmodern backup <options>'
|
17
|
+
|
18
|
+
opts.separator ''
|
19
|
+
opts.separator 'Creates a gzipped archive of a pg_basebackup, with file name:'
|
20
|
+
opts.separator ' NAME.basebackup.CURRENTDATE.tar.gz'
|
21
|
+
opts.separator ''
|
22
|
+
|
23
|
+
opts.on('-U', '--user USER', 'Postgres user (default: "postgres")') do |o|
|
24
|
+
self.options[:user] = o
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on('-d', '--directory DIRECTORY', 'Local directory to put backups (required)') do |o|
|
28
|
+
self.options[:directory] = o
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on('-H', '--host HOST', 'Host of database (eg: fqdn, IP) (required)') do |o|
|
32
|
+
self.options[:host] = o
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on('-p', '--port PORT', 'Port of database (default: 5432)') do |o|
|
36
|
+
self.options[:port] = o
|
37
|
+
end
|
38
|
+
|
39
|
+
opts.on('-n', '--name NAME', 'Name of backup (required)') do |o|
|
40
|
+
self.options[:name] = o
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.on('--pigz CONCURRENCY', 'Use pigz with concurrency CONCURRENCY') do |o|
|
44
|
+
self.options[:pigz] = true
|
45
|
+
self.options[:concurrency] = o
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
49
|
+
puts opts
|
50
|
+
exit
|
51
|
+
end
|
52
|
+
|
53
|
+
opts.on_tail("--version", "Show version") do
|
54
|
+
require 'postmodern/version'
|
55
|
+
puts Postmodern::VERSION
|
56
|
+
exit
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def run
|
62
|
+
setup_environment
|
63
|
+
run_basebackup
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# option wrappers
|
69
|
+
|
70
|
+
def directory
|
71
|
+
@options[:directory]
|
72
|
+
end
|
73
|
+
|
74
|
+
def host
|
75
|
+
@options[:host]
|
76
|
+
end
|
77
|
+
|
78
|
+
def name
|
79
|
+
@options[:name]
|
80
|
+
end
|
81
|
+
|
82
|
+
def port
|
83
|
+
@options[:port]
|
84
|
+
end
|
85
|
+
|
86
|
+
def user
|
87
|
+
@options[:user]
|
88
|
+
end
|
89
|
+
|
90
|
+
# backup methods
|
91
|
+
|
92
|
+
def archive_command
|
93
|
+
return 'gzip -9' unless options[:pigz]
|
94
|
+
"pigz -9 -p #{options[:concurrency]}"
|
95
|
+
end
|
96
|
+
|
97
|
+
def archive_file
|
98
|
+
"#{directory}/#{name}.basebackup.#{current_date}.tar.gz"
|
99
|
+
end
|
100
|
+
|
101
|
+
def basebackup_command
|
102
|
+
"pg_basebackup --checkpoint=fast -F tar -D - -U #{user} -h #{host} -p #{port} | #{archive_command} > #{archive_file}"
|
103
|
+
end
|
104
|
+
|
105
|
+
def current_date
|
106
|
+
Time.now.strftime('%Y%m%d')
|
107
|
+
end
|
108
|
+
|
109
|
+
def run_basebackup
|
110
|
+
$stderr.puts "[#{Time.now.utc}] Creating basebackup: #{host}"
|
111
|
+
stdout, stderr, status = Open3.capture3(script_env, basebackup_command)
|
112
|
+
$stdout.print stdout
|
113
|
+
$stderr.print stderr
|
114
|
+
$stderr.puts "[#{Time.now.utc}] Finished basebackup: #{host}"
|
115
|
+
exit status.exitstatus
|
116
|
+
end
|
117
|
+
|
118
|
+
def setup_environment
|
119
|
+
FileUtils.mkdir_p(directory)
|
120
|
+
end
|
121
|
+
|
122
|
+
def script_env
|
123
|
+
{
|
124
|
+
'PATH' => ENV['PATH']
|
125
|
+
}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
data/lib/postmodern/dummy.rb
CHANGED
data/lib/postmodern/runner.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'postmodern'
|
2
|
+
require 'postmodern/backup/backup'
|
2
3
|
require 'postmodern/wal/archive'
|
3
4
|
require 'postmodern/wal/restore'
|
4
5
|
require 'postmodern/vacuum/vacuum'
|
@@ -11,6 +12,7 @@ module Postmodern
|
|
11
12
|
|
12
13
|
DEFAULT_COMMAND = Dummy
|
13
14
|
COMMAND_MAP = {
|
15
|
+
'backup' => Backup::Backup,
|
14
16
|
'archive' => WAL::Archive,
|
15
17
|
'restore' => WAL::Restore,
|
16
18
|
'vacuum' => Vacuum::Vacuum,
|
@@ -20,7 +22,7 @@ module Postmodern
|
|
20
22
|
def self.run(args)
|
21
23
|
command_for(args.first).new(args).run
|
22
24
|
end
|
23
|
-
|
25
|
+
|
24
26
|
def self.command_for(command)
|
25
27
|
COMMAND_MAP[command] || DEFAULT_COMMAND
|
26
28
|
end
|
data/lib/postmodern/version.rb
CHANGED
data/spec/features/dummy_spec.rb
CHANGED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'postmodern/backup/backup'
|
3
|
+
|
4
|
+
describe Postmodern::Backup::Backup do
|
5
|
+
let(:stdout) { double(to_s: '') }
|
6
|
+
let(:stderr) { double(to_s: '') }
|
7
|
+
let(:status) { double(exitstatus: 0) }
|
8
|
+
|
9
|
+
let(:directory) { '/tmp/pg_backup' }
|
10
|
+
let(:user) { 'pg' }
|
11
|
+
let(:host) { '127.0.0.1' }
|
12
|
+
let(:name) { 'host.com' }
|
13
|
+
let(:port) { 5433 }
|
14
|
+
let(:current_date) { Time.now.strftime('%Y%m%d') }
|
15
|
+
let(:arguments) { %W(--user #{user} --directory #{directory} --host #{host} --name #{name} --port #{port}) }
|
16
|
+
|
17
|
+
subject(:backup) { Postmodern::Backup::Backup.new(arguments) }
|
18
|
+
|
19
|
+
before do
|
20
|
+
allow(Open3).to receive(:capture3).and_return([stdout, stderr, status])
|
21
|
+
allow($stderr).to receive(:puts)
|
22
|
+
allow(backup).to receive(:exit)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#run' do
|
26
|
+
let(:backup_command) { "pg_basebackup --checkpoint=fast -F tar -D - -U #{user} -h #{host} -p #{port}" }
|
27
|
+
|
28
|
+
it 'archives the data directory with gzip' do
|
29
|
+
backup.run
|
30
|
+
expect(Open3).to have_received(:capture3).with(
|
31
|
+
{
|
32
|
+
'PATH' => anything
|
33
|
+
},
|
34
|
+
"#{backup_command} | gzip -9 > #{directory}/#{name}.basebackup.#{current_date}.tar.gz"
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with --pigz' do
|
39
|
+
let(:arguments) { %W(-U #{user} -d #{directory} -H #{host} -n #{name} -p #{port} --pigz 12) }
|
40
|
+
|
41
|
+
it 'archives the data directory with pigz' do
|
42
|
+
backup.run
|
43
|
+
expect(Open3).to have_received(:capture3).with(
|
44
|
+
{
|
45
|
+
'PATH' => anything
|
46
|
+
},
|
47
|
+
"#{backup_command} | pigz -9 -p 12 > #{directory}/#{name}.basebackup.#{current_date}.tar.gz"
|
48
|
+
)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postmodern
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Saxby
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|
@@ -73,6 +73,7 @@ files:
|
|
73
73
|
- examples/postmodern_archive.local
|
74
74
|
- examples/postmodern_restore.local
|
75
75
|
- lib/postmodern.rb
|
76
|
+
- lib/postmodern/backup/backup.rb
|
76
77
|
- lib/postmodern/command.rb
|
77
78
|
- lib/postmodern/db/adapter.rb
|
78
79
|
- lib/postmodern/dummy.rb
|
@@ -89,6 +90,7 @@ files:
|
|
89
90
|
- spec/features/restore_spec.rb
|
90
91
|
- spec/features/vacuum_spec.rb
|
91
92
|
- spec/fixtures/wal/env/postmodern_archive.local
|
93
|
+
- spec/postmodern/backup/backup_spec.rb
|
92
94
|
- spec/postmodern/command_spec.rb
|
93
95
|
- spec/postmodern/db/adapter_spec.rb
|
94
96
|
- spec/postmodern/postmodern_spec.rb
|
@@ -119,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
121
|
version: '0'
|
120
122
|
requirements: []
|
121
123
|
rubyforge_project:
|
122
|
-
rubygems_version: 2.
|
124
|
+
rubygems_version: 2.2.5
|
123
125
|
signing_key:
|
124
126
|
specification_version: 4
|
125
127
|
summary: Tools for managing PostgreSQL
|
@@ -130,6 +132,7 @@ test_files:
|
|
130
132
|
- spec/features/restore_spec.rb
|
131
133
|
- spec/features/vacuum_spec.rb
|
132
134
|
- spec/fixtures/wal/env/postmodern_archive.local
|
135
|
+
- spec/postmodern/backup/backup_spec.rb
|
133
136
|
- spec/postmodern/command_spec.rb
|
134
137
|
- spec/postmodern/db/adapter_spec.rb
|
135
138
|
- spec/postmodern/postmodern_spec.rb
|