@@ -457,6 +457,8 @@ do_backup_instance(void)
457
457
/* Initialize size summary */
458
458
current .data_bytes = 0 ;
459
459
460
+ current .tablespace_map_exists = false;
461
+
460
462
/* Obtain current timeline */
461
463
if (is_remote_backup )
462
464
{
@@ -520,24 +522,6 @@ do_backup_instance(void)
520
522
strncat (label , " with pg_probackup" , lengthof (label ));
521
523
pg_start_backup (label , smooth_checkpoint , & current );
522
524
523
- /*
524
- * If backup_label does not exist in $PGDATA, stop taking backup.
525
- * NOTE. We can check it only on master, though.
526
- */
527
- if (exclusive_backup )
528
- {
529
- char label_path [MAXPGPATH ];
530
- join_path_components (label_path , pgdata , PG_BACKUP_LABEL_FILE );
531
-
532
- /* Leave if no backup file */
533
- if (!fileExists (label_path ))
534
- {
535
- elog (LOG , "%s does not exist, stopping backup" , PG_BACKUP_LABEL_FILE );
536
- pg_stop_backup (NULL );
537
- elog (ERROR , "%s does not exist in PGDATA" , PG_BACKUP_LABEL_FILE );
538
- }
539
- }
540
-
541
525
pgBackupGetPath (& current , database_path , lengthof (database_path ),
542
526
DATABASE_DIR );
543
527
@@ -1541,13 +1525,20 @@ wait_replica_wal_lsn(XLogRecPtr lsn, bool is_start_backup)
1541
1525
static void
1542
1526
pg_stop_backup (pgBackup * backup )
1543
1527
{
1544
- PGconn * conn ;
1545
- PGresult * res ;
1528
+ PGconn * conn ;
1529
+ PGresult * res ;
1530
+ PGresult * tablespace_map_content = NULL ;
1546
1531
uint32 xlogid ;
1547
1532
uint32 xrecoff ;
1548
1533
XLogRecPtr restore_lsn = InvalidXLogRecPtr ;
1549
- bool sent = false;
1550
- int pg_stop_backup_timeout = 0 ;
1534
+ bool sent = false;
1535
+ int pg_stop_backup_timeout = 0 ;
1536
+ char path [MAXPGPATH ];
1537
+ char backup_label [MAXPGPATH ];
1538
+ FILE * fp ;
1539
+ pgFile * file ;
1540
+ size_t len ;
1541
+ char * val = NULL ;
1551
1542
1552
1543
/*
1553
1544
* We will use this values if there are no transactions between start_lsn
@@ -1601,23 +1592,39 @@ pg_stop_backup(pgBackup *backup)
1601
1592
if (!pg_stop_backup_is_sent )
1602
1593
{
1603
1594
if (!exclusive_backup )
1595
+ {
1604
1596
/*
1605
1597
* Stop the non-exclusive backup. Besides stop_lsn it returns from
1606
1598
* pg_stop_backup(false) copy of the backup label and tablespace map
1607
1599
* so they can be written to disk by the caller.
1608
1600
*/
1609
1601
sent = pgut_send (conn ,
1610
- "SELECT *, txid_snapshot_xmax(txid_current_snapshot()),"
1611
- " current_timestamp(0)::timestamptz"
1612
- " FROM pg_stop_backup(false)" ,
1613
- 0 , NULL , WARNING );
1602
+ "SELECT"
1603
+ " labelfile,"
1604
+ " txid_snapshot_xmax(txid_current_snapshot()),"
1605
+ " current_timestamp(0)::timestamptz,"
1606
+ " lsn,"
1607
+ " spcmapfile"
1608
+ " FROM pg_stop_backup(false)" ,
1609
+ 0 , NULL , WARNING );
1610
+ }
1614
1611
else
1612
+ {
1613
+ if (current .tablespace_map_exists )
1614
+ {
1615
+ /* We cannot execute pg_read_file after pg_stop_backup */
1616
+ tablespace_map_content = pgut_execute (conn ,
1617
+ "SELECT pg_read_file('tablespace_map')" ,
1618
+ 0 , NULL );
1619
+ }
1615
1620
sent = pgut_send (conn ,
1616
- "SELECT *, txid_snapshot_xmax(txid_current_snapshot()),"
1617
- " current_timestamp(0)::timestamptz"
1618
- " FROM pg_stop_backup()" ,
1619
- 0 , NULL , WARNING );
1620
-
1621
+ "SELECT"
1622
+ " pg_read_file('backup_label') as labelfile,"
1623
+ " txid_snapshot_xmax(txid_current_snapshot()),"
1624
+ " current_timestamp(0)::timestamptz,"
1625
+ " pg_stop_backup() as lsn" ,
1626
+ 0 , NULL , WARNING );
1627
+ }
1621
1628
pg_stop_backup_is_sent = true;
1622
1629
if (!sent )
1623
1630
elog (ERROR , "Failed to send pg_stop_backup query" );
@@ -1673,7 +1680,7 @@ pg_stop_backup(pgBackup *backup)
1673
1680
if (pg_stop_backup_is_sent && !in_cleanup )
1674
1681
{
1675
1682
/* Extract timeline and LSN from results of pg_stop_backup() */
1676
- XLogDataFromLSN (PQgetvalue (res , 0 , 0 ), & xlogid , & xrecoff );
1683
+ XLogDataFromLSN (PQgetvalue (res , 0 , 3 ), & xlogid , & xrecoff );
1677
1684
/* Calculate LSN */
1678
1685
stop_backup_lsn = (XLogRecPtr ) ((uint64 ) xlogid << 32 ) | xrecoff ;
1679
1686
@@ -1686,96 +1693,89 @@ pg_stop_backup(pgBackup *backup)
1686
1693
elog (ERROR , "Invalid stop_backup_lsn value %X/%X" ,
1687
1694
(uint32 ) (stop_backup_lsn >> 32 ), (uint32 ) (stop_backup_lsn ));
1688
1695
1689
- /* Write backup_label and tablespace_map for backup from replica */
1690
- if (!exclusive_backup )
1696
+ /* Write backup_label and tablespace_map */
1697
+ Assert (PQnfields (res ) >= 4 );
1698
+ pgBackupGetPath (& current , path , lengthof (path ), DATABASE_DIR );
1699
+
1700
+ /* Write backup_label */
1701
+ join_path_components (backup_label , path , PG_BACKUP_LABEL_FILE );
1702
+ fp = fopen (backup_label , "w" );
1703
+ if (fp == NULL )
1704
+ elog (ERROR , "can't open backup label file \"%s\": %s" ,
1705
+ backup_label , strerror (errno ));
1706
+
1707
+ len = strlen (PQgetvalue (res , 0 , 0 ));
1708
+ if (fwrite (PQgetvalue (res , 0 , 0 ), 1 , len , fp ) != len ||
1709
+ fflush (fp ) != 0 ||
1710
+ fsync (fileno (fp )) != 0 ||
1711
+ fclose (fp ))
1712
+ elog (ERROR , "can't write backup label file \"%s\": %s" ,
1713
+ backup_label , strerror (errno ));
1714
+
1715
+ /*
1716
+ * It's vital to check if backup_files_list is initialized,
1717
+ * because we could get here because the backup was interrupted
1718
+ */
1719
+ if (backup_files_list )
1691
1720
{
1692
- char path [MAXPGPATH ];
1693
- char backup_label [MAXPGPATH ];
1694
- FILE * fp ;
1695
- pgFile * file ;
1696
- size_t len ;
1721
+ file = pgFileNew (backup_label , true);
1722
+ calc_file_checksum (file );
1723
+ free (file -> path );
1724
+ file -> path = strdup (PG_BACKUP_LABEL_FILE );
1725
+ parray_append (backup_files_list , file );
1726
+ }
1697
1727
1698
- Assert (PQnfields (res ) >= 5 );
1728
+ if (sscanf (PQgetvalue (res , 0 , 1 ), XID_FMT , & recovery_xid ) != 1 )
1729
+ elog (ERROR ,
1730
+ "result of txid_snapshot_xmax() is invalid: %s" ,
1731
+ PQerrorMessage (conn ));
1732
+ if (!parse_time (PQgetvalue (res , 0 , 2 ), & recovery_time ))
1733
+ elog (ERROR ,
1734
+ "result of current_timestamp is invalid: %s" ,
1735
+ PQerrorMessage (conn ));
1736
+
1737
+ /* Get content for tablespace_map from pg_read_file('tablespace_map') in case of exclusive
1738
+ * or from stop_backup results in case of non-exclusive backup
1739
+ */
1740
+ if (exclusive_backup )
1741
+ {
1742
+ if (current .tablespace_map_exists )
1743
+ {
1744
+ val = PQgetvalue (tablespace_map_content , 0 , 0 );
1745
+ PQclear (tablespace_map_content );
1746
+ }
1747
+ }
1748
+ else
1749
+ val = PQgetvalue (res , 0 , 4 );
1699
1750
1700
- pgBackupGetPath (& current , path , lengthof (path ), DATABASE_DIR );
1751
+ /* Write tablespace_map */
1752
+ if (val && strlen (val ) > 0 )
1753
+ {
1754
+ char tablespace_map [MAXPGPATH ];
1701
1755
1702
- /* Write backup_label */
1703
- join_path_components (backup_label , path , PG_BACKUP_LABEL_FILE );
1704
- fp = fopen (backup_label , "w" );
1756
+ join_path_components (tablespace_map , path , PG_TABLESPACE_MAP_FILE );
1757
+ fp = fopen (tablespace_map , "w" );
1705
1758
if (fp == NULL )
1706
- elog (ERROR , "can't open backup label file \"%s\": %s" ,
1707
- backup_label , strerror (errno ));
1759
+ elog (ERROR , "can't open tablespace map file \"%s\": %s" ,
1760
+ tablespace_map , strerror (errno ));
1708
1761
1709
- len = strlen (PQgetvalue ( res , 0 , 1 ) );
1710
- if (fwrite (PQgetvalue ( res , 0 , 1 ) , 1 , len , fp ) != len ||
1762
+ len = strlen (val );
1763
+ if (fwrite (val , 1 , len , fp ) != len ||
1711
1764
fflush (fp ) != 0 ||
1712
1765
fsync (fileno (fp )) != 0 ||
1713
1766
fclose (fp ))
1714
- elog (ERROR , "can't write backup label file \"%s\": %s" ,
1715
- backup_label , strerror (errno ));
1767
+ elog (ERROR , "can't write tablespace map file \"%s\": %s" ,
1768
+ tablespace_map , strerror (errno ));
1716
1769
1717
- /*
1718
- * It's vital to check if backup_files_list is initialized,
1719
- * because we could get here because the backup was interrupted
1720
- */
1721
1770
if (backup_files_list )
1722
1771
{
1723
- file = pgFileNew (backup_label , true);
1724
- calc_file_checksum (file );
1772
+ file = pgFileNew (tablespace_map , true);
1773
+ if (S_ISREG (file -> mode ))
1774
+ calc_file_checksum (file );
1725
1775
free (file -> path );
1726
- file -> path = strdup (PG_BACKUP_LABEL_FILE );
1776
+ file -> path = strdup (PG_TABLESPACE_MAP_FILE );
1727
1777
parray_append (backup_files_list , file );
1728
1778
}
1729
-
1730
- /* Write tablespace_map */
1731
- if (strlen (PQgetvalue (res , 0 , 2 )) > 0 )
1732
- {
1733
- char tablespace_map [MAXPGPATH ];
1734
-
1735
- join_path_components (tablespace_map , path , PG_TABLESPACE_MAP_FILE );
1736
- fp = fopen (tablespace_map , "w" );
1737
- if (fp == NULL )
1738
- elog (ERROR , "can't open tablespace map file \"%s\": %s" ,
1739
- tablespace_map , strerror (errno ));
1740
-
1741
- len = strlen (PQgetvalue (res , 0 , 2 ));
1742
- if (fwrite (PQgetvalue (res , 0 , 2 ), 1 , len , fp ) != len ||
1743
- fflush (fp ) != 0 ||
1744
- fsync (fileno (fp )) != 0 ||
1745
- fclose (fp ))
1746
- elog (ERROR , "can't write tablespace map file \"%s\": %s" ,
1747
- tablespace_map , strerror (errno ));
1748
-
1749
- if (backup_files_list )
1750
- {
1751
- file = pgFileNew (tablespace_map , true);
1752
- if (S_ISREG (file -> mode ))
1753
- calc_file_checksum (file );
1754
- free (file -> path );
1755
- file -> path = strdup (PG_TABLESPACE_MAP_FILE );
1756
- parray_append (backup_files_list , file );
1757
- }
1758
- }
1759
-
1760
- if (sscanf (PQgetvalue (res , 0 , 3 ), XID_FMT , & recovery_xid ) != 1 )
1761
- elog (ERROR ,
1762
- "result of txid_snapshot_xmax() is invalid: %s" ,
1763
- PQerrorMessage (conn ));
1764
- if (!parse_time (PQgetvalue (res , 0 , 4 ), & recovery_time ))
1765
- elog (ERROR ,
1766
- "result of current_timestamp is invalid: %s" ,
1767
- PQerrorMessage (conn ));
1768
- }
1769
- else
1770
- {
1771
- if (sscanf (PQgetvalue (res , 0 , 1 ), XID_FMT , & recovery_xid ) != 1 )
1772
- elog (ERROR ,
1773
- "result of txid_snapshot_xmax() is invalid: %s" ,
1774
- PQerrorMessage (conn ));
1775
- if (!parse_time (PQgetvalue (res , 0 , 2 ), & recovery_time ))
1776
- elog (ERROR ,
1777
- "result of current_timestamp is invalid: %s" ,
1778
- PQerrorMessage (conn ));
1779
1779
}
1780
1780
PQclear (res );
1781
1781
if (stream_wal )
0 commit comments