@@ -80,6 +80,7 @@ static void backup_files(void *arg);
80
80
static void do_backup_database (parray * backup_list );
81
81
82
82
static void pg_start_backup (const char * label , bool smooth , pgBackup * backup );
83
+ static void pg_switch_wal (PGconn * conn );
83
84
static void pg_stop_backup (pgBackup * backup );
84
85
static int checkpoint_timeout (void );
85
86
@@ -639,19 +640,53 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
639
640
640
641
PQclear (res );
641
642
643
+ if (current .backup_mode == BACKUP_MODE_DIFF_PAGE )
644
+ /*
645
+ * Switch to a new WAL segment. It is necessary to get archived WAL
646
+ * segment, which includes start LSN of current backup.
647
+ */
648
+ pg_switch_wal (conn );
649
+
642
650
if (!stream_wal )
651
+ {
643
652
/*
644
653
* Do not wait start_lsn for stream backup.
645
654
* Because WAL streaming will start after pg_start_backup() in stream
646
655
* mode.
647
656
*/
648
- wait_wal_lsn (backup -> start_lsn , true);
657
+ /* In PAGE mode wait for current segment... */
658
+ if (current .backup_mode == BACKUP_MODE_DIFF_PAGE )
659
+ wait_wal_lsn (backup -> start_lsn , false);
660
+ /* ...for others wait for previous segment */
661
+ else
662
+ wait_wal_lsn (backup -> start_lsn , true);
663
+ }
649
664
650
665
/* Wait for start_lsn to be replayed by replica */
651
666
if (from_replica )
652
667
wait_replica_wal_lsn (backup -> start_lsn , true);
653
668
}
654
669
670
+ /*
671
+ * Switch to a new WAL segment. It should be called only for master.
672
+ */
673
+ static void
674
+ pg_switch_wal (PGconn * conn )
675
+ {
676
+ PGresult * res ;
677
+
678
+ /* Remove annoying NOTICE messages generated by backend */
679
+ res = pgut_execute (conn , "SET client_min_messages = warning;" , 0 , NULL );
680
+ PQclear (res );
681
+
682
+ if (server_version >= 100000 )
683
+ res = pgut_execute (conn , "SELECT * FROM pg_switch_wal()" , 0 , NULL );
684
+ else
685
+ res = pgut_execute (conn , "SELECT * FROM pg_switch_xlog()" , 0 , NULL );
686
+
687
+ PQclear (res );
688
+ }
689
+
655
690
/*
656
691
* Check if the instance supports ptrack
657
692
* TODO Maybe we should rather check ptrack_version()?
@@ -974,7 +1009,7 @@ pg_stop_backup(pgBackup *backup)
974
1009
uint32 xrecoff ;
975
1010
XLogRecPtr restore_lsn = InvalidXLogRecPtr ;
976
1011
bool sent = false;
977
- int pg_stop_backup_timeout = 0 ;
1012
+ int pg_stop_backup_timeout = 0 ;
978
1013
979
1014
/*
980
1015
* We will use this values if there are no transactions between start_lsn
@@ -1050,8 +1085,6 @@ pg_stop_backup(pgBackup *backup)
1050
1085
* Wait for the result of pg_stop_backup(),
1051
1086
* but no longer than PG_STOP_BACKUP_TIMEOUT seconds
1052
1087
*/
1053
- elog (INFO , "wait for pg_stop_backup()" );
1054
-
1055
1088
while (1 )
1056
1089
{
1057
1090
if (!PQconsumeInput (conn ) || PQisBusy (conn ))
@@ -1064,6 +1097,10 @@ pg_stop_backup(pgBackup *backup)
1064
1097
pgut_cancel (conn );
1065
1098
elog (ERROR , "interrupted during waiting for pg_stop_backup" );
1066
1099
}
1100
+
1101
+ if (pg_stop_backup_timeout == 1 )
1102
+ elog (INFO , "wait for pg_stop_backup()" );
1103
+
1067
1104
/*
1068
1105
* If postgres haven't answered in PG_STOP_BACKUP_TIMEOUT seconds,
1069
1106
* send an interrupt.
0 commit comments