@@ -475,6 +475,8 @@ do_backup_instance(void)
475475 pgBackup * prev_backup = NULL ;
476476 parray * prev_backup_filelist = NULL ;
477477
478+ pgFile * pg_control = NULL ;
479+
478480 elog (LOG , "Database backup start" );
479481
480482 /* Initialize size summary */
@@ -754,9 +756,37 @@ do_backup_instance(void)
754756 parray_free (prev_backup_filelist );
755757 }
756758
759+ /* Copy pg_control in case of backup from replica >= 9.6 */
760+ if (current .from_replica && !exclusive_backup )
761+ {
762+ for (i = 0 ; i < parray_num (backup_files_list ); i ++ )
763+ {
764+ pgFile * tmp_file = (pgFile * ) parray_get (backup_files_list , i );
765+
766+ if (strcmp (tmp_file -> name , "pg_control" ) == 0 )
767+ {
768+ pg_control = tmp_file ;
769+ break ;
770+ }
771+ }
772+
773+ if (!pg_control )
774+ elog (ERROR , "Failed to locate pg_control in copied files" );
775+
776+ if (is_remote_backup )
777+ remote_copy_file (NULL , pg_control );
778+ else
779+ if (!copy_file (pgdata , database_path , pg_control ))
780+ elog (ERROR , "Failed to copy pg_control" );
781+ }
782+
783+
757784 /* Notify end of backup */
758785 pg_stop_backup (& current );
759786
787+ if (current .from_replica && !exclusive_backup )
788+ set_min_recovery_point (pg_control , database_path , current .stop_lsn );
789+
760790 /* Add archived xlog files into the list of files of this backup */
761791 if (stream_wal )
762792 {
@@ -883,7 +913,7 @@ do_backup(time_t start_time)
883913 }
884914 }
885915
886- if (current .from_replica )
916+ if (current .from_replica && exclusive_backup )
887917 {
888918 /* Check master connection options */
889919 if (master_host == NULL )
@@ -1089,8 +1119,11 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
10891119
10901120 params [0 ] = label ;
10911121
1092- /* For replica we call pg_start_backup() on master */
1093- conn = (backup -> from_replica ) ? master_conn : backup_conn ;
1122+ /* For 9.5 replica we call pg_start_backup() on master */
1123+ if (backup -> from_replica && exclusive_backup )
1124+ conn = master_conn ;
1125+ else
1126+ conn = backup_conn ;
10941127
10951128 /* 2nd argument is 'fast'*/
10961129 params [1 ] = smooth ? "false" : "true" ;
@@ -1118,16 +1151,21 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
11181151
11191152 PQclear (res );
11201153
1121- if (current .backup_mode == BACKUP_MODE_DIFF_PAGE )
1154+ if (current .backup_mode == BACKUP_MODE_DIFF_PAGE &&
1155+ (!(backup -> from_replica && !exclusive_backup )))
11221156 /*
11231157 * Switch to a new WAL segment. It is necessary to get archived WAL
11241158 * segment, which includes start LSN of current backup.
1159+ * Don`t do this for replica backups unless it`s PG 9.5
11251160 */
11261161 pg_switch_wal (conn );
11271162
1163+ //elog(INFO, "START LSN: %X/%X",
1164+ // (uint32) (backup->start_lsn >> 32), (uint32) (backup->start_lsn));
1165+
11281166 if (current .backup_mode == BACKUP_MODE_DIFF_PAGE )
11291167 /* In PAGE mode wait for current segment... */
1130- wait_wal_lsn (backup -> start_lsn , true, false);
1168+ wait_wal_lsn (backup -> start_lsn , true, false);
11311169 /*
11321170 * Do not wait start_lsn for stream backup.
11331171 * Because WAL streaming will start after pg_start_backup() in stream
@@ -1669,7 +1707,7 @@ pg_stop_backup(pgBackup *backup)
16691707 PGresult * tablespace_map_content = NULL ;
16701708 uint32 lsn_hi ;
16711709 uint32 lsn_lo ;
1672- XLogRecPtr restore_lsn = InvalidXLogRecPtr ;
1710+ // XLogRecPtr restore_lsn = InvalidXLogRecPtr;
16731711 int pg_stop_backup_timeout = 0 ;
16741712 char path [MAXPGPATH ];
16751713 char backup_label [MAXPGPATH ];
@@ -1689,16 +1727,21 @@ pg_stop_backup(pgBackup *backup)
16891727 if (!backup_in_progress )
16901728 elog (ERROR , "backup is not in progress" );
16911729
1692- /* For replica we call pg_stop_backup() on master */
1693- conn = (current .from_replica ) ? master_conn : backup_conn ;
1730+ /* For 9.5 replica we call pg_stop_backup() on master */
1731+ if (current .from_replica && exclusive_backup )
1732+ conn = master_conn ;
1733+ else
1734+ conn = backup_conn ;
16941735
16951736 /* Remove annoying NOTICE messages generated by backend */
16961737 res = pgut_execute (conn , "SET client_min_messages = warning;" ,
16971738 0 , NULL );
16981739 PQclear (res );
16991740
1700- /* Create restore point */
1701- if (backup != NULL )
1741+ /* Create restore point
1742+ * only if it`s backup from master, or exclusive replica(wich connects to master)
1743+ */
1744+ if (backup != NULL && (!current .from_replica || (current .from_replica && exclusive_backup )))
17021745 {
17031746 const char * params [1 ];
17041747 char name [1024 ];
@@ -1716,7 +1759,7 @@ pg_stop_backup(pgBackup *backup)
17161759 /* Extract timeline and LSN from the result */
17171760 XLogDataFromLSN (PQgetvalue (res , 0 , 0 ), & lsn_hi , & lsn_lo );
17181761 /* Calculate LSN */
1719- restore_lsn = ((uint64 ) lsn_hi ) << 32 | lsn_lo ;
1762+ // restore_lsn = ((uint64) lsn_hi) << 32 | lsn_lo;
17201763 PQclear (res );
17211764 }
17221765
@@ -1830,10 +1873,10 @@ pg_stop_backup(pgBackup *backup)
18301873 /* Calculate LSN */
18311874 stop_backup_lsn = ((uint64 ) lsn_hi ) << 32 | lsn_lo ;
18321875
1833- if (!XRecOffIsValid (stop_backup_lsn ))
1834- {
1835- stop_backup_lsn = restore_lsn ;
1836- }
1876+ // if (!XRecOffIsValid(stop_backup_lsn))
1877+ // {
1878+ // stop_backup_lsn = restore_lsn;
1879+ // }
18371880
18381881 if (!XRecOffIsValid (stop_backup_lsn ))
18391882 elog (ERROR , "Invalid stop_backup_lsn value %X/%X" ,
@@ -1939,7 +1982,7 @@ pg_stop_backup(pgBackup *backup)
19391982 stream_xlog_path [MAXPGPATH ];
19401983
19411984 /* Wait for stop_lsn to be received by replica */
1942- if (backup -> from_replica )
1985+ if (current . from_replica )
19431986 wait_replica_wal_lsn (stop_backup_lsn , false);
19441987 /*
19451988 * Wait for stop_lsn to be archived or streamed.
@@ -1962,10 +2005,12 @@ pg_stop_backup(pgBackup *backup)
19622005
19632006 elog (LOG , "Getting the Recovery Time from WAL" );
19642007
2008+ /* iterate over WAL from stop_backup lsn to start_backup lsn */
19652009 if (!read_recovery_info (xlog_path , backup -> tli , xlog_seg_size ,
19662010 backup -> start_lsn , backup -> stop_lsn ,
19672011 & backup -> recovery_time , & backup -> recovery_xid ))
19682012 {
2013+ elog (LOG , "Failed to find Recovery Time in WAL. Forced to trust current_timestamp" );
19692014 backup -> recovery_time = recovery_time ;
19702015 backup -> recovery_xid = recovery_xid ;
19712016 }
@@ -2074,7 +2119,7 @@ backup_files(void *arg)
20742119 elog (ERROR , "interrupted during backup" );
20752120
20762121 if (progress )
2077- elog (LOG , "Progress: (%d/%d). Process file \"%s\"" ,
2122+ elog (INFO , "Progress: (%d/%d). Process file \"%s\"" ,
20782123 i + 1 , n_backup_files_list , file -> path );
20792124
20802125 /* stat file to check its current state */
@@ -2168,7 +2213,7 @@ backup_files(void *arg)
21682213 file -> path , file -> write_size );
21692214 }
21702215 else
2171- elog (LOG , "unexpected file type %d" , buf .st_mode );
2216+ elog (WARNING , "unexpected file type %d" , buf .st_mode );
21722217 }
21732218
21742219 /* Close connection */
0 commit comments