forked from wal-e/wal-e
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for backing up non-running PG cluster
- Loading branch information
Mike Krieger
authored and
Daniel Farina
committed
Aug 4, 2012
1 parent
6de5822
commit f7986b7
Showing
4 changed files
with
116 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
0.5.11 | ||
0.5.12 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
from subprocess import PIPE | ||
import os | ||
from wal_e.piper import popen_sp | ||
|
||
CONTROLDATA_BIN = 'pg_controldata' | ||
CONFIG_BIN = 'pg_config' | ||
|
||
class PgControlDataParser(object): | ||
""" | ||
When we're backing up a PG cluster that is not | ||
running, we can't query it for information like | ||
the current restartpoint's WAL index, | ||
the current PG version, etc. | ||
Fortunately, we can use pg_controldata, which | ||
provides this information and doesn't require | ||
a running PG process | ||
""" | ||
|
||
def __init__(self, data_directory): | ||
self.data_directory = data_directory | ||
pg_config_proc = popen_sp([CONFIG_BIN], | ||
stdout=PIPE) | ||
output = pg_config_proc.communicate()[0] | ||
for line in output.split('\n'): | ||
parts = line.split('=') | ||
if len(parts) != 2: | ||
continue | ||
key, val = map(lambda x: x.strip(), parts) | ||
if key == 'BINDIR': | ||
self._controldata_bin = os.path.join(val, CONTROLDATA_BIN) | ||
elif key == 'VERSION': | ||
self._pg_version = val | ||
|
||
def _read_controldata(self): | ||
controldata_proc = popen_sp([self._controldata_bin, self.data_directory], | ||
stdout=PIPE) | ||
stdout = controldata_proc.communicate()[0] | ||
controldata = {} | ||
for line in stdout.split('\n'): | ||
split_values = line.split(':') | ||
if len(split_values) == 2: | ||
key, val = split_values | ||
controldata[key.strip()] = val.strip() | ||
return controldata | ||
|
||
def controldata_bin(self): | ||
return self._controldata_bin | ||
|
||
def pg_version(self): | ||
return self._pg_version | ||
|
||
def last_xlog_file_name_and_offset(self): | ||
controldata = self._read_controldata() | ||
last_checkpoint_offset = controldata["Latest checkpoint's REDO location"] | ||
current_timeline = controldata["Latest checkpoint's TimeLineID"] | ||
x, offset = last_checkpoint_offset.split('/') | ||
timeline = current_timeline.zfill(8) | ||
wal = x.zfill(8) | ||
offset = offset[0:2].zfill(8) | ||
return { | ||
'file_name': ''.join([timeline, wal, offset]), | ||
'file_offset': offset.zfill(8)} |