mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2025-02-08 14:28:36 +02:00
tests fix
This commit is contained in:
parent
5e034a4acc
commit
1a849cad7e
@ -11,28 +11,28 @@ from . import init_test, option_test, show_test, \
|
||||
|
||||
def load_tests(loader, tests, pattern):
|
||||
suite = unittest.TestSuite()
|
||||
# suite.addTests(loader.loadTestsFromModule(replica))
|
||||
suite.addTests(loader.loadTestsFromModule(replica))
|
||||
# suite.addTests(loader.loadTestsFromModule(pgpro560))
|
||||
# suite.addTests(loader.loadTestsFromModule(pgpro589))
|
||||
suite.addTests(loader.loadTestsFromModule(pgpro688))
|
||||
# suite.addTests(loader.loadTestsFromModule(pgpro688))
|
||||
# suite.addTests(loader.loadTestsFromModule(false_positive))
|
||||
# suite.addTests(loader.loadTestsFromModule(init_test))
|
||||
# suite.addTests(loader.loadTestsFromModule(option_test))
|
||||
# suite.addTests(loader.loadTestsFromModule(show_test))
|
||||
# suite.addTests(loader.loadTestsFromModule(backup_test))
|
||||
# suite.addTests(loader.loadTestsFromModule(delete_test))
|
||||
# suite.addTests(loader.loadTestsFromModule(restore_test))
|
||||
# suite.addTests(loader.loadTestsFromModule(validate_test))
|
||||
# suite.addTests(loader.loadTestsFromModule(retention_test))
|
||||
# suite.addTests(loader.loadTestsFromModule(ptrack_clean))
|
||||
# suite.addTests(loader.loadTestsFromModule(ptrack_cluster))
|
||||
# suite.addTests(loader.loadTestsFromModule(ptrack_move_to_tablespace))
|
||||
# suite.addTests(loader.loadTestsFromModule(ptrack_recovery))
|
||||
# suite.addTests(loader.loadTestsFromModule(ptrack_vacuum))
|
||||
# suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_bits_frozen))
|
||||
# suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_bits_visibility))
|
||||
# suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_full))
|
||||
# suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_truncate))
|
||||
suite.addTests(loader.loadTestsFromModule(init_test))
|
||||
suite.addTests(loader.loadTestsFromModule(option_test))
|
||||
suite.addTests(loader.loadTestsFromModule(show_test))
|
||||
suite.addTests(loader.loadTestsFromModule(backup_test))
|
||||
suite.addTests(loader.loadTestsFromModule(delete_test))
|
||||
suite.addTests(loader.loadTestsFromModule(restore_test))
|
||||
suite.addTests(loader.loadTestsFromModule(validate_test))
|
||||
suite.addTests(loader.loadTestsFromModule(retention_test))
|
||||
suite.addTests(loader.loadTestsFromModule(ptrack_clean))
|
||||
suite.addTests(loader.loadTestsFromModule(ptrack_cluster))
|
||||
suite.addTests(loader.loadTestsFromModule(ptrack_move_to_tablespace))
|
||||
suite.addTests(loader.loadTestsFromModule(ptrack_recovery))
|
||||
suite.addTests(loader.loadTestsFromModule(ptrack_vacuum))
|
||||
suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_bits_frozen))
|
||||
suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_bits_visibility))
|
||||
suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_full))
|
||||
suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_truncate))
|
||||
|
||||
return suite
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import unittest
|
||||
from os import path, listdir
|
||||
import os
|
||||
import six
|
||||
from time import sleep
|
||||
from helpers.ptrack_helpers import ProbackupTest, ProbackupException
|
||||
from testgres import stop_all
|
||||
|
||||
@ -9,6 +10,7 @@ class BackupTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BackupTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'backup'
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
@ -20,132 +22,198 @@ class BackupTest(ProbackupTest, unittest.TestCase):
|
||||
def test_backup_modes_archive(self):
|
||||
"""standart backup modes with ARCHIVE WAL method"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/backup/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
# full backup mode
|
||||
#with open(path.join(node.logs_dir, "backup_full.log"), "wb") as backup_log:
|
||||
# backup_log.write(self.backup_pb(node, options=["--verbose"]))
|
||||
# backup_log.write(self.backup_node(node, options=["--verbose"]))
|
||||
|
||||
self.backup_pb(node)
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
show_backup = self.show_pb(backup_dir, 'node')[0]
|
||||
|
||||
show_backup = self.show_pb(node)[0]
|
||||
full_backup_id = show_backup['ID']
|
||||
self.assertEqual(show_backup['Status'], six.b("OK"))
|
||||
self.assertEqual(show_backup['Mode'], six.b("FULL"))
|
||||
|
||||
# postmaster.pid and postmaster.opts shouldn't be copied
|
||||
excluded = True
|
||||
backups_dir = path.join(self.backup_dir(node), "backups")
|
||||
for backup in listdir(backups_dir):
|
||||
db_dir = path.join(backups_dir, backup, "database")
|
||||
for f in listdir(db_dir):
|
||||
if path.isfile(path.join(db_dir, f)) and \
|
||||
(f == "postmaster.pid" or f == "postmaster.opts"):
|
||||
db_dir = os.path.join(backup_dir, "backups", 'node', backup_id, "database")
|
||||
for f in os.listdir(db_dir):
|
||||
if os.path.isfile(os.path.join(db_dir, f)) \
|
||||
and (f == "postmaster.pid" or f == "postmaster.opts"):
|
||||
excluded = False
|
||||
self.assertEqual(excluded, True)
|
||||
|
||||
# page backup mode
|
||||
self.backup_pb(node, backup_type="page")
|
||||
page_backup_id = self.backup_node(backup_dir, 'node', node, backup_type="page")
|
||||
|
||||
# print self.show_pb(node)
|
||||
show_backup = self.show_pb(node)[1]
|
||||
show_backup = self.show_pb(backup_dir, 'node')[1]
|
||||
self.assertEqual(show_backup['Status'], six.b("OK"))
|
||||
self.assertEqual(show_backup['Mode'], six.b("PAGE"))
|
||||
|
||||
# Check parent backup
|
||||
self.assertEqual(
|
||||
full_backup_id,
|
||||
self.show_pb(node, id=show_backup['ID'])["parent-backup-id"])
|
||||
backup_id,
|
||||
self.show_pb(backup_dir, 'node', backup_id=show_backup['ID'])["parent-backup-id"])
|
||||
|
||||
# ptrack backup mode
|
||||
self.backup_pb(node, backup_type="ptrack")
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="ptrack")
|
||||
|
||||
show_backup = self.show_pb(node)[2]
|
||||
show_backup = self.show_pb(backup_dir, 'node')[2]
|
||||
self.assertEqual(show_backup['Status'], six.b("OK"))
|
||||
self.assertEqual(show_backup['Mode'], six.b("PTRACK"))
|
||||
|
||||
# Check parent backup
|
||||
self.assertEqual(
|
||||
page_backup_id,
|
||||
self.show_pb(backup_dir, 'node', backup_id=show_backup['ID'])["parent-backup-id"])
|
||||
|
||||
node.stop()
|
||||
|
||||
# @unittest.skip("skip")
|
||||
def test_smooth_checkpoint(self):
|
||||
"""full backup with smooth checkpoint"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/backup/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
self.backup_pb(node, options=["-C"])
|
||||
|
||||
self.assertEqual(self.show_pb(node)[0]['Status'], six.b("OK"))
|
||||
|
||||
self.backup_node(backup_dir, 'node' ,node, options=["-C"])
|
||||
self.assertEqual(self.show_pb(backup_dir, 'node')[0]['Status'], six.b("OK"))
|
||||
node.stop()
|
||||
|
||||
def test_page_backup_without_full(self):
|
||||
#@unittest.skip("skip")
|
||||
def test_incremental_backup_without_full(self):
|
||||
"""page-level backup without validated full backup"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/backup/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
try:
|
||||
self.backup_pb(node, backup_type="page")
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="page")
|
||||
# we should die here because exception is what we expect to happen
|
||||
self.assertEqual(1, 0, "Expecting Error because page backup should not be possible without valid full backup.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
pass
|
||||
self.assertEqual(self.show_pb(node)[0]['Status'], six.b("ERROR"))
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: Valid backup on current timeline is not found. Create new FULL backup before an incremental one.\n',
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
sleep(1)
|
||||
|
||||
try:
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="ptrack")
|
||||
# we should die here because exception is what we expect to happen
|
||||
self.assertEqual(1, 0, "Expecting Error because page backup should not be possible without valid full backup.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: Valid backup on current timeline is not found. Create new FULL backup before an incremental one.\n',
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
self.assertEqual(self.show_pb(backup_dir, 'node')[0]['Status'], six.b("ERROR"))
|
||||
node.stop()
|
||||
|
||||
@unittest.expectedFailure
|
||||
# Need to forcibly validate parent
|
||||
def test_incremental_backup_corrupt_full(self):
|
||||
"""page-level backup with corrupted full backup"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
file = os.path.join(backup_dir, "backups", "node", backup_id.decode("utf-8"), "database", "postgresql.conf")
|
||||
os.remove(file)
|
||||
|
||||
try:
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="page")
|
||||
# we should die here because exception is what we expect to happen
|
||||
self.assertEqual(1, 0, "Expecting Error because page backup should not be possible without valid full backup.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: Valid backup on current timeline is not found. Create new FULL backup before an incremental one.\n',
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
sleep(1)
|
||||
self.assertEqual(1, 0, "Expecting Error because page backup should not be possible without valid full backup.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: Valid backup on current timeline is not found. Create new FULL backup before an incremental one.\n',
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
self.assertEqual(self.show_pb(backup_dir, 'node')[0]['Status'], six.b("ERROR"))
|
||||
node.stop()
|
||||
|
||||
# @unittest.skip("skip")
|
||||
def test_ptrack_threads(self):
|
||||
"""ptrack multi thread backup mode"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/backup/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', "ptrack_enable": "on", 'max_wal_senders': '2'}
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
self.backup_pb(node, backup_type="full", options=["-j", "4"])
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="full", options=["-j", "4"])
|
||||
self.assertEqual(self.show_pb(backup_dir, 'node')[0]['Status'], six.b("OK"))
|
||||
|
||||
self.assertEqual(self.show_pb(node)[0]['Status'], six.b("OK"))
|
||||
|
||||
with open(path.join(node.logs_dir, "backup_ptrack.log"), "wb") as backup_log:
|
||||
backup_log.write(self.backup_pb(node, backup_type="ptrack", options=["-j", "4"]))
|
||||
|
||||
self.assertEqual(self.show_pb(node)[0]['Status'], six.b("OK"))
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="ptrack", options=["-j", "4"])
|
||||
self.assertEqual(self.show_pb(backup_dir, 'node')[0]['Status'], six.b("OK"))
|
||||
|
||||
node.stop()
|
||||
|
||||
# @unittest.skip("skip")
|
||||
def test_ptrack_threads_stream(self):
|
||||
"""ptrack multi thread backup mode and stream"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/backup/{0}".format(fname),
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on', 'max_wal_senders': '2'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
self.backup_pb(node, backup_type="full", options=["-j", "4", "--stream"])
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="full", options=["-j", "4", "--stream"])
|
||||
|
||||
self.assertEqual(self.show_pb(node)[0]['Status'], six.b("OK"))
|
||||
|
||||
self.backup_pb(node, backup_type="ptrack", options=["-j", "4", "--stream"])
|
||||
|
||||
self.assertEqual(self.show_pb(node)[1]['Status'], six.b("OK"))
|
||||
self.assertEqual(self.show_pb(backup_dir, 'node')[0]['Status'], six.b("OK"))
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="ptrack", options=["-j", "4", "--stream"])
|
||||
self.assertEqual(self.show_pb(backup_dir, 'node')[1]['Status'], six.b("OK"))
|
||||
node.stop()
|
||||
|
@ -1,5 +1,5 @@
|
||||
import unittest
|
||||
from os import path
|
||||
import os
|
||||
import six
|
||||
from helpers.ptrack_helpers import ProbackupTest, ProbackupException
|
||||
from testgres import stop_all
|
||||
@ -10,6 +10,7 @@ class DeleteTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DeleteTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'delete'
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
@ -20,71 +21,109 @@ class DeleteTest(ProbackupTest, unittest.TestCase):
|
||||
def test_delete_full_backups(self):
|
||||
"""delete full backups"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/delete/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
node.pgbench_init()
|
||||
|
||||
# full backup mode
|
||||
self.backup_pb(node)
|
||||
# full backup
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
pgbench = node.pgbench(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
pgbench.wait()
|
||||
pgbench.stdout.close()
|
||||
|
||||
self.backup_pb(node)
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
pgbench = node.pgbench(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
pgbench.wait()
|
||||
pgbench.stdout.close()
|
||||
|
||||
self.backup_pb(node)
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
show_backups = self.show_pb(node)
|
||||
show_backups = self.show_pb(backup_dir, 'node')
|
||||
id_1 = show_backups[0]['ID']
|
||||
id_2 = show_backups[1]['ID']
|
||||
id_3 = show_backups[2]['ID']
|
||||
self.delete_pb(node, show_backups[1]['ID'])
|
||||
show_backups = self.show_pb(node)
|
||||
self.delete_pb(backup_dir, 'node', id_2)
|
||||
show_backups = self.show_pb(backup_dir, 'node')
|
||||
self.assertEqual(show_backups[0]['ID'], id_1)
|
||||
self.assertEqual(show_backups[1]['ID'], id_3)
|
||||
|
||||
node.stop()
|
||||
|
||||
def test_delete_increment(self):
|
||||
def test_delete_increment_page(self):
|
||||
"""delete increment and all after him"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/delete/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
# full backup mode
|
||||
self.backup_pb(node)
|
||||
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
# page backup mode
|
||||
self.backup_pb(node, backup_type="page")
|
||||
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="page")
|
||||
# page backup mode
|
||||
self.backup_pb(node, backup_type="page")
|
||||
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="page")
|
||||
# full backup mode
|
||||
self.backup_pb(node)
|
||||
|
||||
show_backups = self.show_pb(node)
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
show_backups = self.show_pb(backup_dir, 'node')
|
||||
self.assertEqual(len(show_backups), 4)
|
||||
|
||||
# delete first page backup
|
||||
self.delete_pb(node, show_backups[1]['ID'])
|
||||
self.delete_pb(backup_dir, 'node', show_backups[1]['ID'])
|
||||
|
||||
show_backups = self.show_pb(node)
|
||||
show_backups = self.show_pb(backup_dir, 'node')
|
||||
self.assertEqual(len(show_backups), 2)
|
||||
|
||||
self.assertEqual(show_backups[0]['Mode'], six.b("FULL"))
|
||||
self.assertEqual(show_backups[0]['Status'], six.b("OK"))
|
||||
self.assertEqual(show_backups[1]['Mode'], six.b("FULL"))
|
||||
self.assertEqual(show_backups[1]['Status'], six.b("OK"))
|
||||
|
||||
node.stop()
|
||||
|
||||
def test_delete_increment_ptrack(self):
|
||||
"""delete increment and all after him"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
# full backup mode
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
# page backup mode
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="ptrack")
|
||||
# page backup mode
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="ptrack")
|
||||
# full backup mode
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
show_backups = self.show_pb(backup_dir, 'node')
|
||||
self.assertEqual(len(show_backups), 4)
|
||||
|
||||
# delete first page backup
|
||||
self.delete_pb(backup_dir, 'node', show_backups[1]['ID'])
|
||||
|
||||
show_backups = self.show_pb(backup_dir, 'node')
|
||||
self.assertEqual(len(show_backups), 2)
|
||||
|
||||
self.assertEqual(show_backups[0]['Mode'], six.b("FULL"))
|
||||
|
@ -5,10 +5,9 @@ pg_probackup - utility to manage backup/recovery of PostgreSQL database.
|
||||
|
||||
pg_probackup version
|
||||
|
||||
pg_probackup init -B backup-path -D pgdata-dir
|
||||
pg_probackup init -B backup-path
|
||||
|
||||
pg_probackup set-config -B backup-dir
|
||||
[-d dbname] [-h host] [-p port] [-U username]
|
||||
pg_probackup set-config -B backup-dir --instance=instance_name
|
||||
[--log-level=log-level]
|
||||
[--log-filename=log-filename]
|
||||
[--error-log-filename=error-log-filename]
|
||||
@ -17,36 +16,47 @@ pg_probackup - utility to manage backup/recovery of PostgreSQL database.
|
||||
[--log-rotation-age=log-rotation-age]
|
||||
[--retention-redundancy=retention-redundancy]
|
||||
[--retention-window=retention-window]
|
||||
[--compress-algorithm=compress-algorithm]
|
||||
[--compress-level=compress-level]
|
||||
[-d dbname] [-h host] [-p port] [-U username]
|
||||
[--master-db=db_name] [--master-host=host_name]
|
||||
[--master-port=port] [--master-user=user_name]
|
||||
[--replica-timeout=timeout]
|
||||
|
||||
pg_probackup show-config -B backup-dir
|
||||
pg_probackup show-config -B backup-dir --instance=instance_name
|
||||
|
||||
pg_probackup backup -B backup-path -b backup-mode
|
||||
[-D pgdata-dir] [-C] [--stream [-S slot-name]] [--backup-pg-log]
|
||||
pg_probackup backup -B backup-path -b backup-mode --instance=instance_name
|
||||
[-C] [--stream [-S slot-name]] [--backup-pg-log]
|
||||
[-j num-threads] [--archive-timeout=archive-timeout]
|
||||
[--compress-algorithm=compress-algorithm]
|
||||
[--compress-level=compress-level]
|
||||
[--progress] [--delete-expired]
|
||||
[-d dbname] [-h host] [-p port] [-U username]
|
||||
[--master-db=db_name] [--master-host=host_name]
|
||||
[--master-port=port] [--master-user=user_name]
|
||||
[--replica-timeout=timeout]
|
||||
|
||||
pg_probackup restore -B backup-dir
|
||||
[-D pgdata-dir] [-i backup-id] [--progress]
|
||||
[--time=time|--xid=xid [--inclusive=boolean]]
|
||||
[--timeline=timeline] [-T OLDDIR=NEWDIR]
|
||||
pg_probackup restore -B backup-dir --instance=instance_name
|
||||
[-D pgdata-dir] [-i backup-id] [--progress]
|
||||
[--time=time|--xid=xid [--inclusive=boolean]]
|
||||
[--timeline=timeline] [-T OLDDIR=NEWDIR]
|
||||
|
||||
pg_probackup validate -B backup-dir
|
||||
[-D pgdata-dir] [-i backup-id] [--progress]
|
||||
[--time=time|--xid=xid [--inclusive=boolean]]
|
||||
[--timeline=timeline]
|
||||
pg_probackup validate -B backup-dir [--instance=instance_name]
|
||||
[-i backup-id] [--progress]
|
||||
[--time=time|--xid=xid [--inclusive=boolean]]
|
||||
[--timeline=timeline]
|
||||
|
||||
pg_probackup show -B backup-dir
|
||||
[-i backup-id]
|
||||
[--instance=instance_name [-i backup-id]]
|
||||
|
||||
pg_probackup delete -B backup-dir
|
||||
[--wal] [-i backup-id | --expired]
|
||||
pg_probackup delete -B backup-dir --instance=instance_name
|
||||
[--wal] [-i backup-id | --expired]
|
||||
|
||||
pg_probackup add-instance -B backup-dir
|
||||
--instance=instance_name
|
||||
pg_probackup add-instance -B backup-dir -D pgdata-dir
|
||||
--instance=instance_name
|
||||
|
||||
pg_probackup del-instance -B backup-dir
|
||||
--instance=instance_name
|
||||
--instance=instance_name
|
||||
|
||||
Read the website for details. <https://github.com/postgrespro/pg_probackup>
|
||||
Report bugs to <https://github.com/postgrespro/pg_probackup/issues>.
|
||||
|
@ -12,6 +12,7 @@ class FalsePositive(ProbackupTest, unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(FalsePositive, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'false_positive'
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
|
@ -7,6 +7,7 @@ import six
|
||||
from testgres import get_new_node
|
||||
import hashlib
|
||||
import re
|
||||
import pwd
|
||||
|
||||
|
||||
idx_ptrack = {
|
||||
@ -143,6 +144,7 @@ class ProbackupTest(object):
|
||||
pass
|
||||
self.probackup_path = os.path.abspath(os.path.join(
|
||||
self.dir_path, "../pg_probackup"))
|
||||
self.user = self.get_username()
|
||||
|
||||
def arcwal_dir(self, node):
|
||||
return "%s/backup/wal" % node.base_dir
|
||||
@ -329,6 +331,7 @@ class ProbackupTest(object):
|
||||
|
||||
def init_pb(self, backup_dir):
|
||||
|
||||
shutil.rmtree(backup_dir, ignore_errors=True)
|
||||
return self.run_pb([
|
||||
"init",
|
||||
"-B", backup_dir
|
||||
@ -352,8 +355,8 @@ class ProbackupTest(object):
|
||||
"-D", node.data_dir
|
||||
])
|
||||
|
||||
def clean_pb(self, node):
|
||||
shutil.rmtree(self.backup_dir(node), ignore_errors=True)
|
||||
def clean_pb(self, backup_dir):
|
||||
shutil.rmtree(backup_dir, ignore_errors=True)
|
||||
|
||||
def backup_node(self, backup_dir, instance, node, backup_type="full", options=[], async=False):
|
||||
|
||||
@ -370,11 +373,9 @@ class ProbackupTest(object):
|
||||
|
||||
return self.run_pb(cmd_list + options, async)
|
||||
|
||||
def restore_node(self, backup_dir, instance, data_dir=None, id=None, options=[]):
|
||||
def restore_node(self, backup_dir, instance, node=False, data_dir=None, backup_id=None, options=[]):
|
||||
if data_dir is None:
|
||||
data_dir = node.data_dir
|
||||
if backup_dir is None:
|
||||
backup_dir = self.backup_dir(node)
|
||||
|
||||
cmd_list = [
|
||||
"restore",
|
||||
@ -382,8 +383,8 @@ class ProbackupTest(object):
|
||||
"-D", data_dir,
|
||||
"--instance={0}".format(instance)
|
||||
]
|
||||
if id:
|
||||
cmd_list += ["-i", id]
|
||||
if backup_id:
|
||||
cmd_list += ["-i", backup_id]
|
||||
|
||||
return self.run_pb(cmd_list + options)
|
||||
|
||||
@ -449,44 +450,46 @@ class ProbackupTest(object):
|
||||
specific_record[name.strip()] = var
|
||||
return specific_record
|
||||
|
||||
def validate_pb(self, backup_dir, instance=None, id=None, options=[]):
|
||||
def validate_pb(self, backup_dir, instance=None, backup_id=None, options=[]):
|
||||
|
||||
cmd_list = [
|
||||
"validate",
|
||||
"-B", backup_dir,
|
||||
"-B", backup_dir
|
||||
]
|
||||
if instance:
|
||||
cmd_list += ["--instance={0}".format(instance)]
|
||||
if id:
|
||||
cmd_list += ["-i", id]
|
||||
if backup_id:
|
||||
cmd_list += ["-i", backup_id]
|
||||
|
||||
return self.run_pb(cmd_list + options)
|
||||
|
||||
def delete_pb(self, backup_dir, instance=None, id=None, options=[]):
|
||||
def delete_pb(self, backup_dir, instance=None, backup_id=None, options=[]):
|
||||
cmd_list = [
|
||||
"delete",
|
||||
"-B", self.backup_dir(node),
|
||||
"-B", backup_dir
|
||||
]
|
||||
if instance:
|
||||
cmd_list += ["--instance={0}".format(instance)]
|
||||
if id:
|
||||
cmd_list += ["-i", id]
|
||||
if backup_id:
|
||||
cmd_list += ["-i", backup_id]
|
||||
|
||||
# print(cmd_list)
|
||||
return self.run_pb(cmd_list + options)
|
||||
|
||||
def delete_expired(self, backup_dir, instance=None, options=[]):
|
||||
def delete_expired(self, backup_dir, instance, options=[]):
|
||||
cmd_list = [
|
||||
"delete", "--expired",
|
||||
"-B", self.backup_dir(node),
|
||||
"-B", backup_dir,
|
||||
"--instance={0}".format(instance)
|
||||
]
|
||||
return self.run_pb(cmd_list + options)
|
||||
|
||||
def show_config(self, backup_dir, instance=None):
|
||||
def show_config(self, backup_dir, instance):
|
||||
out_dict = {}
|
||||
cmd_list = [
|
||||
"show-config",
|
||||
"-B", self.backup_dir(node),
|
||||
"-B", backup_dir,
|
||||
"--instance={0}".format(instance)
|
||||
]
|
||||
res = self.run_pb(cmd_list).splitlines()
|
||||
for line in res:
|
||||
@ -556,3 +559,7 @@ class ProbackupTest(object):
|
||||
return str(var[0][0])
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_username(self):
|
||||
""" Returns current user name """
|
||||
return pwd.getpwuid(os.getuid())[0]
|
||||
|
@ -10,51 +10,55 @@ class InitTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(InitTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'init'
|
||||
|
||||
# @unittest.skip("skip")
|
||||
# @unittest.expectedFailure
|
||||
def test_success(self):
|
||||
"""Success normal init"""
|
||||
fname = self.id().split(".")[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/init/{0}".format(fname))
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname))
|
||||
self.init_pb(backup_dir)
|
||||
self.assertEqual(
|
||||
dir_files(self.backup_dir(node)),
|
||||
dir_files(backup_dir),
|
||||
['backups', 'wal']
|
||||
)
|
||||
self.add_instance(node=node, instance='test')
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
|
||||
self.assertEqual("INFO: Instance 'test' deleted successfully\n",
|
||||
self.del_instance(node=node, instance='test'),
|
||||
self.assertEqual("INFO: Instance 'node' successfully deleted\n",
|
||||
self.del_instance(backup_dir, 'node', node),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
try:
|
||||
self.show_pb(node, instance='test')
|
||||
self.show_pb(backup_dir, 'node')
|
||||
self.assertEqual(1, 0, 'Expecting Error due to show of non-existing instance. Output: {0} \n CMD: {1}'.format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(e.message,
|
||||
"ERROR: Instance 'test' does not exist in this backup catalog\n",
|
||||
"ERROR: Instance 'node' does not exist in this backup catalog\n",
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(e.message, self.cmd))
|
||||
|
||||
def test_already_exist(self):
|
||||
"""Failure with backup catalog already existed"""
|
||||
fname = self.id().split(".")[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/init/{0}".format(fname))
|
||||
self.init_pb(node)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname))
|
||||
self.init_pb(backup_dir)
|
||||
try:
|
||||
self.init_pb(node)
|
||||
self.show_pb(backup_dir, 'node')
|
||||
self.assertEqual(1, 0, 'Expecting Error due to initialization in non-empty directory. Output: {0} \n CMD: {1}'.format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(e.message,
|
||||
"ERROR: backup catalog already exist and it's not empty\n",
|
||||
"ERROR: Instance 'node' does not exist in this backup catalog\n",
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
def test_abs_path(self):
|
||||
"""failure with backup catalog should be given as absolute path"""
|
||||
fname = self.id().split(".")[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/init/{0}".format(fname))
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname))
|
||||
try:
|
||||
self.run_pb(["init", "-B", path.relpath("%s/backup" % node.base_dir, self.dir_path)])
|
||||
self.assertEqual(1, 0, 'Expecting Error due to initialization with non-absolute path in --backup-path. Output: {0} \n CMD: {1}'.format(
|
||||
|
@ -1,5 +1,5 @@
|
||||
import unittest
|
||||
from os import path
|
||||
import os
|
||||
import six
|
||||
from helpers.ptrack_helpers import ProbackupTest, ProbackupException
|
||||
from testgres import stop_all
|
||||
@ -9,6 +9,7 @@ class OptionTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(OptionTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'option'
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
@ -19,166 +20,195 @@ class OptionTest(ProbackupTest, unittest.TestCase):
|
||||
def test_help_1(self):
|
||||
"""help options"""
|
||||
fname = self.id().split(".")[3]
|
||||
with open(path.join(self.dir_path, "expected/option_help.out"), "rb") as help_out:
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
with open(os.path.join(self.dir_path, "expected/option_help.out"), "rb") as help_out:
|
||||
self.assertEqual(
|
||||
self.run_pb(["--help"]),
|
||||
help_out.read()
|
||||
)
|
||||
|
||||
# @unittest.skip("skip")
|
||||
def test_version_2(self):
|
||||
"""help options"""
|
||||
fname = self.id().split(".")[3]
|
||||
with open(path.join(self.dir_path, "expected/option_version.out"), "rb") as version_out:
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
with open(os.path.join(self.dir_path, "expected/option_version.out"), "rb") as version_out:
|
||||
self.assertEqual(
|
||||
self.run_pb(["--version"]),
|
||||
version_out.read()
|
||||
)
|
||||
|
||||
# @unittest.skip("skip")
|
||||
def test_without_backup_path_3(self):
|
||||
"""backup command failure without backup mode option"""
|
||||
fname = self.id().split(".")[3]
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
try:
|
||||
self.run_pb(["backup", "-b", "full"])
|
||||
# we should die here because exception is what we expect to happen
|
||||
exit(1)
|
||||
self.assertEqual(1, 0, "Expecting Error because '-B' parameter is not specified.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(
|
||||
e.message,
|
||||
'ERROR: required parameter not specified: BACKUP_PATH (-B, --backup-path)\n'
|
||||
)
|
||||
self.assertEqual(e.message, 'ERROR: required parameter not specified: BACKUP_PATH (-B, --backup-path)\n',
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
|
||||
# @unittest.skip("skip")
|
||||
def test_options_4(self):
|
||||
"""check options test"""
|
||||
fname = self.id().split(".")[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/option/{0}".format(fname))
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
pg_options={'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
try:
|
||||
node.stop()
|
||||
except:
|
||||
pass
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
|
||||
# backup command failure without instance option
|
||||
try:
|
||||
self.run_pb(["backup", "-B", backup_dir, "-D", node.data_dir, "-b", "full"])
|
||||
self.assertEqual(1, 0, "Expecting Error because 'instance' parameter is not specified.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: required parameter not specified: --instance\n',
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
# backup command failure without backup mode option
|
||||
try:
|
||||
self.run_pb(["backup", "-B", self.backup_dir(node), "-D", node.data_dir])
|
||||
# we should die here because exception is what we expect to happen
|
||||
exit(1)
|
||||
self.run_pb(["backup", "-B", backup_dir, "--instance=node", "-D", node.data_dir])
|
||||
self.assertEqual(1, 0, "Expecting Error because '-b' parameter is not specified.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
# print e.message
|
||||
self.assertEqual(
|
||||
e.message,
|
||||
'ERROR: required parameter not specified: BACKUP_MODE (-b, --backup-mode)\n'
|
||||
)
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: required parameter not specified: BACKUP_MODE (-b, --backup-mode)\n',
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
# backup command failure with invalid backup mode option
|
||||
try:
|
||||
self.run_pb(["backup", "-b", "bad", "-B", self.backup_dir(node)])
|
||||
# we should die here because exception is what we expect to happen
|
||||
exit(1)
|
||||
self.run_pb(["backup", "-B", backup_dir, "--instance=node", "-b", "bad"])
|
||||
self.assertEqual(1, 0, "Expecting Error because backup-mode parameter is invalid.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(
|
||||
e.message,
|
||||
'ERROR: invalid backup-mode "bad"\n'
|
||||
)
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: invalid backup-mode "bad"\n',
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
|
||||
# delete failure without ID
|
||||
try:
|
||||
self.run_pb(["delete", "-B", self.backup_dir(node)])
|
||||
self.run_pb(["delete", "-B", backup_dir, "--instance=node"])
|
||||
# we should die here because exception is what we expect to happen
|
||||
exit(1)
|
||||
self.assertEqual(1, 0, "Expecting Error because backup ID is omitted.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(
|
||||
e.message,
|
||||
'ERROR: required backup ID not specified\n'
|
||||
)
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: required backup ID not specified\n',
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
#@unittest.skip("skip")
|
||||
def test_options_5(self):
|
||||
"""check options test"""
|
||||
fname = self.id().split(".")[3]
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
pg_options={'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
self.assertEqual(self.init_pb(backup_dir), six.b("INFO: Backup catalog '{0}' successfully inited\n".format(backup_dir)))
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
|
||||
node.start()
|
||||
|
||||
# syntax error in pg_probackup.conf
|
||||
with open(path.join(self.backup_dir(node), "pg_probackup.conf"), "a") as conf:
|
||||
with open(os.path.join(backup_dir, "backups", "node", "pg_probackup.conf"), "a") as conf:
|
||||
conf.write(" = INFINITE\n")
|
||||
|
||||
try:
|
||||
self.backup_pb(node)
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
# we should die here because exception is what we expect to happen
|
||||
exit(1)
|
||||
self.assertEqual(1, 0, "Expecting Error because of garbage in pg_probackup.conf.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(
|
||||
e.message,
|
||||
'ERROR: syntax error in " = INFINITE"\n'
|
||||
)
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: syntax error in " = INFINITE"\n',
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
self.clean_pb(node)
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
self.clean_pb(backup_dir)
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
|
||||
# invalid value in pg_probackup.conf
|
||||
with open(path.join(self.backup_dir(node), "pg_probackup.conf"), "a") as conf:
|
||||
with open(os.path.join(backup_dir, "backups", "node", "pg_probackup.conf"), "a") as conf:
|
||||
conf.write("BACKUP_MODE=\n")
|
||||
|
||||
try:
|
||||
self.backup_pb(node, backup_type=None),
|
||||
self.backup_node(backup_dir, 'node', node, backup_type=None),
|
||||
# we should die here because exception is what we expect to happen
|
||||
exit(1)
|
||||
self.assertEqual(1, 0, "Expecting Error because of invalid backup-mode in pg_probackup.conf.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(
|
||||
e.message,
|
||||
'ERROR: invalid backup-mode ""\n'
|
||||
)
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: invalid backup-mode ""\n',
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
self.clean_pb(node)
|
||||
self.clean_pb(backup_dir)
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
|
||||
# Command line parameters should override file values
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
with open(path.join(self.backup_dir(node), "pg_probackup.conf"), "a") as conf:
|
||||
with open(os.path.join(backup_dir, "backups", "node", "pg_probackup.conf"), "a") as conf:
|
||||
conf.write("retention-redundancy=1\n")
|
||||
|
||||
self.assertEqual(
|
||||
self.show_config(node)['retention-redundancy'],
|
||||
self.show_config(backup_dir, 'node')['retention-redundancy'],
|
||||
six.b('1')
|
||||
)
|
||||
|
||||
# User cannot send --system-identifier parameter via command line
|
||||
try:
|
||||
self.backup_pb(node, options=["--system-identifier", "123"]),
|
||||
self.backup_node(backup_dir, 'node', node, options=["--system-identifier", "123"]),
|
||||
# we should die here because exception is what we expect to happen
|
||||
exit(1)
|
||||
self.assertEqual(1, 0, "Expecting Error because option system-identifier cannot be specified in command line.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(
|
||||
e.message,
|
||||
'ERROR: option system-identifier cannot be specified in command line\n'
|
||||
)
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: option system-identifier cannot be specified in command line\n',
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
# invalid value in pg_probackup.conf
|
||||
with open(path.join(self.backup_dir(node), "pg_probackup.conf"), "a") as conf:
|
||||
with open(os.path.join(backup_dir, "backups", "node", "pg_probackup.conf"), "a") as conf:
|
||||
conf.write("SMOOTH_CHECKPOINT=FOO\n")
|
||||
|
||||
try:
|
||||
self.backup_pb(node),
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
# we should die here because exception is what we expect to happen
|
||||
exit(1)
|
||||
self.assertEqual(1, 0, "Expecting Error because option -C should be boolean.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(
|
||||
e.message,
|
||||
"ERROR: option -C, --smooth-checkpoint should be a boolean: 'FOO'\n"
|
||||
)
|
||||
self.assertEqual(e.message,
|
||||
"ERROR: option -C, --smooth-checkpoint should be a boolean: 'FOO'\n",
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
self.clean_pb(node)
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
self.clean_pb(backup_dir)
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
|
||||
# invalid option in pg_probackup.conf
|
||||
with open(path.join(self.backup_dir(node), "pg_probackup.conf"), "a") as conf:
|
||||
with open(os.path.join(backup_dir, "backups", "node", "pg_probackup.conf"), "a") as conf:
|
||||
conf.write("TIMELINEID=1\n")
|
||||
|
||||
try:
|
||||
self.backup_pb(node),
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
# we should die here because exception is what we expect to happen
|
||||
exit(1)
|
||||
self.assertEqual(1, 0, 'Expecting Error because of invalid option "TIMELINEID".\n Output: {0} \n CMD: {1}'.format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(
|
||||
e.message,
|
||||
'ERROR: invalid option "TIMELINEID"\n'
|
||||
)
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: invalid option "TIMELINEID"\n',
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
self.clean_pb(node)
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
node.stop()
|
||||
# self.clean_pb(backup_dir)
|
||||
# node.stop()
|
||||
|
@ -15,19 +15,17 @@ class ReplicaTest(ProbackupTest, unittest.TestCase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ReplicaTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'replica'
|
||||
self.instance_1 = 'master'
|
||||
self.instance_2 = 'slave'
|
||||
self.instance_master = 'master'
|
||||
self.instance_replica = 'replica'
|
||||
|
||||
# @classmethod
|
||||
# def tearDownClass(cls):
|
||||
# stop_all()
|
||||
|
||||
# @unittest.skip("skip")
|
||||
@unittest.skip("skip")
|
||||
# @unittest.expectedFailure
|
||||
def test_replica_stream_full_backup(self):
|
||||
"""
|
||||
make full stream backup from replica
|
||||
"""
|
||||
"""make full stream backup from replica"""
|
||||
fname = self.id().split('.')[3]
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
master = self.make_simple_node(base_dir="{0}/{1}/master".format(self.module_name, fname),
|
||||
@ -35,59 +33,127 @@ class ReplicaTest(ProbackupTest, unittest.TestCase):
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'max_wal_senders': '2', 'checkpoint_timeout': '5min'}
|
||||
)
|
||||
master.start()
|
||||
shutil.rmtree(backup_dir, ignore_errors=True)
|
||||
self.init_pb(backup_dir)
|
||||
instance = ''
|
||||
self.add_instance(backup_dir, self.instance_1, master)
|
||||
self.set_archiving(backup_dir, self.instance_1, master)
|
||||
master.restart()
|
||||
self.add_instance(backup_dir, self.instance_master, master)
|
||||
master.start()
|
||||
|
||||
slave = self.make_simple_node(base_dir="{0}/{1}/slave".format(self.module_name, fname))
|
||||
slave_port = slave.port
|
||||
slave.cleanup()
|
||||
# Make empty Object 'replica' from new node
|
||||
replica = self.make_simple_node(base_dir="{0}/{1}/replica".format(self.module_name, fname))
|
||||
replica_port = replica.port
|
||||
replica.cleanup()
|
||||
|
||||
# FULL BACKUP
|
||||
self.backup_node(backup_dir, self.instance_1, master, backup_type='full', options=['--stream'])
|
||||
# FULL STREAM backup of master
|
||||
self.backup_node(backup_dir, self.instance_master, master, backup_type='full', options=['--stream'])
|
||||
master.psql(
|
||||
"postgres",
|
||||
"create table t_heap as select i as id, md5(i::text) as text, md5(repeat(i::text,10))::tsvector as tsvector from generate_series(0,256) i")
|
||||
|
||||
before = master.execute("postgres", "SELECT * FROM t_heap")
|
||||
|
||||
#PAGE BACKUP
|
||||
self.backup_node(backup_dir, self.instance_1, master, backup_type='page', options=['--stream'])
|
||||
self.restore_node(backup_dir, self.instance_1, slave.data_dir)
|
||||
# FULL STREAM backup of master
|
||||
self.backup_node(backup_dir, self.instance_master, master, backup_type='full', options=['--stream'])
|
||||
|
||||
slave.append_conf('postgresql.auto.conf', 'port = {0}'.format(slave.port))
|
||||
slave.append_conf('postgresql.auto.conf', 'hot_standby = on')
|
||||
|
||||
slave.append_conf('recovery.conf', "standby_mode = 'on'")
|
||||
slave.append_conf('recovery.conf',
|
||||
# Restore last backup from master to Replica directory
|
||||
self.restore_node(backup_dir, self.instance_master, replica.data_dir)
|
||||
# Set Replica
|
||||
replica.append_conf('postgresql.auto.conf', 'port = {0}'.format(replica.port))
|
||||
replica.append_conf('postgresql.auto.conf', 'hot_standby = on')
|
||||
replica.append_conf('recovery.conf', "standby_mode = 'on'")
|
||||
replica.append_conf('recovery.conf',
|
||||
"primary_conninfo = 'user={0} port={1} sslmode=prefer sslcompression=1'".format(get_username(), master.port))
|
||||
slave.start({"-t": "600"})
|
||||
# Replica Ready
|
||||
replica.start({"-t": "600"})
|
||||
|
||||
# Check replica
|
||||
after = slave.execute("postgres", "SELECT * FROM t_heap")
|
||||
after = replica.execute("postgres", "SELECT * FROM t_heap")
|
||||
self.assertEqual(before, after)
|
||||
|
||||
# Make backup from replica
|
||||
self.add_instance(backup_dir, self.instance_2, slave)
|
||||
# Add instance replica
|
||||
self.add_instance(backup_dir, self.instance_replica, replica)
|
||||
|
||||
# FULL STREAM backup of replica
|
||||
self.assertTrue('INFO: Wait end of WAL streaming' and 'completed' in
|
||||
self.backup_node(backup_dir, self.instance_2, slave, backup_type='full', options=[
|
||||
self.backup_node(backup_dir, self.instance_replica, replica, backup_type='full', options=[
|
||||
'--stream', '--log-level=verbose', '--master-host=localhost', '--master-db=postgres', '--master-port={0}'.format(master.port)]))
|
||||
self.validate_pb(backup_dir, self.instance_2)
|
||||
self.assertEqual('OK', self.show_pb(backup_dir, self.instance_2)[0]['Status'])
|
||||
|
||||
# Validate instance replica
|
||||
self.validate_pb(backup_dir, self.instance_replica)
|
||||
self.assertEqual('OK', self.show_pb(backup_dir, self.instance_replica)[0]['Status'])
|
||||
|
||||
def test_replica_archive_full_backup(self):
|
||||
"""make page archive backup from replica"""
|
||||
fname = self.id().split('.')[3]
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
master = self.make_simple_node(base_dir="{0}/{1}/master".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'max_wal_senders': '2', 'checkpoint_timeout': '5min'}
|
||||
)
|
||||
self.set_archiving(backup_dir, self.instance_master, master)
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, self.instance_master, master)
|
||||
master.start()
|
||||
|
||||
# Make empty Object 'replica' from new node
|
||||
replica = self.make_simple_node(base_dir="{0}/{1}/replica".format(self.module_name, fname))
|
||||
replica_port = replica.port
|
||||
replica.cleanup()
|
||||
|
||||
# FULL ARCHIVE backup of master
|
||||
self.backup_node(backup_dir, self.instance_master, master, backup_type='full')
|
||||
# Create table t_heap
|
||||
master.psql(
|
||||
"postgres",
|
||||
"create table t_heap as select i as id, md5(i::text) as text, md5(repeat(i::text,10))::tsvector as tsvector from generate_series(0,256) i")
|
||||
before = master.execute("postgres", "SELECT * FROM t_heap")
|
||||
|
||||
# PAGE ARCHIVE backup of master
|
||||
self.backup_node(backup_dir, self.instance_master, master, backup_type='page')
|
||||
|
||||
# Restore last backup from master to Replica directory
|
||||
self.restore_node(backup_dir, self.instance_master, replica.data_dir)
|
||||
|
||||
# Set Replica
|
||||
self.set_archiving(backup_dir, self.instance_replica, replica, replica=True)
|
||||
replica.append_conf('postgresql.auto.conf', 'port = {0}'.format(replica.port))
|
||||
replica.append_conf('postgresql.auto.conf', 'hot_standby = on')
|
||||
|
||||
replica.append_conf('recovery.conf', "standby_mode = 'on'")
|
||||
replica.append_conf('recovery.conf',
|
||||
"primary_conninfo = 'user={0} port={1} sslmode=prefer sslcompression=1'".format(get_username(), master.port))
|
||||
replica.start({"-t": "600"})
|
||||
|
||||
# Check replica
|
||||
after = replica.execute("postgres", "SELECT * FROM t_heap")
|
||||
self.assertEqual(before, after)
|
||||
|
||||
# Make FULL ARCHIVE backup from replica
|
||||
self.add_instance(backup_dir, self.instance_replica, replica)
|
||||
self.assertTrue('INFO: Wait end of WAL streaming' and 'completed' in
|
||||
self.backup_node(backup_dir, self.instance_replica, replica, backup_type='full', options=[
|
||||
'--log-level=verbose', '--master-host=localhost', '--master-db=postgres', '--master-port={0}'.format(master.port)]))
|
||||
self.validate_pb(backup_dir, self.instance_replica)
|
||||
self.assertEqual('OK', self.show_pb(backup_dir, self.instance_replica)[0]['Status'])
|
||||
|
||||
# Drop Table t_heap
|
||||
after = master.execute("postgres", "drop table t_heap")
|
||||
master.psql(
|
||||
"postgres",
|
||||
"create table t_heap as select i as id, md5(i::text) as text, md5(repeat(i::text,10))::tsvector as tsvector from generate_series(0,512) i")
|
||||
before = master.execute("postgres", "SELECT * FROM t_heap")
|
||||
|
||||
# Make page backup from replica
|
||||
self.assertTrue('INFO: Wait end of WAL streaming' and 'completed' in
|
||||
self.backup_node(backup_dir, self.instance_replica, replica, backup_type='page', options=[
|
||||
'--log-level=verbose', '--master-host=localhost', '--master-db=postgres', '--master-port={0}'.format(master.port)]))
|
||||
self.validate_pb(backup_dir, self.instance_replica)
|
||||
self.assertEqual('OK', self.show_pb(backup_dir, self.instance_replica)[0]['Status'])
|
||||
|
||||
@unittest.skip("skip")
|
||||
def test_replica_archive_full_backup(self):
|
||||
def test_replica_archive_full_backup_123(self):
|
||||
"""
|
||||
make full archive backup from replica
|
||||
"""
|
||||
fname = self.id().split('.')[3]
|
||||
master = self.make_simple_node(base_dir="tmp_dirs/replica/{0}/master".format(fname),
|
||||
set_archiving=True,
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'max_wal_senders': '2'}
|
||||
@ -95,9 +161,9 @@ class ReplicaTest(ProbackupTest, unittest.TestCase):
|
||||
master.append_conf('postgresql.auto.conf', 'archive_timeout = 10')
|
||||
master.start()
|
||||
|
||||
slave = self.make_simple_node(base_dir="tmp_dirs/replica/{0}/slave".format(fname))
|
||||
slave_port = slave.port
|
||||
slave.cleanup()
|
||||
replica = self.make_simple_node(base_dir="tmp_dirs/replica/{0}/replica".format(fname))
|
||||
replica_port = replica.port
|
||||
replica.cleanup()
|
||||
|
||||
self.assertEqual(self.init_pb(master), six.b(""))
|
||||
self.backup_pb(node=master, backup_type='full', options=['--stream'])
|
||||
@ -109,27 +175,27 @@ class ReplicaTest(ProbackupTest, unittest.TestCase):
|
||||
before = master.execute("postgres", "SELECT * FROM t_heap")
|
||||
|
||||
id = self.backup_pb(master, backup_type='page', options=['--stream'])
|
||||
self.restore_pb(backup_dir=self.backup_dir(master), data_dir=slave.data_dir)
|
||||
self.restore_pb(backup_dir=self.backup_dir(master), data_dir=replica.data_dir)
|
||||
|
||||
# Settings for Replica
|
||||
slave.append_conf('postgresql.auto.conf', 'port = {0}'.format(slave.port))
|
||||
slave.append_conf('postgresql.auto.conf', 'hot_standby = on')
|
||||
replica.append_conf('postgresql.auto.conf', 'port = {0}'.format(replica.port))
|
||||
replica.append_conf('postgresql.auto.conf', 'hot_standby = on')
|
||||
# Set Archiving for replica
|
||||
self.set_archiving_conf(slave, replica=True)
|
||||
self.set_archiving_conf(replica, replica=True)
|
||||
|
||||
slave.append_conf('recovery.conf', "standby_mode = 'on'")
|
||||
slave.append_conf('recovery.conf',
|
||||
replica.append_conf('recovery.conf', "standby_mode = 'on'")
|
||||
replica.append_conf('recovery.conf',
|
||||
"primary_conninfo = 'user=gsmol port={0} sslmode=prefer sslcompression=1'".format(master.port))
|
||||
slave.start({"-t": "600"})
|
||||
replica.start({"-t": "600"})
|
||||
# Replica Started
|
||||
|
||||
# master.execute("postgres", "checkpoint")
|
||||
|
||||
# Check replica
|
||||
after = slave.execute("postgres", "SELECT * FROM t_heap")
|
||||
after = replica.execute("postgres", "SELECT * FROM t_heap")
|
||||
self.assertEqual(before, after)
|
||||
|
||||
# Make backup from replica
|
||||
self.assertEqual(self.init_pb(slave), six.b(""))
|
||||
self.backup_pb(slave, backup_type='full', options=['--archive-timeout=30'])
|
||||
self.validate_pb(slave)
|
||||
self.assertEqual(self.init_pb(replica), six.b(""))
|
||||
self.backup_pb(replica, backup_type='full', options=['--archive-timeout=30'])
|
||||
self.validate_pb(replica)
|
||||
|
@ -1,4 +1,5 @@
|
||||
import unittest
|
||||
import os
|
||||
from sys import exit
|
||||
from testgres import get_new_node, stop_all
|
||||
from helpers.ptrack_helpers import ProbackupTest, idx_ptrack
|
||||
@ -7,6 +8,7 @@ from helpers.ptrack_helpers import ProbackupTest, idx_ptrack
|
||||
class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SimpleTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'ptrack_clean'
|
||||
|
||||
def teardown(self):
|
||||
stop_all()
|
||||
@ -15,13 +17,16 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# @unittest.expectedFailure
|
||||
def test_ptrack_clean(self):
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir='tmp_dirs/ptrack/{0}'.format(fname),
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
set_archiving=True,
|
||||
initdb_params=['--data-checksums', '-A trust'],
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'ptrack_enable': 'on', 'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.create_tblspace_in_node(node, 'somedata')
|
||||
|
||||
# Create table and indexes
|
||||
@ -35,8 +40,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
i, idx_ptrack[i]['relation'], idx_ptrack[i]['type'], idx_ptrack[i]['column']))
|
||||
|
||||
# Make full backup to clean every ptrack
|
||||
self.init_pb(node)
|
||||
self.backup_pb(node, backup_type='full', options=['-j100', '--stream'])
|
||||
self.backup_node(backup_dir, 'node', node, options=['-j100', '--stream'])
|
||||
|
||||
for i in idx_ptrack:
|
||||
# get fork size and calculate it in pages
|
||||
@ -52,7 +56,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
node.psql('postgres', 'update t_heap set text = md5(text), tsvector = md5(repeat(tsvector::text, 10))::tsvector;')
|
||||
node.psql('postgres', 'vacuum t_heap')
|
||||
|
||||
id = self.backup_pb(node, backup_type='ptrack', options=['-j100', '--stream'])
|
||||
backup_id = self.backup_node(backup_dir, 'node', node, backup_type='ptrack', options=['-j100', '--stream'])
|
||||
node.psql('postgres', 'checkpoint')
|
||||
|
||||
for i in idx_ptrack:
|
||||
@ -71,7 +75,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
node.psql('postgres', 'vacuum t_heap')
|
||||
|
||||
# Make page backup to clean every ptrack
|
||||
self.backup_pb(node, backup_type='page', options=['-j100'])
|
||||
self.backup_node(backup_dir, 'node', node, backup_type='page', options=['-j100'])
|
||||
node.psql('postgres', 'checkpoint')
|
||||
|
||||
for i in idx_ptrack:
|
||||
@ -85,8 +89,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# check that ptrack bits are cleaned
|
||||
self.check_ptrack_clean(idx_ptrack[i], idx_ptrack[i]['size'])
|
||||
|
||||
print self.show_pb(node, as_text=True)
|
||||
self.clean_pb(node)
|
||||
print self.show_pb(backup_dir, 'node', as_text=True)
|
||||
node.stop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -1,4 +1,5 @@
|
||||
import unittest
|
||||
import os
|
||||
from sys import exit
|
||||
from testgres import get_new_node, stop_all
|
||||
from helpers.ptrack_helpers import ProbackupTest, idx_ptrack
|
||||
@ -7,6 +8,7 @@ from helpers.ptrack_helpers import ProbackupTest, idx_ptrack
|
||||
class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SimpleTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'ptrack_cluster'
|
||||
|
||||
def teardown(self):
|
||||
# clean_all()
|
||||
@ -16,12 +18,15 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# @unittest.expectedFailure
|
||||
def test_ptrack_cluster_btree(self):
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/ptrack/{0}".format(fname),
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums', '-A trust'],
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'ptrack_enable': 'on', 'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.create_tblspace_in_node(node, 'somedata')
|
||||
|
||||
# Create table and indexes
|
||||
@ -46,8 +51,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
idx_ptrack[i]['old_pages'] = self.get_md5_per_page_for_fork(
|
||||
idx_ptrack[i]['path'], idx_ptrack[i]['old_size'])
|
||||
|
||||
self.init_pb(node)
|
||||
self.backup_pb(node, backup_type='full', options=['-j100', '--stream'])
|
||||
self.backup_node(backup_dir, 'node', node, options=['-j100', '--stream'])
|
||||
|
||||
node.psql('postgres', 'delete from t_heap where id%2 = 1')
|
||||
node.psql('postgres', 'cluster t_heap using t_btree')
|
||||
@ -68,17 +72,19 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# compare pages and check ptrack sanity
|
||||
self.check_ptrack_sanity(idx_ptrack[i])
|
||||
|
||||
self.clean_pb(node)
|
||||
node.stop()
|
||||
|
||||
def test_ptrack_cluster_spgist(self):
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/ptrack/{0}".format(fname),
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums', '-A trust'],
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'ptrack_enable': 'on', 'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.create_tblspace_in_node(node, 'somedata')
|
||||
|
||||
# Create table and indexes
|
||||
@ -103,8 +109,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
idx_ptrack[i]['old_pages'] = self.get_md5_per_page_for_fork(
|
||||
idx_ptrack[i]['path'], idx_ptrack[i]['old_size'])
|
||||
|
||||
self.init_pb(node)
|
||||
self.backup_pb(node, backup_type='full', options=['-j100', '--stream'])
|
||||
self.backup_node(backup_dir, 'node', node, options=['-j100', '--stream'])
|
||||
|
||||
node.psql('postgres', 'delete from t_heap where id%2 = 1')
|
||||
node.psql('postgres', 'cluster t_heap using t_spgist')
|
||||
@ -125,17 +130,19 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# compare pages and check ptrack sanity
|
||||
self.check_ptrack_sanity(idx_ptrack[i])
|
||||
|
||||
self.clean_pb(node)
|
||||
node.stop()
|
||||
|
||||
def test_ptrack_cluster_brin(self):
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/ptrack/{0}".format(fname),
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums', '-A trust'],
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'ptrack_enable': 'on', 'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.create_tblspace_in_node(node, 'somedata')
|
||||
|
||||
# Create table and indexes
|
||||
@ -160,8 +167,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
idx_ptrack[i]['old_pages'] = self.get_md5_per_page_for_fork(
|
||||
idx_ptrack[i]['path'], idx_ptrack[i]['old_size'])
|
||||
|
||||
self.init_pb(node)
|
||||
self.backup_pb(node, backup_type='full', options=['-j100', '--stream'])
|
||||
self.backup_node(backup_dir, 'node', node, options=['-j100', '--stream'])
|
||||
|
||||
node.psql('postgres', 'delete from t_heap where id%2 = 1')
|
||||
node.psql('postgres', 'cluster t_heap using t_brin')
|
||||
@ -182,17 +188,19 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# compare pages and check ptrack sanity
|
||||
self.check_ptrack_sanity(idx_ptrack[i])
|
||||
|
||||
self.clean_pb(node)
|
||||
node.stop()
|
||||
|
||||
def test_ptrack_cluster_gist(self):
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/ptrack/{0}".format(fname),
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums', '-A trust'],
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'ptrack_enable': 'on', 'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.create_tblspace_in_node(node, 'somedata')
|
||||
|
||||
# Create table and indexes
|
||||
@ -217,8 +225,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
idx_ptrack[i]['old_pages'] = self.get_md5_per_page_for_fork(
|
||||
idx_ptrack[i]['path'], idx_ptrack[i]['old_size'])
|
||||
|
||||
self.init_pb(node)
|
||||
self.backup_pb(node, backup_type='full', options=['-j100', '--stream'])
|
||||
self.backup_node(backup_dir, 'node', node, options=['-j100', '--stream'])
|
||||
|
||||
node.psql('postgres', 'delete from t_heap where id%2 = 1')
|
||||
node.psql('postgres', 'cluster t_heap using t_gist')
|
||||
@ -239,17 +246,19 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# compare pages and check ptrack sanity
|
||||
self.check_ptrack_sanity(idx_ptrack[i])
|
||||
|
||||
self.clean_pb(node)
|
||||
node.stop()
|
||||
|
||||
def test_ptrack_cluster_gin(self):
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/ptrack/{0}".format(fname),
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums', '-A trust'],
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'ptrack_enable': 'on', 'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.create_tblspace_in_node(node, 'somedata')
|
||||
|
||||
# Create table and indexes
|
||||
@ -274,8 +283,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
idx_ptrack[i]['old_pages'] = self.get_md5_per_page_for_fork(
|
||||
idx_ptrack[i]['path'], idx_ptrack[i]['old_size'])
|
||||
|
||||
self.init_pb(node)
|
||||
self.backup_pb(node, backup_type='full', options=['-j100', '--stream'])
|
||||
self.backup_node(backup_dir, 'node', node, options=['-j100', '--stream'])
|
||||
|
||||
node.psql('postgres', 'delete from t_heap where id%2 = 1')
|
||||
node.psql('postgres', 'cluster t_heap using t_gin')
|
||||
@ -296,7 +304,6 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# compare pages and check ptrack sanity
|
||||
self.check_ptrack_sanity(idx_ptrack[i])
|
||||
|
||||
self.clean_pb(node)
|
||||
node.stop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -10,6 +10,7 @@ from time import sleep
|
||||
class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SimpleTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'ptrack_move_to_tablespace'
|
||||
|
||||
def teardown(self):
|
||||
# clean_all()
|
||||
@ -18,13 +19,16 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# @unittest.skip("skip")
|
||||
# @unittest.expectedFailure
|
||||
def test_ptrack_recovery(self):
|
||||
fname = self.id().split(".")[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/ptrack/{0}".format(fname),
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums', '-A trust'],
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'ptrack_enable': 'on', 'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.create_tblspace_in_node(node, 'somedata')
|
||||
|
||||
# Create table and indexes
|
||||
@ -54,7 +58,6 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# check that ptrack has correct bits after recovery
|
||||
self.check_ptrack_recovery(idx_ptrack[i])
|
||||
|
||||
self.clean_pb(node)
|
||||
node.stop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -10,6 +10,7 @@ from time import sleep
|
||||
class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SimpleTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'ptrack_move_to_tablespace'
|
||||
|
||||
def teardown(self):
|
||||
# clean_all()
|
||||
@ -18,13 +19,16 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# @unittest.skip("skip")
|
||||
# @unittest.expectedFailure
|
||||
def test_ptrack_recovery(self):
|
||||
fname = self.id().split(".")[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/ptrack/{0}".format(fname),
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums', '-A trust'],
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'ptrack_enable': 'on', 'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.create_tblspace_in_node(node, 'somedata')
|
||||
|
||||
# Create table
|
||||
@ -56,7 +60,6 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# check that ptrack has correct bits after recovery
|
||||
self.check_ptrack_recovery(idx_ptrack[i])
|
||||
|
||||
self.clean_pb(node)
|
||||
node.stop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -1,4 +1,5 @@
|
||||
import unittest
|
||||
import os
|
||||
from sys import exit
|
||||
from testgres import get_new_node, stop_all
|
||||
from helpers.ptrack_helpers import ProbackupTest, idx_ptrack
|
||||
@ -7,6 +8,7 @@ from helpers.ptrack_helpers import ProbackupTest, idx_ptrack
|
||||
class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SimpleTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'ptrack_vacuum'
|
||||
|
||||
def teardown(self):
|
||||
# clean_all()
|
||||
@ -16,12 +18,15 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# @unittest.expectedFailure
|
||||
def test_ptrack_vacuum(self):
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir='tmp_dirs/ptrack/{0}'.format(fname),
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums', '-A trust'],
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'ptrack_enable': 'on', 'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.create_tblspace_in_node(node, 'somedata')
|
||||
|
||||
# Create table and indexes
|
||||
@ -47,8 +52,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
idx_ptrack[i]['path'], idx_ptrack[i]['old_size'])
|
||||
|
||||
# Make full backup to clean every ptrack
|
||||
self.init_pb(node)
|
||||
self.backup_pb(node, backup_type='full', options=['-j100', '--stream'])
|
||||
self.backup_node(backup_dir, 'node', node, options=['-j100', '--stream'])
|
||||
for i in idx_ptrack:
|
||||
idx_ptrack[i]['ptrack'] = self.get_ptrack_bits_per_page_for_fork(
|
||||
node, idx_ptrack[i]['path'], idx_ptrack[i]['old_size'])
|
||||
@ -74,7 +78,6 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# compare pages and check ptrack sanity
|
||||
self.check_ptrack_sanity(idx_ptrack[i])
|
||||
|
||||
self.clean_pb(node)
|
||||
node.stop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -1,3 +1,4 @@
|
||||
import os
|
||||
import unittest
|
||||
from sys import exit
|
||||
from testgres import get_new_node, stop_all
|
||||
@ -7,6 +8,7 @@ from helpers.ptrack_helpers import ProbackupTest, idx_ptrack
|
||||
class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SimpleTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'ptrack_vacuum_bits_frozen'
|
||||
|
||||
def teardown(self):
|
||||
# clean_all()
|
||||
@ -16,12 +18,15 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# @unittest.expectedFailure
|
||||
def test_ptrack_vacuum_bits_frozen(self):
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir='tmp_dirs/ptrack/{0}'.format(fname),
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums', '-A trust'],
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'ptrack_enable': 'on', 'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.create_tblspace_in_node(node, 'somedata')
|
||||
|
||||
# Create table and indexes
|
||||
@ -45,8 +50,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
idx_ptrack[i]['old_pages'] = self.get_md5_per_page_for_fork(
|
||||
idx_ptrack[i]['path'], idx_ptrack[i]['old_size'])
|
||||
|
||||
self.init_pb(node)
|
||||
self.backup_pb(node, backup_type='full', options=['-j100', '--stream'])
|
||||
self.backup_node(backup_dir, 'node', node, options=['-j100', '--stream'])
|
||||
|
||||
node.psql('postgres', 'vacuum freeze t_heap')
|
||||
node.psql('postgres', 'checkpoint')
|
||||
@ -65,8 +69,6 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
# compare pages and check ptrack sanity
|
||||
self.check_ptrack_sanity(idx_ptrack[i])
|
||||
|
||||
self.clean_pb(node)
|
||||
node.stop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -1,3 +1,4 @@
|
||||
import os
|
||||
import unittest
|
||||
from sys import exit
|
||||
from testgres import get_new_node, stop_all
|
||||
@ -7,6 +8,7 @@ from helpers.ptrack_helpers import ProbackupTest, idx_ptrack
|
||||
class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SimpleTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'ptrack_vacuum_bits_visibility'
|
||||
|
||||
def teardown(self):
|
||||
# clean_all()
|
||||
@ -16,12 +18,15 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# @unittest.expectedFailure
|
||||
def test_ptrack_vacuum_bits_visibility(self):
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir='tmp_dirs/ptrack/{0}'.format(fname),
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums', '-A trust'],
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'ptrack_enable': 'on', 'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.create_tblspace_in_node(node, 'somedata')
|
||||
|
||||
# Create table and indexes
|
||||
@ -45,8 +50,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
idx_ptrack[i]['old_pages'] = self.get_md5_per_page_for_fork(
|
||||
idx_ptrack[i]['path'], idx_ptrack[i]['old_size'])
|
||||
|
||||
self.init_pb(node)
|
||||
self.backup_pb(node, backup_type='full', options=['-j100', '--stream'])
|
||||
self.backup_node(backup_dir, 'node', node, options=['-j100', '--stream'])
|
||||
|
||||
node.psql('postgres', 'vacuum t_heap')
|
||||
node.psql('postgres', 'checkpoint')
|
||||
@ -65,8 +69,6 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
# compare pages and check ptrack sanity
|
||||
self.check_ptrack_sanity(idx_ptrack[i])
|
||||
|
||||
self.clean_pb(node)
|
||||
node.stop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -1,3 +1,4 @@
|
||||
import os
|
||||
import unittest
|
||||
from sys import exit
|
||||
from testgres import get_new_node, stop_all
|
||||
@ -8,6 +9,7 @@ from helpers.ptrack_helpers import ProbackupTest, idx_ptrack
|
||||
class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SimpleTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'ptrack_vacuum_full'
|
||||
|
||||
def teardown(self):
|
||||
# clean_all()
|
||||
@ -17,12 +19,15 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# @unittest.expectedFailure
|
||||
def test_ptrack_vacuum_full(self):
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir='tmp_dirs/ptrack/{0}'.format(fname),
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums', '-A trust'],
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'ptrack_enable': 'on', 'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.create_tblspace_in_node(node, 'somedata')
|
||||
|
||||
# Create table and indexes
|
||||
@ -47,8 +52,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
idx_ptrack[i]['old_pages'] = self.get_md5_per_page_for_fork(
|
||||
idx_ptrack[i]['path'], idx_ptrack[i]['old_size'])
|
||||
|
||||
self.init_pb(node)
|
||||
self.backup_pb(node, backup_type='full', options=['-j100', '--stream'])
|
||||
self.backup_node(backup_dir, 'node', node, options=['-j100', '--stream'])
|
||||
|
||||
node.psql('postgres', 'delete from t_heap where id%2 = 1')
|
||||
node.psql('postgres', 'vacuum full t_heap')
|
||||
@ -68,8 +72,6 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
# compare pages and check ptrack sanity, the most important part
|
||||
self.check_ptrack_sanity(idx_ptrack[i])
|
||||
|
||||
self.clean_pb(node)
|
||||
node.stop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -1,3 +1,4 @@
|
||||
import os
|
||||
import unittest
|
||||
from sys import exit
|
||||
from testgres import get_new_node, stop_all
|
||||
@ -7,6 +8,7 @@ from helpers.ptrack_helpers import ProbackupTest, idx_ptrack
|
||||
class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SimpleTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'ptrack_vacuum_truncate'
|
||||
|
||||
def teardown(self):
|
||||
# clean_all()
|
||||
@ -16,12 +18,15 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
# @unittest.expectedFailure
|
||||
def test_ptrack_vacuum_truncate(self):
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir='tmp_dirs/ptrack/{0}'.format(fname),
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums', '-A trust'],
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'ptrack_enable': 'on', 'wal_level': 'replica', 'max_wal_senders': '2'})
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.create_tblspace_in_node(node, 'somedata')
|
||||
|
||||
# Create table and indexes
|
||||
@ -46,8 +51,7 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
idx_ptrack[i]['old_pages'] = self.get_md5_per_page_for_fork(
|
||||
idx_ptrack[i]['path'], idx_ptrack[i]['old_size'])
|
||||
|
||||
self.init_pb(node)
|
||||
self.backup_pb(node, backup_type='full', options=['-j100', '--stream'])
|
||||
self.backup_node(backup_dir, 'node', node, options=['-j100', '--stream'])
|
||||
|
||||
node.psql('postgres', 'delete from t_heap where id > 128;')
|
||||
node.psql('postgres', 'vacuum t_heap')
|
||||
@ -67,8 +71,6 @@ class SimpleTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
# compare pages and check ptrack sanity
|
||||
self.check_ptrack_sanity(idx_ptrack[i])
|
||||
|
||||
self.clean_pb(node)
|
||||
node.stop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -15,8 +15,6 @@ class ReplicaTest(ProbackupTest, unittest.TestCase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ReplicaTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'replica'
|
||||
self.instance_1 = 'master'
|
||||
self.instance_2 = 'slave'
|
||||
|
||||
# @classmethod
|
||||
# def tearDownClass(cls):
|
||||
@ -25,9 +23,7 @@ class ReplicaTest(ProbackupTest, unittest.TestCase):
|
||||
# @unittest.skip("skip")
|
||||
# @unittest.expectedFailure
|
||||
def test_replica_stream_full_backup(self):
|
||||
"""
|
||||
make full stream backup from replica
|
||||
"""
|
||||
"""make full stream backup from replica"""
|
||||
fname = self.id().split('.')[3]
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
master = self.make_simple_node(base_dir="{0}/{1}/master".format(self.module_name, fname),
|
||||
@ -35,37 +31,31 @@ class ReplicaTest(ProbackupTest, unittest.TestCase):
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'max_wal_senders': '2', 'checkpoint_timeout': '30s'}
|
||||
)
|
||||
|
||||
master.start()
|
||||
shutil.rmtree(backup_dir, ignore_errors=True)
|
||||
self.init_pb(backup_dir)
|
||||
instance = ''
|
||||
self.add_instance(backup_dir, self.instance_1, master)
|
||||
self.set_archiving(backup_dir, self.instance_1, master)
|
||||
master.restart()
|
||||
self.add_instance(backup_dir, 'master', master)
|
||||
|
||||
slave = self.make_simple_node(base_dir="{0}/{1}/slave".format(self.module_name, fname))
|
||||
slave_port = slave.port
|
||||
slave.cleanup()
|
||||
|
||||
# FULL BACKUP
|
||||
self.backup_node(backup_dir, self.instance_1, master, backup_type='full', options=['--stream'])
|
||||
self.backup_node(backup_dir, 'master', master, backup_type='full', options=['--stream'])
|
||||
master.psql(
|
||||
"postgres",
|
||||
"create table t_heap as select i as id, md5(i::text) as text, md5(repeat(i::text,10))::tsvector as tsvector from generate_series(0,256) i")
|
||||
|
||||
before = master.execute("postgres", "SELECT * FROM t_heap")
|
||||
|
||||
#PAGE BACKUP
|
||||
self.backup_node(backup_dir, self.instance_1, master, backup_type='page', options=['--stream'])
|
||||
self.restore_node(backup_dir, self.instance_1, slave.data_dir)
|
||||
#FULL BACKUP
|
||||
self.backup_node(backup_dir, 'master', master, options=['--stream'])
|
||||
self.restore_node(backup_dir, 'master', slave)
|
||||
|
||||
slave.append_conf('postgresql.auto.conf', 'port = {0}'.format(slave.port))
|
||||
slave.append_conf('postgresql.auto.conf', 'hot_standby = on')
|
||||
|
||||
slave.append_conf('recovery.conf', "standby_mode = 'on'")
|
||||
slave.append_conf('recovery.conf',
|
||||
"primary_conninfo = 'user=gsmol port={0} sslmode=prefer sslcompression=1'".format(master.port))
|
||||
"primary_conninfo = 'user={0} port={1} sslmode=prefer sslcompression=1'".format(self.user, master.port))
|
||||
slave.start({"-t": "600"})
|
||||
# Replica Ready
|
||||
|
||||
@ -74,34 +64,35 @@ class ReplicaTest(ProbackupTest, unittest.TestCase):
|
||||
self.assertEqual(before, after)
|
||||
|
||||
# Make backup from replica
|
||||
self.add_instance(backup_dir, self.instance_2, slave)
|
||||
time.sleep(2)
|
||||
self.add_instance(backup_dir, 'slave', slave)
|
||||
#time.sleep(2)
|
||||
self.assertTrue('INFO: Wait end of WAL streaming' and 'completed' in
|
||||
self.backup_node(backup_dir, self.instance_2, slave, backup_type='full', options=['--stream', '--log-level=verbose']))
|
||||
self.validate_pb(backup_dir, self.instance_2)
|
||||
self.assertEqual('OK', self.show_pb(backup_dir, self.instance_2)[0]['Status'])
|
||||
self.backup_node(backup_dir, 'slave', slave, options=['--stream', '--log-level=verbose',
|
||||
'--master-host=localhost', '--master-db=postgres','--master-port={0}'.format(master.port)]))
|
||||
self.validate_pb(backup_dir, 'slave')
|
||||
self.assertEqual('OK', self.show_pb(backup_dir, 'slave')[0]['Status'])
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
def test_replica_archive_full_backup(self):
|
||||
"""
|
||||
make full archive backup from replica
|
||||
"""
|
||||
"""make full archive backup from replica"""
|
||||
fname = self.id().split('.')[3]
|
||||
master = self.make_simple_node(base_dir="tmp_dirs/replica/{0}/master".format(fname),
|
||||
set_archiving=True,
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
master = self.make_simple_node(base_dir="{0}/{1}/master".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'max_wal_senders': '2'}
|
||||
pg_options={'wal_level': 'replica', 'max_wal_senders': '2', 'checkpoint_timeout': '30s'}
|
||||
)
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'master', master)
|
||||
self.set_archiving(backup_dir, 'master', master)
|
||||
# force more frequent wal switch
|
||||
master.append_conf('postgresql.auto.conf', 'archive_timeout = 10')
|
||||
master.start()
|
||||
|
||||
slave = self.make_simple_node(base_dir="tmp_dirs/replica/{0}/slave".format(fname))
|
||||
slave_port = slave.port
|
||||
slave = self.make_simple_node(base_dir="{0}/{1}/slave".format(self.module_name, fname))
|
||||
slave.cleanup()
|
||||
|
||||
self.assertEqual(self.init_pb(master), six.b(""))
|
||||
self.backup_pb(node=master, backup_type='full', options=['--stream'])
|
||||
self.backup_node(backup_dir, 'master', master)
|
||||
|
||||
master.psql(
|
||||
"postgres",
|
||||
@ -109,28 +100,30 @@ class ReplicaTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
before = master.execute("postgres", "SELECT * FROM t_heap")
|
||||
|
||||
id = self.backup_pb(master, backup_type='page', options=['--stream'])
|
||||
self.restore_pb(backup_dir=self.backup_dir(master), data_dir=slave.data_dir)
|
||||
backup_id = self.backup_node(backup_dir, 'master', master, backup_type='page')
|
||||
self.restore_node(backup_dir, 'master', slave)
|
||||
|
||||
# Settings for Replica
|
||||
slave.append_conf('postgresql.auto.conf', 'port = {0}'.format(slave.port))
|
||||
slave.append_conf('postgresql.auto.conf', 'hot_standby = on')
|
||||
# Set Archiving for replica
|
||||
self.set_archiving_conf(slave, replica=True)
|
||||
#self.set_archiving_conf( slave, replica=True)
|
||||
self.set_archiving(backup_dir, 'slave', slave, replica=True)
|
||||
|
||||
# Set Replica
|
||||
slave.append_conf('postgresql.auto.conf', 'port = {0}'.format(slave.port))
|
||||
slave.append_conf('postgresql.auto.conf', 'hot_standby = on')
|
||||
slave.append_conf('recovery.conf', "standby_mode = 'on'")
|
||||
slave.append_conf('recovery.conf',
|
||||
"primary_conninfo = 'user=gsmol port={0} sslmode=prefer sslcompression=1'".format(master.port))
|
||||
"primary_conninfo = 'user={0} port={1} sslmode=prefer sslcompression=1'".format(self.user, master.port))
|
||||
slave.start({"-t": "600"})
|
||||
# Replica Started
|
||||
|
||||
# master.execute("postgres", "checkpoint")
|
||||
|
||||
# Check replica
|
||||
after = slave.execute("postgres", "SELECT * FROM t_heap")
|
||||
self.assertEqual(before, after)
|
||||
|
||||
# Make backup from replica
|
||||
self.assertEqual(self.init_pb(slave), six.b(""))
|
||||
self.backup_pb(slave, backup_type='full', options=['--archive-timeout=30'])
|
||||
self.validate_pb(slave)
|
||||
self.add_instance(backup_dir, 'slave', slave)
|
||||
self.backup_node(backup_dir, 'slave', slave, options=['--archive-timeout=300',
|
||||
'--master-host=localhost', '--master-db=postgres','--master-port={0}'.format(master.port)])
|
||||
self.validate_pb(backup_dir, 'slave')
|
||||
|
@ -1,52 +1,57 @@
|
||||
import unittest
|
||||
import os
|
||||
from os import path
|
||||
import six
|
||||
from helpers.ptrack_helpers import ProbackupTest, ProbackupException
|
||||
from testgres import stop_all
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
import shutil
|
||||
from sys import exit
|
||||
|
||||
|
||||
class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RestoreTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'restore'
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
stop_all()
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
# @unittest.expectedFailure
|
||||
def test_restore_full_to_latest(self):
|
||||
"""recovery to latest from full backup"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
node.pgbench_init(scale=2)
|
||||
pgbench = node.pgbench(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
pgbench.wait()
|
||||
pgbench.stdout.close()
|
||||
before = node.execute("postgres", "SELECT * FROM pgbench_branches")
|
||||
self.backup_pb(node)
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
node.stop({"-m": "immediate"})
|
||||
node.cleanup()
|
||||
|
||||
# 1 - Test recovery from latest
|
||||
self.assertTrue(six.b("INFO: Restore of backup") and
|
||||
six.b("completed.") in self.restore_pb(node, options=["-j", "4"]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-j", "4"]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
# 2 - Test that recovery.conf was created
|
||||
recovery_conf = path.join(node.data_dir, "recovery.conf")
|
||||
self.assertEqual(path.isfile(recovery_conf), True)
|
||||
recovery_conf = os.path.join(node.data_dir, "recovery.conf")
|
||||
self.assertEqual(os.path.isfile(recovery_conf), True)
|
||||
|
||||
node.start({"-t": "600"})
|
||||
|
||||
@ -55,35 +60,38 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
def test_restore_full_page_to_latest(self):
|
||||
"""recovery to latest from full + page backups"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
node.pgbench_init(scale=2)
|
||||
|
||||
with open(path.join(node.logs_dir, "backup_1.log"), "wb") as backup_log:
|
||||
backup_log.write(self.backup_pb(node))
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
pgbench = node.pgbench(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
pgbench.wait()
|
||||
pgbench.stdout.close()
|
||||
|
||||
self.backup_pb(node, backup_type="page")
|
||||
backup_id = self.backup_node(backup_dir, 'node', node, backup_type="page")
|
||||
|
||||
before = node.execute("postgres", "SELECT * FROM pgbench_branches")
|
||||
|
||||
node.stop({"-m": "immediate"})
|
||||
node.cleanup()
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup") and
|
||||
six.b("completed.") in self.restore_pb(node, options=["-j", "4"]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-j", "4"]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start({"-t": "600"})
|
||||
|
||||
@ -92,29 +100,33 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
def test_restore_to_timeline(self):
|
||||
"""recovery to target timeline"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
node.pgbench_init(scale=2)
|
||||
|
||||
before = node.execute("postgres", "SELECT * FROM pgbench_branches")
|
||||
|
||||
self.backup_pb(node, backup_type="full")
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
target_tli = int(node.get_control_data()[six.b("Latest checkpoint's TimeLineID")])
|
||||
node.stop({"-m": "immediate"})
|
||||
node.cleanup()
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup") and
|
||||
six.b("completed.") in self.restore_pb(node, options=["-j", "4"]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-j", "4"]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start({"-t": "600"})
|
||||
|
||||
@ -122,14 +134,15 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
pgbench.wait()
|
||||
pgbench.stdout.close()
|
||||
|
||||
self.backup_pb(node, backup_type="full")
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="full")
|
||||
|
||||
node.stop({"-m": "immediate"})
|
||||
node.cleanup()
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup") and
|
||||
six.b("completed.") in self.restore_pb(node,
|
||||
options=["-j", "4", "--timeline=%i" % target_tli]))
|
||||
# Correct Backup must be choosen for restore
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-j", "4", "--timeline={0}".format(target_tli)]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
recovery_target_timeline = self.get_recovery_conf(node)["recovery_target_timeline"]
|
||||
self.assertEqual(int(recovery_target_timeline), target_tli)
|
||||
@ -141,22 +154,24 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
def test_restore_to_time(self):
|
||||
"""recovery to target timeline"""
|
||||
"""recovery to target time"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
node.pgbench_init(scale=2)
|
||||
|
||||
node.pgbench_init(scale=2)
|
||||
before = node.execute("postgres", "SELECT * FROM pgbench_branches")
|
||||
|
||||
backup_id = self.backup_pb(node, backup_type="full")
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
target_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
pgbench = node.pgbench(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
@ -166,8 +181,9 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
node.stop()
|
||||
node.cleanup()
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup {0} completed.".format(backup_id)) in self.restore_pb(node,
|
||||
options=["-j", "4", '--time="{0}"'.format(target_time)]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-j", "4", '--time="{0}"'.format(target_time)]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start({"-t": "600"})
|
||||
|
||||
@ -176,23 +192,26 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
def test_restore_to_xid(self):
|
||||
"""recovery to target xid"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
node.pgbench_init(scale=2)
|
||||
with node.connect("postgres") as con:
|
||||
con.execute("CREATE TABLE tbl0005 (a text)")
|
||||
con.commit()
|
||||
|
||||
self.backup_pb(node, backup_type="full")
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
pgbench = node.pgbench(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
pgbench.wait()
|
||||
@ -211,14 +230,14 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
# Enforce segment to be archived to ensure that recovery goes up to the
|
||||
# wanted point. There is no way to ensure that all segments needed have
|
||||
# been archived up to the xmin point saved earlier without that.
|
||||
node.execute("postgres", "SELECT pg_switch_xlog()")
|
||||
#node.execute("postgres", "SELECT pg_switch_xlog()")
|
||||
|
||||
node.stop({"-m": "fast"})
|
||||
node.cleanup()
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup") and
|
||||
six.b("completed.") in self.restore_pb(node,
|
||||
options=["-j", "4", '--xid=%s' % target_xid]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-j", "4", '--xid={0}'.format(target_xid)]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start({"-t": "600"})
|
||||
|
||||
@ -227,42 +246,38 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
def test_restore_full_ptrack_archive(self):
|
||||
"""recovery to latest from full + ptrack backups"""
|
||||
"""recovery to latest from archive full+ptrack backups"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
node.pgbench_init(scale=2)
|
||||
is_ptrack = node.execute("postgres", "SELECT proname FROM pg_proc WHERE proname='pg_ptrack_clear'")
|
||||
if not is_ptrack:
|
||||
node.stop()
|
||||
self.skipTest("ptrack not supported")
|
||||
return
|
||||
|
||||
node.append_conf("postgresql.conf", "ptrack_enable = on")
|
||||
node.restart()
|
||||
|
||||
self.backup_pb(node, backup_type="full")
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
pgbench = node.pgbench(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
pgbench.wait()
|
||||
pgbench.stdout.close()
|
||||
|
||||
self.backup_pb(node, backup_type="ptrack")
|
||||
backup_id = self.backup_node(backup_dir, 'node', node, backup_type="ptrack")
|
||||
|
||||
before = node.execute("postgres", "SELECT * FROM pgbench_branches")
|
||||
|
||||
node.stop({"-m": "immediate"})
|
||||
node.cleanup()
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup") and
|
||||
six.b("completed.") in self.restore_pb(node, options=["-j", "4"]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-j", "4"]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start({"-t": "600"})
|
||||
|
||||
@ -271,48 +286,44 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("skip")
|
||||
def test_restore_full_ptrack_ptrack(self):
|
||||
"""recovery to latest from full + ptrack + ptrack backups"""
|
||||
# @unittest.skip("skip")
|
||||
def test_restore_ptrack(self):
|
||||
"""recovery to latest from archive full+ptrack+ptrack backups"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
node.pgbench_init(scale=2)
|
||||
is_ptrack = node.execute("postgres", "SELECT proname FROM pg_proc WHERE proname='pg_ptrack_clear'")
|
||||
if not is_ptrack:
|
||||
node.stop()
|
||||
self.skipTest("ptrack not supported")
|
||||
return
|
||||
|
||||
node.append_conf("postgresql.conf", "ptrack_enable = on")
|
||||
node.restart()
|
||||
|
||||
self.backup_pb(node, backup_type="full")
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
pgbench = node.pgbench(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
pgbench.wait()
|
||||
pgbench.stdout.close()
|
||||
|
||||
self.backup_pb(node, backup_type="ptrack")
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="ptrack")
|
||||
|
||||
pgbench = node.pgbench(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
pgbench.wait()
|
||||
pgbench.stdout.close()
|
||||
|
||||
self.backup_pb(node, backup_type="ptrack")
|
||||
backup_id = self.backup_node(backup_dir, 'node', node, backup_type="ptrack")
|
||||
|
||||
before = node.execute("postgres", "SELECT * FROM pgbench_branches")
|
||||
|
||||
node.stop({"-m": "immediate"})
|
||||
node.cleanup()
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup") and
|
||||
six.b("completed.") in self.restore_pb(node, options=["-j", "4"]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-j", "4"]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start({"-t": "600"})
|
||||
|
||||
@ -321,38 +332,39 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
node.stop()
|
||||
|
||||
# @unittest.skip("skip")
|
||||
def test_restore_full_ptrack_stream(self):
|
||||
"""recovery in stream mode to latest from full + ptrack backups"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on', 'max_wal_senders': '2'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
node.pgbench_init(scale=2)
|
||||
is_ptrack = node.execute("postgres", "SELECT proname FROM pg_proc WHERE proname='pg_ptrack_clear'")
|
||||
if not is_ptrack:
|
||||
node.stop()
|
||||
self.skipTest("ptrack not supported")
|
||||
return
|
||||
|
||||
self.backup_pb(node, backup_type="full", options=["--stream"])
|
||||
node.pgbench_init(scale=2)
|
||||
|
||||
self.backup_node(backup_dir, 'node', node, options=["--stream"])
|
||||
|
||||
pgbench = node.pgbench(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
pgbench.wait()
|
||||
pgbench.stdout.close()
|
||||
|
||||
backup_id = self.backup_pb(node, backup_type="ptrack", options=["--stream"])
|
||||
backup_id = self.backup_node(backup_dir, 'node', node, backup_type="ptrack", options=["--stream"])
|
||||
|
||||
before = node.execute("postgres", "SELECT * FROM pgbench_branches")
|
||||
|
||||
node.stop()
|
||||
node.cleanup()
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup {0} completed.".format(backup_id)) in
|
||||
self.restore_pb(node, options=["-j", "4"]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-j", "4"]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start({"-t": "600"})
|
||||
|
||||
@ -361,28 +373,24 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
def test_restore_full_ptrack_under_load(self):
|
||||
"""recovery to latest from full + ptrack backups with loads when ptrack backup do"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on', 'max_wal_senders': '2'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
wal_segment_size = self.guc_wal_segment_size(node)
|
||||
node.pgbench_init(scale=2)
|
||||
is_ptrack = node.execute("postgres", "SELECT proname FROM pg_proc WHERE proname='pg_ptrack_clear'")
|
||||
if not is_ptrack:
|
||||
node.stop()
|
||||
self.skipTest("ptrack not supported")
|
||||
return
|
||||
node.restart()
|
||||
|
||||
self.backup_pb(node, backup_type="full")
|
||||
node.pgbench_init(scale=2)
|
||||
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
pgbench = node.pgbench(
|
||||
stdout=subprocess.PIPE,
|
||||
@ -390,7 +398,7 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
options=["-c", "4", "-T", "8"]
|
||||
)
|
||||
|
||||
self.backup_pb(node, backup_type="ptrack", options=["--stream"])
|
||||
backup_id = self.backup_node(backup_dir, 'node', node, backup_type="ptrack", options=["--stream"])
|
||||
|
||||
pgbench.wait()
|
||||
pgbench.stdout.close()
|
||||
@ -402,10 +410,9 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
node.stop({"-m": "immediate"})
|
||||
node.cleanup()
|
||||
|
||||
self.wrong_wal_clean(node, wal_segment_size)
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup") and
|
||||
six.b("completed.") in self.restore_pb(node, options=["-j", "4"]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-j", "4"]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start({"-t": "600"})
|
||||
|
||||
@ -416,27 +423,23 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
def test_restore_full_under_load_ptrack(self):
|
||||
"""recovery to latest from full + page backups with loads when full backup do"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on', 'max_wal_senders': '2'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
wal_segment_size = self.guc_wal_segment_size(node)
|
||||
node.pgbench_init(scale=2)
|
||||
is_ptrack = node.execute("postgres", "SELECT proname FROM pg_proc WHERE proname='pg_ptrack_clear'")
|
||||
if not is_ptrack:
|
||||
node.stop()
|
||||
self.skipTest("ptrack not supported")
|
||||
return
|
||||
|
||||
node.restart()
|
||||
# wal_segment_size = self.guc_wal_segment_size(node)
|
||||
node.pgbench_init(scale=2)
|
||||
|
||||
pgbench = node.pgbench(
|
||||
stdout=subprocess.PIPE,
|
||||
@ -444,12 +447,12 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
options=["-c", "4", "-T", "8"]
|
||||
)
|
||||
|
||||
self.backup_pb(node, backup_type="full")
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
pgbench.wait()
|
||||
pgbench.stdout.close()
|
||||
|
||||
self.backup_pb(node, backup_type="ptrack", options=["--stream"])
|
||||
backup_id = self.backup_node(backup_dir, 'node', node, backup_type="ptrack", options=["--stream"])
|
||||
|
||||
bbalance = node.execute("postgres", "SELECT sum(bbalance) FROM pgbench_branches")
|
||||
delta = node.execute("postgres", "SELECT sum(delta) FROM pgbench_history")
|
||||
@ -458,37 +461,39 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
node.stop({"-m": "immediate"})
|
||||
node.cleanup()
|
||||
self.wrong_wal_clean(node, wal_segment_size)
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup") and
|
||||
six.b("completed.") in self.restore_pb(node, options=["-j", "4"]))
|
||||
#self.wrong_wal_clean(node, wal_segment_size)
|
||||
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-j", "4"]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
node.start({"-t": "600"})
|
||||
|
||||
bbalance = node.execute("postgres", "SELECT sum(bbalance) FROM pgbench_branches")
|
||||
delta = node.execute("postgres", "SELECT sum(delta) FROM pgbench_history")
|
||||
|
||||
self.assertEqual(bbalance, delta)
|
||||
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
def test_restore_to_xid_inclusive(self):
|
||||
"""recovery with target inclusive false"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on'}
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on', 'max_wal_senders': '2'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
node.pgbench_init(scale=2)
|
||||
with node.connect("postgres") as con:
|
||||
con.execute("CREATE TABLE tbl0005 (a text)")
|
||||
con.commit()
|
||||
|
||||
self.backup_pb(node, backup_type="full")
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
pgbench = node.pgbench(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
pgbench.wait()
|
||||
@ -507,17 +512,15 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
# Enforce segment to be archived to ensure that recovery goes up to the
|
||||
# wanted point. There is no way to ensure that all segments needed have
|
||||
# been archived up to the xmin point saved earlier without that.
|
||||
node.execute("postgres", "SELECT pg_switch_xlog()")
|
||||
# node.execute("postgres", "SELECT pg_switch_xlog()")
|
||||
|
||||
node.stop({"-m": "fast"})
|
||||
node.cleanup()
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup") and
|
||||
six.b("completed.") in self.restore_pb(node,
|
||||
options=[
|
||||
"-j", "4",
|
||||
'--xid=%s' % target_xid,
|
||||
"--inclusive=false"]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node,
|
||||
options=["-j", "4", '--xid={0}'.format(target_xid), "--inclusive=false"]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start({"-t": "600"})
|
||||
|
||||
@ -527,20 +530,22 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
def test_restore_with_tablespace_mapping_1(self):
|
||||
"""recovery using tablespace-mapping option"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on'}
|
||||
pg_options={'wal_level': 'replica', 'ptrack_enable': 'on', 'max_wal_senders': '2'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
# Create tablespace
|
||||
tblspc_path = path.join(node.base_dir, "tblspc")
|
||||
tblspc_path = os.path.join(node.base_dir, "tblspc")
|
||||
os.makedirs(tblspc_path)
|
||||
with node.connect("postgres") as con:
|
||||
con.connection.autocommit = True
|
||||
@ -550,82 +555,88 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
con.execute("INSERT INTO test VALUES (1)")
|
||||
con.commit()
|
||||
|
||||
self.backup_pb(node)
|
||||
self.assertEqual(self.show_pb(node)[0]['Status'], six.b("OK"))
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
self.assertEqual(self.show_pb(backup_dir, 'node')[0]['Status'], six.b("OK"))
|
||||
|
||||
# 1 - Try to restore to existing directory
|
||||
node.stop()
|
||||
try:
|
||||
self.restore_pb(node)
|
||||
assertEqual(1, 0, 'Error is expected because restore destination is not empty')
|
||||
self.restore_node(backup_dir, 'node', node)
|
||||
# we should die here because exception is what we expect to happen
|
||||
self.assertEqual(1, 0, "Expecting Error because restore destionation is not empty.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(
|
||||
e.message,
|
||||
'ERROR: restore destination is not empty: "{0}"\n'.format(node.data_dir))
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: restore destination is not empty: "{0}"\n'.format(node.data_dir),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
# 2 - Try to restore to existing tablespace directory
|
||||
shutil.rmtree(node.data_dir)
|
||||
node.cleanup()
|
||||
try:
|
||||
self.restore_pb(node)
|
||||
assertEqual(1, 0, 'Error is expected because restore tablespace destination is not empty')
|
||||
self.restore_node(backup_dir, 'node', node)
|
||||
# we should die here because exception is what we expect to happen
|
||||
self.assertEqual(1, 0, "Expecting Error because restore tablespace destination is not empty.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertEqual(
|
||||
e.message,
|
||||
'ERROR: restore tablespace destination is not empty: "{0}"\n'.format(tblspc_path))
|
||||
self.assertEqual(e.message,
|
||||
'ERROR: restore tablespace destination is not empty: "{0}"\n'.format(tblspc_path),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
# 3 - Restore using tablespace-mapping
|
||||
tblspc_path_new = path.join(node.base_dir, "tblspc_new")
|
||||
self.assertTrue(six.b("INFO: Restore of backup") and
|
||||
six.b("completed.") in self.restore_pb(node,
|
||||
options=["-T", "%s=%s" % (tblspc_path, tblspc_path_new)]))
|
||||
tblspc_path_new = os.path.join(node.base_dir, "tblspc_new")
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-T", "%s=%s" % (tblspc_path, tblspc_path_new)]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start()
|
||||
id = node.execute("postgres", "SELECT id FROM test")
|
||||
self.assertEqual(id[0][0], 1)
|
||||
res = node.execute("postgres", "SELECT id FROM test")
|
||||
self.assertEqual(res[0][0], 1)
|
||||
|
||||
# 4 - Restore using tablespace-mapping using page backup
|
||||
self.backup_pb(node)
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
with node.connect("postgres") as con:
|
||||
con.execute("INSERT INTO test VALUES (2)")
|
||||
con.commit()
|
||||
self.backup_pb(node, backup_type="page")
|
||||
backup_id = self.backup_node(backup_dir, 'node', node, backup_type="page")
|
||||
|
||||
show_pb = self.show_pb(node)
|
||||
show_pb = self.show_pb(backup_dir, 'node')
|
||||
self.assertEqual(show_pb[1]['Status'], six.b("OK"))
|
||||
self.assertEqual(show_pb[2]['Status'], six.b("OK"))
|
||||
|
||||
node.stop()
|
||||
node.cleanup()
|
||||
tblspc_path_page = path.join(node.base_dir, "tblspc_page")
|
||||
tblspc_path_page = os.path.join(node.base_dir, "tblspc_page")
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup") and
|
||||
six.b("completed.") in self.restore_pb(node,
|
||||
options=["-T", "%s=%s" % (tblspc_path_new, tblspc_path_page)]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-T", "%s=%s" % (tblspc_path_new, tblspc_path_page)]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start()
|
||||
id = node.execute("postgres", "SELECT id FROM test OFFSET 1")
|
||||
self.assertEqual(id[0][0], 2)
|
||||
res = node.execute("postgres", "SELECT id FROM test OFFSET 1")
|
||||
self.assertEqual(res[0][0], 2)
|
||||
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
def test_restore_with_tablespace_mapping_2(self):
|
||||
"""recovery using tablespace-mapping option and page backup"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
# Full backup
|
||||
self.backup_pb(node)
|
||||
self.assertEqual(self.show_pb(node)[0]['Status'], six.b("OK"))
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
self.assertEqual(self.show_pb(backup_dir, 'node')[0]['Status'], six.b("OK"))
|
||||
|
||||
# Create tablespace
|
||||
tblspc_path = path.join(node.base_dir, "tblspc")
|
||||
tblspc_path = os.path.join(node.base_dir, "tblspc")
|
||||
os.makedirs(tblspc_path)
|
||||
with node.connect("postgres") as con:
|
||||
con.connection.autocommit = True
|
||||
@ -635,9 +646,9 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
con.commit()
|
||||
|
||||
# First page backup
|
||||
self.backup_pb(node, backup_type="page")
|
||||
self.assertEqual(self.show_pb(node)[1]['Status'], six.b("OK"))
|
||||
self.assertEqual(self.show_pb(node)[1]['Mode'], six.b("PAGE"))
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="page")
|
||||
self.assertEqual(self.show_pb(backup_dir, 'node')[1]['Status'], six.b("OK"))
|
||||
self.assertEqual(self.show_pb(backup_dir, 'node')[1]['Mode'], six.b("PAGE"))
|
||||
|
||||
# Create tablespace table
|
||||
with node.connect("postgres") as con:
|
||||
@ -649,18 +660,18 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
con.commit()
|
||||
|
||||
# Second page backup
|
||||
self.backup_pb(node, backup_type="page")
|
||||
self.assertEqual(self.show_pb(node)[2]['Status'], six.b("OK"))
|
||||
self.assertEqual(self.show_pb(node)[2]['Mode'], six.b("PAGE"))
|
||||
backup_id = self.backup_node(backup_dir, 'node', node, backup_type="page")
|
||||
self.assertEqual(self.show_pb(backup_dir, 'node')[2]['Status'], six.b("OK"))
|
||||
self.assertEqual(self.show_pb(backup_dir, 'node')[2]['Mode'], six.b("PAGE"))
|
||||
|
||||
node.stop()
|
||||
node.cleanup()
|
||||
|
||||
tblspc_path_new = path.join(node.base_dir, "tblspc_new")
|
||||
tblspc_path_new = os.path.join(node.base_dir, "tblspc_new")
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup") and
|
||||
six.b("completed.") in self.restore_pb(node,
|
||||
options=["-T", "%s=%s" % (tblspc_path, tblspc_path_new)]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-T", "%s=%s" % (tblspc_path, tblspc_path_new)]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
node.start()
|
||||
|
||||
count = node.execute("postgres", "SELECT count(*) FROM tbl")
|
||||
@ -669,30 +680,31 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
self.assertEqual(count[0][0], 4)
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
def test_archive_node_backup_stream_restore_to_recovery_time(self):
|
||||
"""make node with archiving, make stream backup, make PITR to Recovery Time
|
||||
"""
|
||||
"""make node with archiving, make stream backup, make PITR to Recovery Time"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/pgpro668/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'max_wal_senders': '2'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
backup_id = self.backup_pb(node, backup_type='full', options=["--stream"])
|
||||
backup_id = self.backup_node(backup_dir, 'node', node, options=["--stream"])
|
||||
node.psql("postgres", "create table t_heap(a int)")
|
||||
node.psql("postgres", "select pg_switch_xlog()")
|
||||
node.stop()
|
||||
node.cleanup()
|
||||
|
||||
recovery_time = self.show_pb(node, id=backup_id)['recovery-time']
|
||||
recovery_time = self.show_pb(backup_dir, 'node', backup_id=backup_id)['recovery-time']
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup {0} completed.".format(backup_id)) in
|
||||
self.restore_pb(node, options=["-j", "4", '--time="{0}"'.format(recovery_time)]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node, options=["-j", "4", '--time="{0}"'.format(recovery_time)]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start({"-t": "600"})
|
||||
|
||||
@ -701,29 +713,31 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
self.assertEqual(True, node.status())
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("skip")
|
||||
# @unittest.skip("skip")
|
||||
def test_archive_node_backup_stream_pitr(self):
|
||||
"""make node with archiving, make stream backup, create table t_heap, make pitr to Recovery Time, check that t_heap do not exists"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
set_replication=True,
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'max_wal_senders': '2'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
backup_id = self.backup_pb(node, backup_type='full', options=["--stream"])
|
||||
backup_id = self.backup_node(backup_dir, 'node', node, options=["--stream"])
|
||||
node.psql("postgres", "create table t_heap(a int)")
|
||||
node.psql("postgres", "select pg_switch_xlog()")
|
||||
node.stop()
|
||||
node.cleanup()
|
||||
|
||||
recovery_time = self.show_pb(node, id=backup_id)['recovery-time']
|
||||
recovery_time = self.show_pb(backup_dir, 'node', backup_id=backup_id)['recovery-time']
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup {0} completed.".format(backup_id)) in
|
||||
self.restore_pb(node, options=["-j", "4", '--time="{0}"'.format(recovery_time)]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node,
|
||||
options=["-j", "4", '--time="{0}"'.format(recovery_time)]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start({"-t": "600"})
|
||||
|
||||
@ -731,33 +745,34 @@ class RestoreTest(ProbackupTest, unittest.TestCase):
|
||||
self.assertEqual(True, 'does not exist' in res[2])
|
||||
node.stop()
|
||||
|
||||
@unittest.skip("fucking illegal")
|
||||
def test_archive_node_backup_stream_pitr_2(self):
|
||||
"""make node with archiving, make stream backup, create table t_heap, make pitr to Recovery Time, check that t_heap do not exists"""
|
||||
# @unittest.skip("skip")
|
||||
def test_archive_node_backup_archive_pitr_2(self):
|
||||
"""make node with archiving, make archive backup, create table t_heap, make pitr to Recovery Time, check that t_heap do not exists"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/restore/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
set_replication=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica', 'max_wal_senders': '2'}
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
# exit(1)
|
||||
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
backup_id = self.backup_pb(node, backup_type='full', options=["--stream"])
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
node.psql("postgres", "create table t_heap(a int)")
|
||||
node.psql("postgres", "select pg_switch_xlog()")
|
||||
node.pg_ctl('stop', {'-m': 'immediate', '-D': '{0}'.format(node.data_dir)})
|
||||
node.cleanup()
|
||||
|
||||
recovery_time = self.show_pb(node, id=backup_id)['recovery-time']
|
||||
recovery_time = self.show_pb(backup_dir, 'node', backup_id)['recovery-time']
|
||||
|
||||
self.assertTrue(six.b("INFO: Restore of backup {0} completed.".format(backup_id)) in self.restore_pb(node,
|
||||
options=["-j", "4", '--time="{0}"'.format(recovery_time)]))
|
||||
self.assertIn(six.b("INFO: Restore of backup {0} completed.".format(backup_id)),
|
||||
self.restore_node(backup_dir, 'node', node,
|
||||
options=["-j", "4", '--time="{0}"'.format(recovery_time)]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
node.start({"-t": "600"})
|
||||
|
||||
res = node.psql("postgres", 'select * from t_heap')
|
||||
self.assertEqual(True, 'does not exist' in res[2])
|
||||
# node.stop()
|
||||
node.stop()
|
||||
|
@ -10,6 +10,7 @@ class RetentionTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RetentionTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'retention'
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
@ -20,30 +21,31 @@ class RetentionTest(ProbackupTest, unittest.TestCase):
|
||||
def test_retention_redundancy_1(self):
|
||||
"""purge backups using redundancy-based retention policy"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/retention/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.init_pb(node)
|
||||
with open(path.join(self.backup_dir(node), "pg_probackup.conf"), "a") as conf:
|
||||
with open(os.path.join(backup_dir, 'backups', 'node', "pg_probackup.conf"), "a") as conf:
|
||||
conf.write("retention-redundancy = 1\n")
|
||||
|
||||
# Make backups to be purged
|
||||
self.backup_pb(node)
|
||||
self.backup_pb(node, backup_type="page")
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="page")
|
||||
# Make backups to be keeped
|
||||
self.backup_pb(node)
|
||||
self.backup_pb(node, backup_type="page")
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="page")
|
||||
|
||||
self.assertEqual(len(self.show_pb(node)), 4)
|
||||
self.assertEqual(len(self.show_pb(backup_dir, 'node')), 4)
|
||||
|
||||
# Purge backups
|
||||
log = self.delete_expired(node)
|
||||
self.assertEqual(len(self.show_pb(node)), 2)
|
||||
log = self.delete_expired(backup_dir, 'node')
|
||||
self.assertEqual(len(self.show_pb(backup_dir, 'node')), 2)
|
||||
|
||||
# Check that WAL segments were deleted
|
||||
min_wal = None
|
||||
@ -53,7 +55,7 @@ class RetentionTest(ProbackupTest, unittest.TestCase):
|
||||
min_wal = line[31:-1]
|
||||
elif line.startswith(b"INFO: removed max WAL segment"):
|
||||
max_wal = line[31:-1]
|
||||
for wal_name in listdir(path.join(self.backup_dir(node), "wal")):
|
||||
for wal_name in listdir(os.path.join(backup_dir, 'wal', 'node')):
|
||||
if not wal_name.endswith(".backup"):
|
||||
wal_name_b = wal_name.encode('ascii')
|
||||
self.assertEqual(wal_name_b[8:] > min_wal[8:], True)
|
||||
@ -65,40 +67,43 @@ class RetentionTest(ProbackupTest, unittest.TestCase):
|
||||
def test_retention_window_2(self):
|
||||
"""purge backups using window-based retention policy"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/retention/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
|
||||
self.init_pb(node)
|
||||
with open(path.join(self.backup_dir(node), "pg_probackup.conf"), "a") as conf:
|
||||
with open(os.path.join(backup_dir, 'backups', 'node', "pg_probackup.conf"), "a") as conf:
|
||||
conf.write("retention-redundancy = 1\n")
|
||||
conf.write("retention-window = 1\n")
|
||||
|
||||
# Make backups to be purged
|
||||
self.backup_pb(node)
|
||||
self.backup_pb(node, backup_type="page")
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="page")
|
||||
# Make backup to be keeped
|
||||
self.backup_pb(node)
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
backups = path.join(self.backup_dir(node), "backups")
|
||||
backups = path.join(backup_dir, 'backups', 'node')
|
||||
days_delta = 5
|
||||
for backup in listdir(backups):
|
||||
if backup == 'pg_probackup.conf':
|
||||
continue
|
||||
with open(path.join(backups, backup, "backup.control"), "a") as conf:
|
||||
conf.write("recovery_time='{:%Y-%m-%d %H:%M:%S}'\n".format(
|
||||
datetime.now() - timedelta(days=days_delta)))
|
||||
days_delta -= 1
|
||||
|
||||
# Make backup to be keeped
|
||||
self.backup_pb(node, backup_type="page")
|
||||
self.backup_node(backup_dir, 'node', node, backup_type="page")
|
||||
|
||||
self.assertEqual(len(self.show_pb(node)), 4)
|
||||
self.assertEqual(len(self.show_pb(backup_dir, 'node')), 4)
|
||||
|
||||
# Purge backups
|
||||
self.delete_expired(node)
|
||||
self.assertEqual(len(self.show_pb(node)), 2)
|
||||
self.delete_expired(backup_dir, 'node')
|
||||
self.assertEqual(len(self.show_pb(backup_dir, 'node')), 2)
|
||||
|
||||
node.stop()
|
||||
|
@ -10,6 +10,7 @@ class OptionTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(OptionTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'show'
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
@ -17,39 +18,48 @@ class OptionTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
# @unittest.skip("skip")
|
||||
# @unittest.expectedFailure
|
||||
def show_test_1(self):
|
||||
def test_show_1(self):
|
||||
"""Status DONE and OK"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/show/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
self.assertEqual(
|
||||
self.backup_pb(node, options=["--quiet"]),
|
||||
self.backup_node(backup_dir, 'node', node, options=["--log-level=panic"]),
|
||||
None
|
||||
)
|
||||
self.assertIn(six.b("OK"), self.show_pb(node, as_text=True))
|
||||
self.assertIn(six.b("OK"), self.show_pb(backup_dir, 'node', as_text=True))
|
||||
node.stop()
|
||||
|
||||
# @unittest.skip("skip")
|
||||
def test_corrupt_2(self):
|
||||
"""Status CORRUPT"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/show/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
id_backup = self.backup_pb(node)
|
||||
|
||||
path.join(self.backup_dir(node), "backups", id_backup.decode("utf-8"), "database", "postgresql.conf")
|
||||
os.remove(path.join(self.backup_dir(node), "backups", id_backup.decode("utf-8"), "database", "postgresql.conf"))
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
self.validate_pb(node, id_backup)
|
||||
self.assertIn(six.b("CORRUPT"), self.show_pb(node, as_text=True))
|
||||
# delete file which belong to backup
|
||||
file = path.join(backup_dir, "backups", "node", backup_id.decode("utf-8"), "database", "postgresql.conf")
|
||||
os.remove(file)
|
||||
|
||||
self.validate_pb(backup_dir, 'node', backup_id)
|
||||
self.assertIn(six.b("CORRUPT"), self.show_pb(backup_dir, as_text=True))
|
||||
node.stop()
|
||||
|
@ -13,6 +13,7 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ValidateTest, self).__init__(*args, **kwargs)
|
||||
self.module_name = 'validate'
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
@ -23,20 +24,22 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
||||
def test_validate_wal_unreal_values(self):
|
||||
"""make node with archiving, make archive backup, validate to both real and unreal values"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/validate/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
node.pgbench_init(scale=2)
|
||||
with node.connect("postgres") as con:
|
||||
con.execute("CREATE TABLE tbl0005 (a text)")
|
||||
con.commit()
|
||||
|
||||
backup_id = self.backup_pb(node)
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
node.pgbench_init(scale=2)
|
||||
pgbench = node.pgbench(
|
||||
@ -48,17 +51,18 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
||||
pgbench.wait()
|
||||
pgbench.stdout.close()
|
||||
|
||||
target_time = self.show_pb(node, id=backup_id)['recovery-time']
|
||||
target_time = self.show_pb(backup_dir, 'node', backup_id)['recovery-time']
|
||||
after_backup_time = datetime.now().replace(second=0, microsecond=0)
|
||||
|
||||
# Validate to real time
|
||||
self.assertIn(six.b("INFO: backup validation completed successfully on"),
|
||||
self.validate_pb(node, options=["--time='{0}'".format(target_time)]))
|
||||
self.assertIn(six.b("INFO: backup validation completed successfully"),
|
||||
self.validate_pb(backup_dir, 'node', options=["--time='{0}'".format(target_time)]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
# Validate to unreal time
|
||||
unreal_time_1 = after_backup_time - timedelta(days=2)
|
||||
try:
|
||||
self.validate_pb(node, options=["--time='{0}'".format(unreal_time_1)])
|
||||
self.validate_pb(backup_dir, 'node', options=["--time='{0}'".format(unreal_time_1)])
|
||||
self.assertEqual(1, 0, "Expecting Error because of validation to unreal time.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
@ -68,7 +72,7 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
||||
# Validate to unreal time #2
|
||||
unreal_time_2 = after_backup_time + timedelta(days=2)
|
||||
try:
|
||||
self.validate_pb(node, options=["--time='{0}'".format(unreal_time_2)])
|
||||
self.validate_pb(backup_dir, 'node', options=["--time='{0}'".format(unreal_time_2)])
|
||||
self.assertEqual(1, 0, "Expecting Error because of validation to unreal time.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
@ -83,13 +87,14 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
||||
target_xid = res[0][0]
|
||||
node.execute("postgres", "SELECT pg_switch_xlog()")
|
||||
|
||||
self.assertIn(six.b("INFO: backup validation completed successfully on"),
|
||||
self.validate_pb(node, options=["--xid={0}".format(target_xid)]))
|
||||
self.assertIn(six.b("INFO: backup validation completed successfully"),
|
||||
self.validate_pb(backup_dir, 'node', options=["--xid={0}".format(target_xid)]),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
# Validate to unreal xid
|
||||
unreal_xid = int(target_xid) + 1000
|
||||
try:
|
||||
self.validate_pb(node, options=["--xid={0}".format(unreal_xid)])
|
||||
self.validate_pb(backup_dir, 'node', options=["--xid={0}".format(unreal_xid)])
|
||||
self.assertEqual(1, 0, "Expecting Error because of validation to unreal xid.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
@ -97,35 +102,32 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
# Validate with backup ID
|
||||
self.assertIn(six.b("INFO: backup validation completed successfully on"),
|
||||
self.validate_pb(node, backup_id))
|
||||
self.assertIn(six.b("INFO: backup validation completed successfully"),
|
||||
self.validate_pb(backup_dir, 'node', backup_id),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(self.output), self.cmd))
|
||||
|
||||
# @unittest.skip("skip")
|
||||
def test_validate_corrupt_wal_1(self):
|
||||
"""
|
||||
make node with archiving
|
||||
make archive backup
|
||||
corrupt all wal files
|
||||
run validate, expecting error because of wal corruption
|
||||
make sure that backup status is 'CORRUPT'
|
||||
"""
|
||||
"""make archive node, make archive backup, corrupt all wal files, run validate, expect errors"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/validate/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
with node.connect("postgres") as con:
|
||||
con.execute("CREATE TABLE tbl0005 (a text)")
|
||||
con.commit()
|
||||
|
||||
backup_id = self.backup_pb(node)
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
# Corrupt WAL
|
||||
wals_dir = os.path.join(self.backup_dir(node), "wal")
|
||||
wals_dir = os.path.join(backup_dir, 'wal', 'node')
|
||||
wals = [f for f in os.listdir(wals_dir) if os.path.isfile(os.path.join(wals_dir, f)) and not f.endswith('.backup')]
|
||||
wals.sort()
|
||||
for wal in wals:
|
||||
@ -136,48 +138,43 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
# Simple validate
|
||||
try:
|
||||
self.validate_pb(node)
|
||||
self.validate_pb(backup_dir, 'node')
|
||||
self.assertEqual(1, 0, "Expecting Error because of wal segments corruption.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertTrue('Possible WAL CORRUPTION' in e.message),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd)
|
||||
|
||||
self.assertEqual('CORRUPT', self.show_pb(node, id=backup_id)['status'], 'Backup STATUS should be "CORRUPT"')
|
||||
self.assertEqual('CORRUPT', self.show_pb(backup_dir, 'node', backup_id)['status'], 'Backup STATUS should be "CORRUPT"')
|
||||
node.stop()
|
||||
|
||||
# @unittest.skip("skip")
|
||||
def test_validate_corrupt_wal_2(self):
|
||||
"""
|
||||
make node with archiving
|
||||
make archive backup
|
||||
corrupt all wal files
|
||||
run validate to real xid, expecting error because of wal corruption
|
||||
make sure that backup status is 'CORRUPT'
|
||||
"""
|
||||
"""make archive node, make full backup, corrupt all wal files, run validate to real xid, expect errors"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/validate/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
with node.connect("postgres") as con:
|
||||
con.execute("CREATE TABLE tbl0005 (a text)")
|
||||
con.commit()
|
||||
|
||||
backup_id = self.backup_pb(node)
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
target_xid = None
|
||||
with node.connect("postgres") as con:
|
||||
res = con.execute("INSERT INTO tbl0005 VALUES ('inserted') RETURNING (xmin)")
|
||||
con.commit()
|
||||
target_xid = res[0][0]
|
||||
node.execute("postgres", "SELECT pg_switch_xlog()")
|
||||
|
||||
# Corrupt WAL
|
||||
wals_dir = os.path.join(self.backup_dir(node), "wal")
|
||||
wals_dir = os.path.join(backup_dir, 'wal', 'node')
|
||||
wals = [f for f in os.listdir(wals_dir) if os.path.isfile(os.path.join(wals_dir, f)) and not f.endswith('.backup')]
|
||||
wals.sort()
|
||||
for wal in wals:
|
||||
@ -188,34 +185,34 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
||||
|
||||
# Validate to xid
|
||||
try:
|
||||
self.validate_pb(node, backup_id, options=['--xid={0}'.format(target_xid)])
|
||||
self.validate_pb(backup_dir, 'node', backup_id, options=['--xid={0}'.format(target_xid)])
|
||||
self.assertEqual(1, 0, "Expecting Error because of wal segments corruption.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertTrue('Possible WAL CORRUPTION' in e.message),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd)
|
||||
|
||||
self.assertEqual('CORRUPT', self.show_pb(node, id=backup_id)['status'], 'Backup STATUS should be "CORRUPT"')
|
||||
self.assertEqual('CORRUPT', self.show_pb(backup_dir, 'node', backup_id)['status'], 'Backup STATUS should be "CORRUPT"')
|
||||
node.stop()
|
||||
|
||||
# @unittest.skip("skip")
|
||||
def test_validate_wal_lost_segment_1(self):
|
||||
"""
|
||||
make node with archiving
|
||||
make archive backup
|
||||
"""make archive node, make archive full backup,
|
||||
delete from archive wal segment which belong to previous backup
|
||||
run validate, expecting error because of missing wal segment
|
||||
make sure that backup status is 'CORRUPT'
|
||||
"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/validate/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
|
||||
node.pgbench_init(scale=2)
|
||||
pgbench = node.pgbench(
|
||||
stdout=subprocess.PIPE,
|
||||
@ -224,31 +221,30 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
||||
)
|
||||
pgbench.wait()
|
||||
pgbench.stdout.close()
|
||||
backup_id = self.backup_pb(node, backup_type='full')
|
||||
backup_id = self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
# Delete wal segment
|
||||
wals_dir = os.path.join(self.backup_dir(node), "wal")
|
||||
wals_dir = os.path.join(backup_dir, 'wal', 'node')
|
||||
wals = [f for f in os.listdir(wals_dir) if os.path.isfile(os.path.join(wals_dir, f)) and not f.endswith('.backup')]
|
||||
file = os.path.join(self.backup_dir(node), "wal", wals[1])
|
||||
file = os.path.join(backup_dir, 'wal', 'node', wals[1])
|
||||
os.remove(file)
|
||||
try:
|
||||
self.validate_pb(node)
|
||||
self.validate_pb(backup_dir, 'node')
|
||||
self.assertEqual(1, 0, "Expecting Error because of wal segment disappearance.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertTrue(re.match('WARNING: WAL segment "{0}" is absent\nERROR: there are not enough WAL records to restore from [0-9a-fA-F\/]+ to [0-9a-fA-F\/]+\n\Z'.format(
|
||||
file), e.message),
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
self.assertIn('WARNING: WAL segment "{0}" is absent\nERROR: there are not enough WAL records to restore'.format(
|
||||
file), e.message, '\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
self.assertEqual('CORRUPT', self.show_pb(node, id=backup_id)['status'], 'Backup {0} should have STATUS "CORRUPT"')
|
||||
self.assertEqual('CORRUPT', self.show_pb(backup_dir, 'node', backup_id)['status'], 'Backup {0} should have STATUS "CORRUPT"')
|
||||
|
||||
# Be paranoid and run validate again
|
||||
try:
|
||||
self.validate_pb(node)
|
||||
self.validate_pb(backup_dir, 'node')
|
||||
self.assertEqual(1, 0, "Expecting Error because of backup corruption.\n Output: {0} \n CMD: {1}".format(
|
||||
repr(self.output), self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertTrue(re.match('ERROR: Backup {0} has status: CORRUPT\n\Z'.format(backup_id), e.message),
|
||||
self.assertIn('INFO: Backup {0} has status CORRUPT. Skip validation.\n'.format(backup_id), e.message,
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
node.stop()
|
||||
|
||||
@ -262,15 +258,17 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
||||
make sure that backup status is 'ERROR'
|
||||
"""
|
||||
fname = self.id().split('.')[3]
|
||||
node = self.make_simple_node(base_dir="tmp_dirs/validate/{0}".format(fname),
|
||||
set_archiving=True,
|
||||
node = self.make_simple_node(base_dir="{0}/{1}/node".format(self.module_name, fname),
|
||||
initdb_params=['--data-checksums'],
|
||||
pg_options={'wal_level': 'replica'}
|
||||
)
|
||||
|
||||
backup_dir = os.path.join(self.tmp_path, self.module_name, fname, 'backup')
|
||||
self.init_pb(backup_dir)
|
||||
self.add_instance(backup_dir, 'node', node)
|
||||
self.set_archiving(backup_dir, 'node', node)
|
||||
node.start()
|
||||
self.assertEqual(self.init_pb(node), six.b(""))
|
||||
self.backup_pb(node, backup_type='full')
|
||||
|
||||
self.backup_node(backup_dir, 'node', node)
|
||||
|
||||
# make some wals
|
||||
node.pgbench_init(scale=2)
|
||||
@ -283,20 +281,22 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
||||
pgbench.stdout.close()
|
||||
|
||||
# delete last wal segment
|
||||
wals_dir = os.path.join(self.backup_dir(node), "wal")
|
||||
wals_dir = os.path.join(backup_dir, 'wal', 'node')
|
||||
wals = [f for f in os.listdir(wals_dir) if os.path.isfile(os.path.join(wals_dir, f)) and not f.endswith('.backup')]
|
||||
wals = map(int, wals)
|
||||
file = os.path.join(self.backup_dir(node), "wal", '0000000' + str(max(wals)))
|
||||
file = os.path.join(wals_dir, '0000000' + str(max(wals)))
|
||||
os.remove(file)
|
||||
|
||||
try:
|
||||
backup_id = self.backup_pb(node, backup_type='page')
|
||||
backup_id = self.backup_node(backup_dir, 'node', node, backup_type='page')
|
||||
self.assertEqual(1, 0, "Expecting Error because of wal segment disappearance.\n Output: {0} \n CMD: {1}".format(
|
||||
self.output, self.cmd))
|
||||
except ProbackupException, e:
|
||||
self.assertTrue(re.match('INFO: wait for LSN [0-9a-fA-F\/]+ in archived WAL segment .*\nWARNING: could not read WAL record at [0-9a-fA-F\/]+\nERROR: WAL segment "{0}" is absent\n\Z'.format(
|
||||
file), e.message),
|
||||
self.assertTrue('INFO: wait for LSN'
|
||||
and 'in archived WAL segment'
|
||||
and 'WARNING: could not read WAL record at'
|
||||
and 'ERROR: WAL segment "{0}" is absent\n'.format(file) in e.message,
|
||||
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(repr(e.message), self.cmd))
|
||||
|
||||
self.assertEqual('ERROR', self.show_pb(node)[1]['Status'], 'Backup {0} should have STATUS "ERROR"')
|
||||
self.assertEqual('ERROR', self.show_pb(backup_dir, 'node')[1]['Status'], 'Backup {0} should have STATUS "ERROR"')
|
||||
node.stop()
|
||||
|
Loading…
x
Reference in New Issue
Block a user