Class: EY::Backup::Postgresql
- Inherits:
-
Engine
show all
- Defined in:
- lib/ey_backup/engines/postgresql_engine.rb
Constant Summary
Constants included
from Spawner
Spawner::CHUNK_SIZE
Instance Attribute Summary
Attributes inherited from Engine
#force, #host, #key_id, #password, #username
Instance Method Summary
collapse
Methods inherited from Engine
descendants, #gpg?, inherited, #initialize, label, lookup, register
Methods included from Spawner
#ioify, #run, #runs?, #spawn
Methods inherited from Base
#logger
Instance Method Details
#cancel_connections(database_name) ⇒ Object
57
58
59
60
61
|
# File 'lib/ey_backup/engines/postgresql_engine.rb', line 57
def cancel_connections(database_name)
%x{psql -U postgres -h #{host} -c"SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = '#{database_name}';"}
end
|
#check_connections(database_name) ⇒ Object
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
# File 'lib/ey_backup/engines/postgresql_engine.rb', line 37
def check_connections(database_name)
active_connections = %x{PGPASSWORD='#{password}' psql -U postgres -h #{host} -t -c "select count(*) from pg_stat_activity where datname='#{database_name}';"}
if active_connections.to_i > 0
res = ''
unless force
puts "There are currently #{stdout.string.to_i} connections on database: '#{database_name}'; can I kill these to continue (Y/n):"
Timeout::timeout(30){
res = gets.strip
}
end
if res.upcase == 'Y' or force
cancel_connections(database_name)
else
EY::Backup.logger.fatal(%Q{ERROR: Target database has active connections. For more information, see "Restore or load a database" in docs.engineyard.com})
end
end
end
|
#check_if_replica ⇒ Object
75
76
77
78
79
80
|
# File 'lib/ey_backup/engines/postgresql_engine.rb', line 75
def check_if_replica
stdout = %x{PGPASSWORD='#{password}' psql -U postgres -h #{host} -t -c "select pg_is_in_recovery()"| head -n 1}
unless stdout.chomp =~ /^\W*f$/
EY::Backup.logger.fatal(%Q{ERROR: Target host: '#{host}' is currently a replica in recovery mode; restore operations need to be processed against the master.})
end
end
|
#create_command(database_name) ⇒ Object
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
# File 'lib/ey_backup/engines/postgresql_engine.rb', line 82
def create_command(database_name)
%x{PGPASSWORD='#{password}' psql -U postgres -h #{host} -t -c "SELECT 'CREATE DATABASE ' || datname ||
' WITH OWNER ' || pg_user.usename ||
CASE (select pg_encoding_to_char(encoding) from pg_database where datname='template1')
WHEN pg_encoding_to_char(encoding)
THEN ''
ELSE ' template=template0'
END ||
' ENCODING ''' || pg_encoding_to_char(encoding) ||
''' LC_COLLATE ''' || datcollate||
''' LC_CTYPE ''' || datctype ||
''' CONNECTION LIMIT ' || datconnlimit || ';'
FROM pg_database
INNER JOIN pg_user
ON pg_user.usesysid = pg_database.datdba
WHERE datname = '#{database_name}'"
}
end
|
#create_database(database_name) ⇒ Object
69
70
71
72
73
|
# File 'lib/ey_backup/engines/postgresql_engine.rb', line 69
def create_database(database_name)
command = "PGPASSWORD='#{password}' createdb -U#{username} -h #{host} #{database_name}"
verbose "Creating Database with: #{command}"
%x{#{command}}
end
|
#cycle_database(database_name) ⇒ Object
101
102
103
104
105
106
107
108
109
110
|
# File 'lib/ey_backup/engines/postgresql_engine.rb', line 101
def cycle_database(database_name)
create_cmd = create_command(database_name).chomp
if create_cmd == ''
create_database(database_name)
else
check_connections(database_name)
drop_database(database_name)
%x{PGPASSWORD='#{password}' psql -U postgres -h #{host} -t -c "#{create_cmd}"}
end
end
|
#drop_database(database_name) ⇒ Object
63
64
65
66
67
|
# File 'lib/ey_backup/engines/postgresql_engine.rb', line 63
def drop_database(database_name)
command = "PGPASSWORD='#{password}' dropdb -h #{host} -Upostgres #{database_name}"
verbose "Dropping Database with: #{command}"
%x{#{command}}
end
|
#dump(database_name, basename) ⇒ Object
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# File 'lib/ey_backup/engines/postgresql_engine.rb', line 6
def dump(database_name, basename)
file = basename + '.dump'
command = "PGPASSWORD='#{password}' pg_dump -h #{host} --create --format=c -Upostgres #{database_name} 2> /tmp/eybackup.$$.dumperr"
if gpg?
command << " | " << GPGEncryptor.command_for(key_id)
file << GPGEncryptor.extension
end
command << " > #{file}"
run(command, database_name)
file
end
|
#load(database_name, file) ⇒ Object
23
24
25
26
27
28
29
30
31
32
33
34
35
|
# File 'lib/ey_backup/engines/postgresql_engine.rb', line 23
def load(database_name, file)
if file =~ /.gpz$/ abort "Cannot restore a GPG backup directly; decrypt the file (#{file}) using your key and then load with pg_restore."
end
cycle_database(database_name)
command = "cat #{file}"
command << " | PGPASSWORD='#{password}' pg_restore -h #{host} --format=c -Upostgres -d #{database_name} 2> /tmp/eybackup.$$.dumperr"
run(command, database_name)
end
|
#suffix ⇒ Object
112
113
114
|
# File 'lib/ey_backup/engines/postgresql_engine.rb', line 112
def suffix
/\.(dump|gpz)$/
end
|