This is an automated email from the ASF dual-hosted git repository.

leborchuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git


The following commit(s) were added to refs/heads/main by this push:
     new c49e871b02c Fix recovery slot handling before pg_basebackup (#1675)
c49e871b02c is described below

commit c49e871b02ce8e566455573ae7b074094a079773
Author: Aviral Garg <[email protected]>
AuthorDate: Thu May 21 16:27:41 2026 +0530

    Fix recovery slot handling before pg_basebackup (#1675)
    
    This PR fixes the recovery flow when the internal WAL replication slot does 
not already exist on the source segment.
    
    Before this change, both gpsegrecovery and gpconfigurenewsegment would 
start pg_basebackup first and only retry with slot creation after the backup 
failed. In practice, that meant a full base backup could run for a long time 
and then fail at the end because the slot was missing.
    
    This change fixes that at the root:
    
    adds a shared helper to check whether the replication slot already exists
    creates the slot up front when needed, before pg_basebackup starts
    removes the fallback second pg_basebackup attempt from both recovery paths
    updates unit tests to cover the new behavior and the new failure mode
    
    ---------
    
    Co-authored-by: Leonid <[email protected]>
---
 gpMgmt/bin/gppylib/commands/pg.py                  | 28 ++++++-
 .../commands/test/unit/test_unit_pg_base_backup.py | 55 ++++++++++++++
 .../gppylib/test/unit/test_unit_gpsegrecovery.py   | 88 +++++++++++-----------
 gpMgmt/bin/lib/gpconfigurenewsegment               | 31 ++------
 gpMgmt/sbin/gpsegrecovery.py                       | 27 ++-----
 5 files changed, 137 insertions(+), 92 deletions(-)

diff --git a/gpMgmt/bin/gppylib/commands/pg.py 
b/gpMgmt/bin/gppylib/commands/pg.py
index a2af133c28f..f430b294500 100644
--- a/gpMgmt/bin/gppylib/commands/pg.py
+++ b/gpMgmt/bin/gppylib/commands/pg.py
@@ -1,13 +1,15 @@
 #!/usr/bin/env python3
 #
-# Copyright (c) Greenplum Inc 2008. All Rights Reserved. 
+# Copyright (c) Greenplum Inc 2008. All Rights Reserved.
 #
 
+from contextlib import closing
 import os
 import pipes
 
 from gppylib.gplog import *
 from gppylib.gparray import *
+from gppylib.db import dbconn
 from .base import *
 from .unix import *
 from gppylib.commands.base import *
@@ -17,6 +19,30 @@ logger = get_default_logger()
 
 GPHOME=os.environ.get('GPHOME')
 
+
+def ensure_replication_slot_exists(source_host, source_port,
+                                   replication_slot_name):
+    if not replication_slot_name:
+        return False
+
+    escaped_slot_name = replication_slot_name.replace("'", "''")
+    dburl = dbconn.DbURL(hostname=source_host, port=source_port,
+                         dbname='template1')
+    with closing(dbconn.connect(dburl, utility=True)) as conn:
+        slot_exists = dbconn.querySingleton(
+            conn,
+            "SELECT count(*) FROM pg_catalog.pg_replication_slots "
+            "WHERE slot_name = '{}'".format(escaped_slot_name))
+        if slot_exists > 0:
+            return False
+
+        dbconn.execSQL(
+            conn,
+            "SELECT pg_catalog.pg_create_physical_replication_slot('{}')"
+            .format(escaped_slot_name))
+
+    return True
+
 class DbStatus(Command):
     def __init__(self,name,db,ctxt=LOCAL,remoteHost=None):
         self.db=db        
diff --git a/gpMgmt/bin/gppylib/commands/test/unit/test_unit_pg_base_backup.py 
b/gpMgmt/bin/gppylib/commands/test/unit/test_unit_pg_base_backup.py
index 117f62b41ea..66621c39d5c 100644
--- a/gpMgmt/bin/gppylib/commands/test/unit/test_unit_pg_base_backup.py
+++ b/gpMgmt/bin/gppylib/commands/test/unit/test_unit_pg_base_backup.py
@@ -1,4 +1,5 @@
 import unittest
+from unittest.mock import Mock, patch
 from gppylib.commands import pg
 
 
@@ -44,6 +45,60 @@ class TestUnitPgBaseBackup(unittest.TestCase):
         self.assertNotIn("-x", base_backup.command_tokens)
         self.assertNotIn("--xlog", base_backup.command_tokens)
 
+    @patch('gppylib.commands.pg.dbconn.querySingleton', return_value=1)
+    @patch('gppylib.commands.pg.dbconn.connect')
+    @patch('gppylib.commands.pg.dbconn.DbURL')
+    def 
test_ensure_replication_slot_exists_returns_false_when_slot_exists(self, 
mock_dburl,
+                                                                           
mock_connect,
+                                                                           
mock_query_singleton):
+        mock_conn = Mock()
+        mock_connect.return_value = mock_conn
+
+        created = pg.ensure_replication_slot_exists('source-host', 5432, 
'slot_name')
+
+        self.assertFalse(created)
+        mock_dburl.assert_called_once_with(hostname='source-host', port=5432, 
dbname='template1')
+        mock_connect.assert_called_once_with(mock_dburl.return_value, 
utility=True)
+        self.assertEqual(1, mock_query_singleton.call_count)
+        self.assertIn("FROM pg_catalog.pg_replication_slots", 
mock_query_singleton.call_args[0][1])
+        mock_conn.close.assert_called_once_with()
+
+    @patch('gppylib.commands.pg.dbconn.execSQL')
+    @patch('gppylib.commands.pg.dbconn.querySingleton', return_value=0)
+    @patch('gppylib.commands.pg.dbconn.connect')
+    @patch('gppylib.commands.pg.dbconn.DbURL')
+    def test_ensure_replication_slot_exists_creates_missing_slot(self, 
mock_dburl,
+                                                                 mock_connect,
+                                                                 
mock_query_singleton,
+                                                                 
mock_exec_sql):
+        mock_conn = Mock()
+        mock_connect.return_value = mock_conn
+
+        created = pg.ensure_replication_slot_exists('source-host', 5432, 
'slot_name')
+
+        self.assertTrue(created)
+        mock_dburl.assert_called_once_with(hostname='source-host', port=5432, 
dbname='template1')
+        mock_connect.assert_called_once_with(mock_dburl.return_value, 
utility=True)
+        self.assertEqual(1, mock_query_singleton.call_count)
+        self.assertIn("FROM pg_catalog.pg_replication_slots", 
mock_query_singleton.call_args[0][1])
+        mock_exec_sql.assert_called_once()
+        self.assertIn("pg_create_physical_replication_slot('slot_name')",
+                      mock_exec_sql.call_args[0][1])
+        mock_conn.close.assert_called_once_with()
+
+    @patch('gppylib.commands.pg.dbconn.querySingleton')
+    @patch('gppylib.commands.pg.dbconn.connect')
+    @patch('gppylib.commands.pg.dbconn.DbURL')
+    def test_ensure_replication_slot_exists_skips_empty_slot_name(self, 
mock_dburl,
+                                                                  mock_connect,
+                                                                  
mock_query_singleton):
+        created = pg.ensure_replication_slot_exists('source-host', 5432, None)
+
+        self.assertFalse(created)
+        mock_dburl.assert_not_called()
+        mock_connect.assert_not_called()
+        mock_query_singleton.assert_not_called()
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/gpMgmt/bin/gppylib/test/unit/test_unit_gpsegrecovery.py 
b/gpMgmt/bin/gppylib/test/unit/test_unit_gpsegrecovery.py
index c806dbaed90..b525801b07a 100644
--- a/gpMgmt/bin/gppylib/test/unit/test_unit_gpsegrecovery.py
+++ b/gpMgmt/bin/gppylib/test/unit/test_unit_gpsegrecovery.py
@@ -106,10 +106,12 @@ class FullRecoveryTestCase(GpTestCase):
         self.maxDiff = None
         self.mock_logger = Mock(spec=['log', 'info', 'debug', 'error', 'warn', 
'exception'])
         self.apply_patches([
+            patch('gpsegrecovery.ensure_replication_slot_exists'),
             patch('gpsegrecovery.start_segment', return_value=Mock()),
             patch('gpsegrecovery.PgBaseBackup.__init__', return_value=None),
             patch('gpsegrecovery.PgBaseBackup.run')
         ])
+        self.mock_ensure_slot = 
self.get_mock_from_apply_patch('ensure_replication_slot_exists')
         self.mock_pgbasebackup_run = self.get_mock_from_apply_patch('run')
         self.mock_pgbasebackup_init = 
self.get_mock_from_apply_patch('__init__')
 
@@ -130,6 +132,7 @@ class FullRecoveryTestCase(GpTestCase):
         super(FullRecoveryTestCase, self).tearDown()
 
     def _assert_basebackup_runs(self, expected_init_args):
+        self.mock_ensure_slot.assert_called_once_with('sdw1', 40000, 
'internal_wal_replication_slot')
         self.assertEqual(1, self.mock_pgbasebackup_init.call_count)
         self.assertEqual(expected_init_args, 
self.mock_pgbasebackup_init.call_args)
         self.assertEqual(1, self.mock_pgbasebackup_run.call_count)
@@ -172,49 +175,37 @@ class FullRecoveryTestCase(GpTestCase):
         self._assert_basebackup_runs(expected_init_args1)
         self._assert_cmd_passed()
 
-    def test_basebackup_run_one_exception(self):
-        self.mock_pgbasebackup_run.side_effect = [Exception('backup failed 
once'), Mock()]
+    def test_basebackup_slot_check_exception(self):
+        self.mock_ensure_slot.side_effect = [Exception('slot check failed')]
 
         self.full_recovery_cmd.run()
 
-        expected_init_args1 = call("/data/mirror0", "sdw1", '40000', 
create_slot=False,
-                                   
replication_slot_name='internal_wal_replication_slot',
-                                   forceoverwrite=True, target_gp_dbid=2, 
progress_file='/tmp/test_progress_file')
-        expected_init_args2 = call("/data/mirror0", "sdw1", '40000', 
create_slot=True,
-                                   
replication_slot_name='internal_wal_replication_slot',
-                                   forceoverwrite=True, target_gp_dbid=2, 
progress_file='/tmp/test_progress_file')
-        self.assertEqual(2, self.mock_pgbasebackup_init.call_count)
-        self.assertEqual([expected_init_args1, expected_init_args2] , 
self.mock_pgbasebackup_init.call_args_list)
-        self.assertEqual(2, self.mock_pgbasebackup_run.call_count)
-        self.assertEqual([call(validateAfter=True),call(validateAfter=True)], 
self.mock_pgbasebackup_run.call_args_list)
-        
gpsegrecovery.start_segment.assert_called_once_with(self.seg_recovery_info, 
self.mock_logger, self.era)
-        self._assert_cmd_passed()
+        self.assertEqual(0, self.mock_pgbasebackup_init.call_count)
+        self.assertEqual(0, self.mock_pgbasebackup_run.call_count)
+        self.assertEqual(0, gpsegrecovery.start_segment.call_count)
+        self._assert_cmd_failed('{"error_type": "full", "error_msg": "slot 
check failed", "dbid": 2, '
+                                '"datadir": "/data/mirror0", "port": 50000, '
+                                '"progress_file": "/tmp/test_progress_file"}')
 
-    def test_basebackup_run_two_exceptions(self):
-        self.mock_pgbasebackup_run.side_effect=[Exception('backup failed 
once'),
-                                                Exception('backup failed 
twice')]
+    def test_basebackup_run_exception(self):
+        self.mock_pgbasebackup_run.side_effect=[Exception('backup failed 
once')]
 
         self.full_recovery_cmd.run()
 
         expected_init_args1 = call("/data/mirror0", "sdw1", '40000', 
create_slot=False,
                                    
replication_slot_name='internal_wal_replication_slot',
                                    forceoverwrite=True, target_gp_dbid=2, 
progress_file='/tmp/test_progress_file')
-        expected_init_args2 = call("/data/mirror0", "sdw1", '40000', 
create_slot=True,
-                                   
replication_slot_name='internal_wal_replication_slot',
-                                   forceoverwrite=True, target_gp_dbid=2, 
progress_file='/tmp/test_progress_file')
-        self.assertEqual(2, self.mock_pgbasebackup_init.call_count)
-        self.assertEqual([expected_init_args1, expected_init_args2], 
self.mock_pgbasebackup_init.call_args_list)
-        self.assertEqual(2, self.mock_pgbasebackup_run.call_count)
-        self.assertEqual([call(validateAfter=True),call(validateAfter=True)], 
self.mock_pgbasebackup_run.call_args_list)
-        self.mock_logger.info.any_call('Running pg_basebackup failed: backup 
failed once')
-        self.mock_logger.info.assert_called_with("Re-running pg_basebackup, 
creating the slot this time")
+        self.mock_ensure_slot.assert_called_once_with('sdw1', 40000, 
'internal_wal_replication_slot')
+        self.assertEqual(1, self.mock_pgbasebackup_init.call_count)
+        self.assertEqual([expected_init_args1], 
self.mock_pgbasebackup_init.call_args_list)
+        self.assertEqual(1, self.mock_pgbasebackup_run.call_count)
+        self.assertEqual([call(validateAfter=True)], 
self.mock_pgbasebackup_run.call_args_list)
         self.assertEqual(0, gpsegrecovery.start_segment.call_count)
-        self._assert_cmd_failed('{"error_type": "full", "error_msg": "backup 
failed twice", "dbid": 2, ' \
+        self._assert_cmd_failed('{"error_type": "full", "error_msg": "backup 
failed once", "dbid": 2, ' \
                                 '"datadir": "/data/mirror0", "port": 50000, 
"progress_file": "/tmp/test_progress_file"}')
 
-    def test_basebackup_run_no_forceoverwrite_two_exceptions(self):
-        self.mock_pgbasebackup_run.side_effect = [Exception('backup failed 
once'),
-                                                  Exception('backup failed 
twice')]
+    def test_basebackup_run_no_forceoverwrite_exception(self):
+        self.mock_pgbasebackup_run.side_effect = [Exception('backup failed 
once')]
         self.full_recovery_cmd.forceoverwrite = False
 
         self.full_recovery_cmd.run()
@@ -222,16 +213,13 @@ class FullRecoveryTestCase(GpTestCase):
         expected_init_args1 = call("/data/mirror0", "sdw1", '40000', 
create_slot=False,
                                    
replication_slot_name='internal_wal_replication_slot',
                                    forceoverwrite=False, target_gp_dbid=2, 
progress_file='/tmp/test_progress_file')
-        # regardless of the passed in value, second call to pg_basebackup will 
always have forceoverwrite=True
-        expected_init_args2 = call("/data/mirror0", "sdw1", '40000', 
create_slot=True,
-                                   
replication_slot_name='internal_wal_replication_slot',
-                                   forceoverwrite=True, target_gp_dbid=2, 
progress_file='/tmp/test_progress_file')
-        self.assertEqual(2, self.mock_pgbasebackup_init.call_count)
-        self.assertEqual([expected_init_args1, expected_init_args2], 
self.mock_pgbasebackup_init.call_args_list)
-        self.assertEqual(2, self.mock_pgbasebackup_run.call_count)
-        self.assertEqual([call(validateAfter=True),call(validateAfter=True)], 
self.mock_pgbasebackup_run.call_args_list)
+        self.mock_ensure_slot.assert_called_once_with('sdw1', 40000, 
'internal_wal_replication_slot')
+        self.assertEqual(1, self.mock_pgbasebackup_init.call_count)
+        self.assertEqual([expected_init_args1], 
self.mock_pgbasebackup_init.call_args_list)
+        self.assertEqual(1, self.mock_pgbasebackup_run.call_count)
+        self.assertEqual([call(validateAfter=True)], 
self.mock_pgbasebackup_run.call_args_list)
         self.assertEqual(0, gpsegrecovery.start_segment.call_count)
-        self._assert_cmd_failed('{"error_type": "full", "error_msg": "backup 
failed twice", "dbid": 2, ' \
+        self._assert_cmd_failed('{"error_type": "full", "error_msg": "backup 
failed once", "dbid": 2, ' \
                                 '"datadir": "/data/mirror0", "port": 50000, 
"progress_file": "/tmp/test_progress_file"}')
 
     def test_basebackup_init_exception(self):
@@ -287,7 +275,10 @@ class SegRecoveryTestCase(GpTestCase):
     @patch('gppylib.commands.pg.PgRewind.run')
     @patch('gpsegrecovery.PgBaseBackup.__init__', return_value=None)
     @patch('gpsegrecovery.PgBaseBackup.run')
-    def test_complete_workflow(self, mock_pgbasebackup_run, 
mock_pgbasebackup_init, mock_pgrewind_run, mock_pgrewind_init):
+    @patch('gpsegrecovery.ensure_replication_slot_exists')
+    def test_complete_workflow(self, mock_ensure_slot, mock_pgbasebackup_run,
+                               mock_pgbasebackup_init, mock_pgrewind_run,
+                               mock_pgrewind_init):
         mix_confinfo = gppylib.recoveryinfo.serialize_list([
             self.full_r1, self.incr_r2])
         sys.argv = ['gpsegrecovery', '-l', '/tmp/logdir', '--era', 
'{}'.format(self.era), '-c {}'.format(mix_confinfo)]
@@ -301,17 +292,21 @@ class SegRecoveryTestCase(GpTestCase):
         self.assertEqual(1, mock_pgrewind_init.call_count)
         self.assertEqual(1, mock_pgbasebackup_run.call_count)
         self.assertEqual(1, mock_pgbasebackup_init.call_count)
+        mock_ensure_slot.assert_called_once_with('source_hostname1', 6001, 
'internal_wal_replication_slot')
         self.assertRegex(gplog.get_logfile(), '/gpsegrecovery.py_\d+\.log')
 
     @patch('gppylib.commands.pg.PgRewind.__init__', return_value=None)
     @patch('gppylib.commands.pg.PgRewind.run')
     @patch('gpsegrecovery.PgBaseBackup.__init__', return_value=None)
     @patch('gpsegrecovery.PgBaseBackup.run')
-    def test_complete_workflow_exception(self, mock_pgbasebackup_run, 
mock_pgbasebackup_init, mock_pgrewind_run,
+    @patch('gpsegrecovery.ensure_replication_slot_exists')
+    def test_complete_workflow_exception(self, mock_ensure_slot,
+                                         mock_pgbasebackup_run,
+                                         mock_pgbasebackup_init,
+                                         mock_pgrewind_run,
                                          mock_pgrewind_init):
         mock_pgrewind_run.side_effect = [Exception('pg_rewind failed')]
-        mock_pgbasebackup_run.side_effect = [Exception('pg_basebackup failed 
once'),
-                                             Exception('pg_basebackup failed 
twice')]
+        mock_pgbasebackup_run.side_effect = [Exception('pg_basebackup failed 
once')]
         mix_confinfo = gppylib.recoveryinfo.serialize_list([
             self.full_r1, self.incr_r2])
         sys.argv = ['gpsegrecovery', '-l', '/tmp/logdir', 
'--era={}'.format(self.era), '-c {}'.format(mix_confinfo)]
@@ -322,14 +317,15 @@ class SegRecoveryTestCase(GpTestCase):
 
         self.assertCountEqual('[{"error_type": "incremental", "error_msg": 
"pg_rewind failed", "dbid": 4, "datadir": "target_data_dir4", '
                               '"port": 5004, "progress_file": 
"/tmp/progress_file4"} , '
-                              '{"error_type": "full", "error_msg": 
"pg_basebackup failed twice", "dbid": 1,'
+                              '{"error_type": "full", "error_msg": 
"pg_basebackup failed once", "dbid": 1,'
                               '"datadir": "target_data_dir1", "port": 5001, 
"progress_file": "/tmp/progress_file1"}]',
                               buf.getvalue().strip())
         self.assertEqual(1, ex.exception.code)
         self.assertEqual(1, mock_pgrewind_run.call_count)
         self.assertEqual(1, mock_pgrewind_init.call_count)
-        self.assertEqual(2, mock_pgbasebackup_run.call_count)
-        self.assertEqual(2, mock_pgbasebackup_init.call_count)
+        self.assertEqual(1, mock_pgbasebackup_run.call_count)
+        self.assertEqual(1, mock_pgbasebackup_init.call_count)
+        mock_ensure_slot.assert_called_once_with('source_hostname1', 6001, 
'internal_wal_replication_slot')
         self.assertRegex(gplog.get_logfile(), '/gpsegrecovery.py_\d+\.log')
 
     @patch('recovery_base.gplog.setup_tool_logging')
diff --git a/gpMgmt/bin/lib/gpconfigurenewsegment 
b/gpMgmt/bin/lib/gpconfigurenewsegment
index c37c70bf1fa..4f71348b9a8 100755
--- a/gpMgmt/bin/lib/gpconfigurenewsegment
+++ b/gpMgmt/bin/lib/gpconfigurenewsegment
@@ -10,7 +10,7 @@ from optparse import Option, OptionGroup, OptionParser, 
OptionValueError, SUPPRE
 
 from gppylib.gpparseopts import OptParser, OptChecker
 from gppylib.commands.gp import ModifyConfSetting, SegmentStart, SegmentStop
-from gppylib.commands.pg import PgBaseBackup
+from gppylib.commands.pg import PgBaseBackup, ensure_replication_slot_exists
 from gppylib.db import dbconn
 from gppylib.commands import unix
 from gppylib.commands.pg import DbStatus
@@ -134,6 +134,10 @@ class ConfExpSegCmd(Command):
                         self.progressFile = '%s/pg_basebackup.%s.dbid%s.out' % 
(gplog.get_logger_dir(),
                                                                                
 datetime.datetime.today().strftime('%Y%m%d_%H%M%S'),
                                                                                
 self.dbid)
+                    ensure_replication_slot_exists(
+                        self.syncWithSegmentHostname,
+                        self.syncWithSegmentPort,
+                        self.replicationSlotName)
                     # Create a mirror based on the primary
                     cmd = PgBaseBackup(target_datadir=self.datadir,
                                        
source_host=self.syncWithSegmentHostname,
@@ -149,30 +153,9 @@ class ConfExpSegCmd(Command):
                         self.set_results(CommandResult(0, b'', b'', True, 
False))
                         if shouldDeleteProgressFile:
                             os.remove(self.progressFile)
-
                     except Exception as e:
-                        #  If the cluster never has mirrors, cmd will fail
-                        #  quickly because the internal slot doesn't exist.
-                        #  Re-run with `create_slot`.
-                        #  GPDB_12_MERGE_FIXME could we check it before? or let
-                        #  pg_basebackup create slot if not exists.
-                        cmd = PgBaseBackup(target_datadir=self.datadir,
-                                           
source_host=self.syncWithSegmentHostname,
-                                           
source_port=str(self.syncWithSegmentPort),
-                                           create_slot = True,
-                                           
replication_slot_name=self.replicationSlotName,
-                                           forceoverwrite=True,
-                                           target_gp_dbid=self.dbid,
-                                           logfile=self.progressFile)
-                        try:
-                            logger.info("Re-running pg_basebackup, creating 
the slot this time")
-                            cmd.run(validateAfter=True)
-                            self.set_results(CommandResult(0, b'', b'', True, 
False))
-                            if shouldDeleteProgressFile:
-                                os.remove(self.progressFile)
-                        except Exception as e:
-                            self.set_results(CommandResult(1, b'', 
str(e).encode(), True, False))
-                            raise
+                        self.set_results(CommandResult(1, b'', 
str(e).encode(), True, False))
+                        raise
 
                     logger.info("Successfully ran pg_basebackup: %s" % 
cmd.cmdStr)
                     return
diff --git a/gpMgmt/sbin/gpsegrecovery.py b/gpMgmt/sbin/gpsegrecovery.py
index 811a73ccbb5..51c72581e47 100644
--- a/gpMgmt/sbin/gpsegrecovery.py
+++ b/gpMgmt/sbin/gpsegrecovery.py
@@ -4,7 +4,8 @@ import os
 import signal
 
 from gppylib.recoveryinfo import RecoveryErrorType
-from gppylib.commands.pg import PgBaseBackup, PgRewind
+from gppylib.commands.pg import (PgBaseBackup, PgRewind,
+                                 ensure_replication_slot_exists)
 from recovery_base import RecoveryBase, set_recovery_cmd_results
 from gppylib.commands.base import Command
 from gppylib.commands.gp import SegmentStart
@@ -30,6 +31,9 @@ class FullRecovery(Command):
     @set_recovery_cmd_results
     def run(self):
         self.error_type = RecoveryErrorType.BASEBACKUP_ERROR
+        ensure_replication_slot_exists(self.recovery_info.source_hostname,
+                                       self.recovery_info.source_port,
+                                       self.replicationSlotName)
         cmd = PgBaseBackup(self.recovery_info.target_datadir,
                            self.recovery_info.source_hostname,
                            str(self.recovery_info.source_port),
@@ -39,26 +43,7 @@ class FullRecovery(Command):
                            
target_gp_dbid=self.recovery_info.target_segment_dbid,
                            progress_file=self.recovery_info.progress_file)
         self.logger.info("Running pg_basebackup with progress output 
temporarily in %s" % self.recovery_info.progress_file)
-        try:
-            cmd.run(validateAfter=True)
-        except Exception as e: #TODO should this be ExecutionError?
-            self.logger.info("Running pg_basebackup failed: {}".format(str(e)))
-
-            #  If the cluster never has mirrors, cmd will fail
-            #  quickly because the internal slot doesn't exist.
-            #  Re-run with `create_slot`.
-            #  GPDB_12_MERGE_FIXME could we check it before? or let
-            #  pg_basebackup create slot if not exists.
-            cmd = PgBaseBackup(self.recovery_info.target_datadir,
-                               self.recovery_info.source_hostname,
-                               str(self.recovery_info.source_port),
-                               create_slot=True,
-                               replication_slot_name=self.replicationSlotName,
-                               forceoverwrite=True,
-                               
target_gp_dbid=self.recovery_info.target_segment_dbid,
-                               progress_file=self.recovery_info.progress_file)
-            self.logger.info("Re-running pg_basebackup, creating the slot this 
time")
-            cmd.run(validateAfter=True)
+        cmd.run(validateAfter=True)
 
         self.error_type = RecoveryErrorType.DEFAULT_ERROR
         self.logger.info("Successfully ran pg_basebackup for dbid: {}".format(


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to