@@ -1962,7 +1962,9 @@ def test_incremental_partial_restore_exclude_checksum(self):
19621962 node2 , options = [
19631963 "--db-exclude=db1" ,
19641964 "--db-exclude=db5" ,
1965- "-I" , "checksum" ])
1965+ "-I" , "checksum" ,
1966+ "--destroy-all-other-dbs" ,
1967+ ])
19661968
19671969 pgdata2 = self .pgdata_content (node2 .data_dir )
19681970
@@ -2068,7 +2070,9 @@ def test_incremental_partial_restore_exclude_lsn(self):
20682070 node2 , options = [
20692071 "--db-exclude=db1" ,
20702072 "--db-exclude=db5" ,
2071- "-I" , "lsn" ])
2073+ "-I" , "lsn" ,
2074+ "--destroy-all-other-dbs" ,
2075+ ])
20722076
20732077 pgdata2 = self .pgdata_content (node2 .data_dir )
20742078
@@ -2188,7 +2192,8 @@ def test_incremental_partial_restore_exclude_tablespace_checksum(self):
21882192 "--db-exclude=db1" ,
21892193 "--db-exclude=db5" ,
21902194 "-T" , "{0}={1}" .format (
2191- node_tablespace , node2_tablespace )])
2195+ node_tablespace , node2_tablespace ),
2196+ "--destroy-all-other-dbs" ])
21922197 # we should die here because exception is what we expect to happen
21932198 self .assertEqual (
21942199 1 , 0 ,
@@ -2209,7 +2214,9 @@ def test_incremental_partial_restore_exclude_tablespace_checksum(self):
22092214 "--db-exclude=db1" ,
22102215 "--db-exclude=db5" ,
22112216 "-T" , "{0}={1}" .format (
2212- node_tablespace , node2_tablespace )])
2217+ node_tablespace , node2_tablespace ),
2218+ "--destroy-all-other-dbs" ,
2219+ ])
22132220
22142221 pgdata2 = self .pgdata_content (node2 .data_dir )
22152222
@@ -2241,6 +2248,127 @@ def test_incremental_partial_restore_exclude_tablespace_checksum(self):
22412248
22422249 self .assertNotIn ('PANIC' , output )
22432250
2251+ def test_incremental_partial_restore_deny (self ):
2252+ """
2253+ Do now allow partial incremental restore into non-empty PGDATA
2254+ becase we can't limit WAL replay to a single database.
2255+ """
2256+ backup_dir = os .path .join (self .tmp_path , self .module_name , self .fname , 'backup' )
2257+ node = self .make_simple_node (
2258+ base_dir = os .path .join (self .module_name , self .fname , 'node' ),
2259+ initdb_params = ['--data-checksums' ])
2260+
2261+ self .init_pb (backup_dir )
2262+ self .add_instance (backup_dir , 'node' , node )
2263+ self .set_archiving (backup_dir , 'node' , node )
2264+ node .slow_start ()
2265+
2266+ for i in range (1 , 3 ):
2267+ node .safe_psql ('postgres' , f'CREATE database db{ i } ' )
2268+
2269+ # FULL backup
2270+ backup_id = self .backup_node (backup_dir , 'node' , node )
2271+ pgdata = self .pgdata_content (node .data_dir )
2272+
2273+ try :
2274+ self .restore_node (backup_dir , 'node' , node , options = ["--db-include=db1" , '-I' , 'LSN' ])
2275+ self .fail ("incremental partial restore is not allowed" )
2276+ except ProbackupException as e :
2277+ self .assertIn ("Incremental restore is not allowed: Postmaster is running." , e .message )
2278+
2279+ node .safe_psql ('db2' , 'create table x (id int)' )
2280+ node .safe_psql ('db2' , 'insert into x values (42)' )
2281+
2282+ node .stop ()
2283+
2284+ try :
2285+ self .restore_node (backup_dir , 'node' , node , options = ["--db-include=db1" , '-I' , 'LSN' ])
2286+ self .fail ("because incremental partial restore is not allowed" )
2287+ except ProbackupException as e :
2288+ self .assertIn ("Incremental restore is not allowed: Partial incremental restore into non-empty PGDATA is forbidden" , e .message )
2289+
2290+ node .slow_start ()
2291+ value = node .execute ('db2' , 'select * from x' )[0 ][0 ]
2292+ self .assertEqual (42 , value )
2293+
2294+ def test_deny_incremental_partial_restore_exclude_tablespace_checksum (self ):
2295+ """
2296+ Do now allow partial incremental restore into non-empty PGDATA
2297+ becase we can't limit WAL replay to a single database.
2298+ (case of tablespaces)
2299+ """
2300+ backup_dir = os .path .join (self .tmp_path , self .module_name , self .fname , 'backup' )
2301+ node = self .make_simple_node (
2302+ base_dir = os .path .join (self .module_name , self .fname , 'node' ),
2303+ initdb_params = ['--data-checksums' ])
2304+
2305+ self .init_pb (backup_dir )
2306+ self .add_instance (backup_dir , 'node' , node )
2307+ self .set_archiving (backup_dir , 'node' , node )
2308+ node .slow_start ()
2309+
2310+ self .create_tblspace_in_node (node , 'somedata' )
2311+
2312+ node_tablespace = self .get_tblspace_path (node , 'somedata' )
2313+
2314+ tbl_oid = node .safe_psql (
2315+ 'postgres' ,
2316+ "SELECT oid "
2317+ "FROM pg_tablespace "
2318+ "WHERE spcname = 'somedata'" ).rstrip ()
2319+
2320+ for i in range (1 , 10 , 1 ):
2321+ node .safe_psql (
2322+ 'postgres' ,
2323+ 'CREATE database db{0} tablespace somedata' .format (i ))
2324+
2325+ db_list_raw = node .safe_psql (
2326+ 'postgres' ,
2327+ 'SELECT to_json(a) '
2328+ 'FROM (SELECT oid, datname FROM pg_database) a' ).rstrip ()
2329+
2330+ db_list_splitted = db_list_raw .splitlines ()
2331+
2332+ db_list = {}
2333+ for line in db_list_splitted :
2334+ line = json .loads (line )
2335+ db_list [line ['datname' ]] = line ['oid' ]
2336+
2337+ # FULL backup
2338+ backup_id = self .backup_node (backup_dir , 'node' , node )
2339+
2340+ # node2
2341+ node2 = self .make_simple_node ('node2' )
2342+ node2 .cleanup ()
2343+ node2_tablespace = self .get_tblspace_path (node2 , 'somedata' )
2344+
2345+ # in node2 restore full backup
2346+ self .restore_node (
2347+ backup_dir , 'node' ,
2348+ node2 , options = [
2349+ "-T" , f"{ node_tablespace } ={ node2_tablespace } " ])
2350+
2351+ # partial incremental restore into node2
2352+ try :
2353+ self .restore_node (backup_dir , 'node' , node2 ,
2354+ options = ["-I" , "checksum" ,
2355+ "--db-exclude=db1" ,
2356+ "--db-exclude=db5" ,
2357+ "-T" , f"{ node_tablespace } ={ node2_tablespace } " ])
2358+ self .fail ("remapped tablespace contain old data" )
2359+ except ProbackupException as e :
2360+ pass
2361+
2362+ try :
2363+ self .restore_node (backup_dir , 'node' , node2 ,
2364+ options = [
2365+ "-I" , "checksum" , "--force" ,
2366+ "--db-exclude=db1" , "--db-exclude=db5" ,
2367+ "-T" , f"{ node_tablespace } ={ node2_tablespace } " ])
2368+ self .fail ("incremental partial restore is not allowed" )
2369+ except ProbackupException as e :
2370+ self .assertIn ("Incremental restore is not allowed: Partial incremental restore into non-empty PGDATA is forbidden" , e .message )
2371+
22442372 def test_incremental_pg_filenode_map (self ):
22452373 """
22462374 https://github.com/postgrespro/pg_probackup/issues/320
0 commit comments