Call a checkpoint on master before pg_rewind.

PostgreSQL does not run a checkpoint during promition.
Since pg_rewind relies on the last checkpoint to get the timeline,
there is a short race condition right after the promotion, when
it can get the timeline wrong and fail. We work around this by
calling the checkpoint manually.

Make sure our test configuration does both archive and recovery.
This commit is contained in:
Oleksii Kliukin
2015-12-09 13:17:36 +01:00
parent 735fe0b345
commit c5285bc293
+6 -4
View File
@@ -342,13 +342,13 @@ class Postgresql:
ret and not block_callbacks and self.call_nowait(ACTION_ON_START)
return ret
def checkpoint(self):
def checkpoint(self, connstring=None):
try:
r = parseurl('postgres://{}/postgres'.format(self.local_address))
r['options'] = '-c statement_timeout=0'
with psycopg2.connect(**r) as conn:
connstring = connstring or 'postgres://{}/postgres'.format(self.local_address)
with psycopg2.connect(connstring) as conn:
conn.autocommit = True
with conn.cursor() as cur:
cur.execute("SET statement_timeout = 0")
cur.execute('CHECKPOINT')
except:
logging.exception('Exception during CHECKPOINT')
@@ -454,6 +454,8 @@ recovery_target_timeline = 'latest'
r['user'] = r['username']
env = self.write_pgpass(r)
pc = "user={user} host={host} port={port} dbname=postgres sslmode=prefer sslcompression=1".format(**r)
# first run a checkpoint on a promoted master in order to make it store the new timeline ([email protected])
self.checkpoint(pc)
logger.info("running pg_rewind from {}".format(pc))
pg_rewind = ['pg_rewind', '-D', self.data_dir, '--source-server', pc]
try: