@@ -104,7 +104,8 @@ static int checkpoint_timeout(void);
104
104
105
105
//static void backup_list_file(parray *files, const char *root, )
106
106
static void parse_backup_filelist_filenames (parray * files , const char * root );
107
- static void wait_wal_lsn (XLogRecPtr lsn , bool wait_prev_segment );
107
+ static void wait_wal_lsn (XLogRecPtr lsn , bool is_start_lsn ,
108
+ bool wait_prev_segment );
108
109
static void wait_replica_wal_lsn (XLogRecPtr lsn , bool is_start_backup );
109
110
static void make_pagemap_from_ptrack (parray * files );
110
111
static void * StreamLog (void * arg );
@@ -717,7 +718,7 @@ do_backup_instance(void)
717
718
}
718
719
719
720
/* Run threads */
720
- elog (LOG , "Start transfering data files" );
721
+ elog (INFO , "Start transfering data files" );
721
722
for (i = 0 ; i < num_threads ; i ++ )
722
723
{
723
724
backup_files_arg * arg = & (threads_args [i ]);
@@ -738,7 +739,7 @@ do_backup_instance(void)
738
739
backup_isok = false;
739
740
}
740
741
if (backup_isok )
741
- elog (LOG , "Data files are transfered" );
742
+ elog (INFO , "Data files are transfered" );
742
743
else
743
744
elog (ERROR , "Data files transferring failed" );
744
745
@@ -1070,8 +1071,8 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
1070
1071
{
1071
1072
PGresult * res ;
1072
1073
const char * params [2 ];
1073
- uint32 xlogid ;
1074
- uint32 xrecoff ;
1074
+ uint32 lsn_hi ;
1075
+ uint32 lsn_lo ;
1075
1076
PGconn * conn ;
1076
1077
1077
1078
params [0 ] = label ;
@@ -1099,9 +1100,9 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
1099
1100
backup_in_progress = true;
1100
1101
1101
1102
/* Extract timeline and LSN from results of pg_start_backup() */
1102
- XLogDataFromLSN (PQgetvalue (res , 0 , 0 ), & xlogid , & xrecoff );
1103
+ XLogDataFromLSN (PQgetvalue (res , 0 , 0 ), & lsn_hi , & lsn_lo );
1103
1104
/* Calculate LSN */
1104
- backup -> start_lsn = (XLogRecPtr ) (( uint64 ) xlogid << 32 ) | xrecoff ;
1105
+ backup -> start_lsn = (( uint64 ) lsn_hi ) << 32 | lsn_lo ;
1105
1106
1106
1107
PQclear (res );
1107
1108
@@ -1112,20 +1113,17 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
1112
1113
*/
1113
1114
pg_switch_wal (conn );
1114
1115
1115
- if (!stream_wal )
1116
- {
1117
- /*
1118
- * Do not wait start_lsn for stream backup.
1119
- * Because WAL streaming will start after pg_start_backup() in stream
1120
- * mode.
1121
- */
1116
+ if (current .backup_mode == BACKUP_MODE_DIFF_PAGE )
1122
1117
/* In PAGE mode wait for current segment... */
1123
- if (current .backup_mode == BACKUP_MODE_DIFF_PAGE )
1124
- wait_wal_lsn (backup -> start_lsn , false);
1118
+ wait_wal_lsn (backup -> start_lsn , true, false);
1119
+ /*
1120
+ * Do not wait start_lsn for stream backup.
1121
+ * Because WAL streaming will start after pg_start_backup() in stream
1122
+ * mode.
1123
+ */
1124
+ else if (!stream_wal )
1125
1125
/* ...for others wait for previous segment */
1126
- else
1127
- wait_wal_lsn (backup -> start_lsn , true);
1128
- }
1126
+ wait_wal_lsn (backup -> start_lsn , true, true);
1129
1127
1130
1128
/* Wait for start_lsn to be replayed by replica */
1131
1129
if (backup -> from_replica )
@@ -1443,16 +1441,20 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_filenode,
1443
1441
* If current backup started in stream mode wait for 'lsn' to be streamed in
1444
1442
* 'pg_wal' directory.
1445
1443
*
1444
+ * If 'is_start_lsn' is true and backup mode is PAGE then we wait for 'lsn' to
1445
+ * be archived in archive 'wal' directory regardless stream mode.
1446
+ *
1446
1447
* If 'wait_prev_segment' wait for previous segment.
1447
1448
*/
1448
1449
static void
1449
- wait_wal_lsn (XLogRecPtr lsn , bool wait_prev_segment )
1450
+ wait_wal_lsn (XLogRecPtr lsn , bool is_start_lsn , bool wait_prev_segment )
1450
1451
{
1451
1452
TimeLineID tli ;
1452
1453
XLogSegNo targetSegNo ;
1453
- char wal_dir [MAXPGPATH ],
1454
- wal_segment_path [MAXPGPATH ];
1455
- char wal_segment [MAXFNAMELEN ];
1454
+ char pg_wal_dir [MAXPGPATH ];
1455
+ char wal_segment_path [MAXPGPATH ],
1456
+ * wal_segment_dir ,
1457
+ wal_segment [MAXFNAMELEN ];
1456
1458
bool file_exists = false;
1457
1459
uint32 try_count = 0 ,
1458
1460
timeout ;
@@ -1469,18 +1471,28 @@ wait_wal_lsn(XLogRecPtr lsn, bool wait_prev_segment)
1469
1471
targetSegNo -- ;
1470
1472
XLogFileName (wal_segment , tli , targetSegNo );
1471
1473
1472
- if (stream_wal )
1474
+ /*
1475
+ * In pg_start_backup we wait for 'lsn' in 'pg_wal' directory iff it is
1476
+ * stream and non-page backup. Page backup needs archived WAL files, so we
1477
+ * wait for 'lsn' in archive 'wal' directory for page backups.
1478
+ *
1479
+ * In pg_stop_backup it depends only on stream_wal.
1480
+ */
1481
+ if (stream_wal &&
1482
+ (current .backup_mode != BACKUP_MODE_DIFF_PAGE || !is_start_lsn ))
1473
1483
{
1474
- pgBackupGetPath2 (& current , wal_dir , lengthof (wal_dir ),
1484
+ pgBackupGetPath2 (& current , pg_wal_dir , lengthof (pg_wal_dir ),
1475
1485
DATABASE_DIR , PG_XLOG_DIR );
1476
- join_path_components (wal_segment_path , wal_dir , wal_segment );
1486
+ join_path_components (wal_segment_path , pg_wal_dir , wal_segment );
1487
+ wal_segment_dir = pg_wal_dir ;
1477
1488
1478
1489
timeout = (uint32 ) checkpoint_timeout ();
1479
1490
timeout = timeout + timeout * 0.1 ;
1480
1491
}
1481
1492
else
1482
1493
{
1483
1494
join_path_components (wal_segment_path , arclog_path , wal_segment );
1495
+ wal_segment_dir = arclog_path ;
1484
1496
timeout = archive_timeout ;
1485
1497
}
1486
1498
@@ -1523,8 +1535,7 @@ wait_wal_lsn(XLogRecPtr lsn, bool wait_prev_segment)
1523
1535
/*
1524
1536
* A WAL segment found. Check LSN on it.
1525
1537
*/
1526
- if ((stream_wal && wal_contains_lsn (wal_dir , lsn , tli )) ||
1527
- (!stream_wal && wal_contains_lsn (arclog_path , lsn , tli )))
1538
+ if (wal_contains_lsn (wal_segment_dir , lsn , tli ))
1528
1539
/* Target LSN was found */
1529
1540
{
1530
1541
elog (LOG , "Found LSN: %X/%X" , (uint32 ) (lsn >> 32 ), (uint32 ) lsn );
@@ -1574,8 +1585,8 @@ wait_replica_wal_lsn(XLogRecPtr lsn, bool is_start_backup)
1574
1585
while (true)
1575
1586
{
1576
1587
PGresult * res ;
1577
- uint32 xlogid ;
1578
- uint32 xrecoff ;
1588
+ uint32 lsn_hi ;
1589
+ uint32 lsn_lo ;
1579
1590
XLogRecPtr replica_lsn ;
1580
1591
1581
1592
/*
@@ -1606,9 +1617,9 @@ wait_replica_wal_lsn(XLogRecPtr lsn, bool is_start_backup)
1606
1617
}
1607
1618
1608
1619
/* Extract timeline and LSN from result */
1609
- XLogDataFromLSN (PQgetvalue (res , 0 , 0 ), & xlogid , & xrecoff );
1620
+ XLogDataFromLSN (PQgetvalue (res , 0 , 0 ), & lsn_hi , & lsn_lo );
1610
1621
/* Calculate LSN */
1611
- replica_lsn = (XLogRecPtr ) (( uint64 ) xlogid << 32 ) | xrecoff ;
1622
+ replica_lsn = (( uint64 ) lsn_hi ) << 32 | lsn_lo ;
1612
1623
PQclear (res );
1613
1624
1614
1625
/* target lsn was replicated */
@@ -1642,10 +1653,10 @@ pg_stop_backup(pgBackup *backup)
1642
1653
PGconn * conn ;
1643
1654
PGresult * res ;
1644
1655
PGresult * tablespace_map_content = NULL ;
1645
- uint32 xlogid ;
1646
- uint32 xrecoff ;
1656
+ uint32 lsn_hi ;
1657
+ uint32 lsn_lo ;
1647
1658
XLogRecPtr restore_lsn = InvalidXLogRecPtr ;
1648
- int pg_stop_backup_timeout = 0 ;
1659
+ int pg_stop_backup_timeout = 0 ;
1649
1660
char path [MAXPGPATH ];
1650
1661
char backup_label [MAXPGPATH ];
1651
1662
FILE * fp ;
@@ -1688,6 +1699,10 @@ pg_stop_backup(pgBackup *backup)
1688
1699
1689
1700
res = pgut_execute (conn , "SELECT pg_catalog.pg_create_restore_point($1)" ,
1690
1701
1 , params );
1702
+ /* Extract timeline and LSN from the result */
1703
+ XLogDataFromLSN (PQgetvalue (res , 0 , 0 ), & lsn_hi , & lsn_lo );
1704
+ /* Calculate LSN */
1705
+ restore_lsn = ((uint64 ) lsn_hi ) << 32 | lsn_lo ;
1691
1706
PQclear (res );
1692
1707
}
1693
1708
@@ -1720,7 +1735,6 @@ pg_stop_backup(pgBackup *backup)
1720
1735
}
1721
1736
else
1722
1737
{
1723
-
1724
1738
stop_backup_query = "SELECT"
1725
1739
" pg_catalog.txid_snapshot_xmax(pg_catalog.txid_current_snapshot()),"
1726
1740
" current_timestamp(0)::timestamptz,"
@@ -1739,6 +1753,8 @@ pg_stop_backup(pgBackup *backup)
1739
1753
*/
1740
1754
if (pg_stop_backup_is_sent && !in_cleanup )
1741
1755
{
1756
+ res = NULL ;
1757
+
1742
1758
while (1 )
1743
1759
{
1744
1760
if (!PQconsumeInput (conn ) || PQisBusy (conn ))
@@ -1780,8 +1796,11 @@ pg_stop_backup(pgBackup *backup)
1780
1796
{
1781
1797
switch (PQresultStatus (res ))
1782
1798
{
1799
+ /*
1800
+ * We should expect only PGRES_TUPLES_OK since pg_stop_backup
1801
+ * returns tuples.
1802
+ */
1783
1803
case PGRES_TUPLES_OK :
1784
- case PGRES_COMMAND_OK :
1785
1804
break ;
1786
1805
default :
1787
1806
elog (ERROR , "query failed: %s query was: %s" ,
@@ -1793,9 +1812,9 @@ pg_stop_backup(pgBackup *backup)
1793
1812
backup_in_progress = false;
1794
1813
1795
1814
/* Extract timeline and LSN from results of pg_stop_backup() */
1796
- XLogDataFromLSN (PQgetvalue (res , 0 , 2 ), & xlogid , & xrecoff );
1815
+ XLogDataFromLSN (PQgetvalue (res , 0 , 2 ), & lsn_hi , & lsn_lo );
1797
1816
/* Calculate LSN */
1798
- stop_backup_lsn = (XLogRecPtr ) (( uint64 ) xlogid << 32 ) | xrecoff ;
1817
+ stop_backup_lsn = (( uint64 ) lsn_hi ) << 32 | lsn_lo ;
1799
1818
1800
1819
if (!XRecOffIsValid (stop_backup_lsn ))
1801
1820
{
@@ -1912,7 +1931,7 @@ pg_stop_backup(pgBackup *backup)
1912
1931
* Wait for stop_lsn to be archived or streamed.
1913
1932
* We wait for stop_lsn in stream mode just in case.
1914
1933
*/
1915
- wait_wal_lsn (stop_backup_lsn , false);
1934
+ wait_wal_lsn (stop_backup_lsn , false, false );
1916
1935
1917
1936
if (stream_wal )
1918
1937
{
@@ -2606,16 +2625,16 @@ get_last_ptrack_lsn(void)
2606
2625
2607
2626
{
2608
2627
PGresult * res ;
2609
- uint32 xlogid ;
2610
- uint32 xrecoff ;
2628
+ uint32 lsn_hi ;
2629
+ uint32 lsn_lo ;
2611
2630
XLogRecPtr lsn ;
2612
2631
2613
2632
res = pgut_execute (backup_conn , "select pg_catalog.pg_ptrack_control_lsn()" , 0 , NULL );
2614
2633
2615
2634
/* Extract timeline and LSN from results of pg_start_backup() */
2616
- XLogDataFromLSN (PQgetvalue (res , 0 , 0 ), & xlogid , & xrecoff );
2635
+ XLogDataFromLSN (PQgetvalue (res , 0 , 0 ), & lsn_hi , & lsn_lo );
2617
2636
/* Calculate LSN */
2618
- lsn = (XLogRecPtr ) (( uint64 ) xlogid << 32 ) | xrecoff ;
2637
+ lsn = (( uint64 ) lsn_hi ) << 32 | lsn_lo ;
2619
2638
2620
2639
PQclear (res );
2621
2640
return lsn ;
0 commit comments