@@ -67,7 +67,6 @@ static parray *do_backup_database(parray *backup_list, bool smooth_checkpoint);
6767
6868static void pg_start_backup (const char * label ,bool smooth ,pgBackup * backup );
6969static void pg_stop_backup (pgBackup * backup );
70- static void pg_switch_xlog (void );
7170
7271static bool pg_is_standby (void );
7372static void add_pgdata_files (parray * files ,const char * root );
@@ -169,7 +168,7 @@ do_backup_database(parray *backup_list, bool smooth_checkpoint)
169168/* start stream replication */
170169if (stream_wal )
171170{
172- join_path_components (dst_backup_path ,database_path ,"pg_xlog" );
171+ join_path_components (dst_backup_path ,database_path ,PG_XLOG_DIR );
173172dir_create_dir (dst_backup_path ,DIR_PERMISSION );
174173
175174pthread_mutex_lock (& check_stream_mut );
@@ -186,14 +185,14 @@ do_backup_database(parray *backup_list, bool smooth_checkpoint)
186185char label_path [MAXPGPATH ];
187186
188187/* If backup_label does not exist in $PGDATA, stop taking backup */
189- join_path_components (label_path ,pgdata ,"backup_label" );
188+ join_path_components (label_path ,pgdata ,PG_BACKUP_LABEL_FILE );
190189
191190/* Leave if no backup file */
192191if (!fileExists (label_path ))
193192{
194- elog (LOG ,"backup_label does not exist, stopping backup" );
193+ elog (LOG ,"%s does not exist, stopping backup" , PG_BACKUP_LABEL_FILE );
195194pg_stop_backup (NULL );
196- elog (ERROR ,"backup_label does not exist in PGDATA." );
195+ elog (ERROR ,"%s does not exist in PGDATA" , PG_BACKUP_LABEL_FILE );
197196}
198197}
199198
@@ -353,7 +352,7 @@ do_backup_database(parray *backup_list, bool smooth_checkpoint)
353352
354353/* Scan backup pg_xlog dir */
355354list_file = parray_new ();
356- join_path_components (pg_xlog_path ,database_path ,"pg_xlog" );
355+ join_path_components (pg_xlog_path ,database_path ,PG_XLOG_DIR );
357356dir_list_file (list_file ,pg_xlog_path , false, true, false);
358357
359358/* Remove file path root prefix and calc meta */
@@ -739,6 +738,8 @@ wait_archive_lsn(XLogRecPtr lsn, bool prev_segno)
739738char wal_file [MAXFNAMELEN ];
740739uint32 try_count = 0 ;
741740
741+ Assert (!stream_wal );
742+
742743tli = get_current_timeline (false);
743744
744745/* As well as WAL file name */
@@ -764,8 +765,8 @@ wait_archive_lsn(XLogRecPtr lsn, bool prev_segno)
764765
765766if (archive_timeout > 0 && try_count > archive_timeout )
766767elog (ERROR ,
767- "switched WAL could not be archived in %d seconds" ,
768- archive_timeout );
768+ "switched WALsegment %s could not be archived in %d seconds" ,
769+ wal_file , archive_timeout );
769770}
770771}
771772
@@ -778,6 +779,8 @@ pg_stop_backup(pgBackup *backup)
778779PGresult * res ;
779780uint32 xlogid ;
780781uint32 xrecoff ;
782+ time_t recovery_time ;
783+ TransactionId recovery_xid ;
781784
782785/* Remove annoying NOTICE messages generated by backend */
783786res = pgut_execute (backup_conn ,"SET client_min_messages = warning;" ,
@@ -786,10 +789,18 @@ pg_stop_backup(pgBackup *backup)
786789
787790if (from_replica )
788791res = pgut_execute (backup_conn ,
789- "SELECT * FROM pg_stop_backup(false)" ,0 ,NULL );
792+ "SELECT *, txid_snapshot_xmax(txid_current_snapshot()) FROM pg_stop_backup(false)" ,
793+ 0 ,NULL );
790794else
791795res = pgut_execute (backup_conn ,
792- "SELECT * FROM pg_stop_backup()" ,0 ,NULL );
796+ "SELECT *, txid_snapshot_xmax(txid_current_snapshot()) FROM pg_stop_backup()" ,
797+ 0 ,NULL );
798+
799+ /*
800+ * We will use this value if there are no transactions between start_lsn
801+ * and stop_lsn.
802+ */
803+ recovery_time = time (NULL );
793804
794805/*
795806 * Extract timeline and LSN from results of pg_stop_backup()
@@ -809,7 +820,7 @@ pg_stop_backup(pgBackup *backup)
809820Assert (PQnfields (res ) >=3 );
810821
811822pgBackupGetPath (& current ,path ,lengthof (path ),DATABASE_DIR );
812- join_path_components (backup_label ,path ,"backup_label" );
823+ join_path_components (backup_label ,path ,PG_BACKUP_LABEL_FILE );
813824
814825/* Write backup_label */
815826fp = fopen (backup_label ,"w" );
@@ -823,7 +834,7 @@ pg_stop_backup(pgBackup *backup)
823834file = pgFileNew (backup_label , true);
824835calc_file (file );
825836free (file -> path );
826- file -> path = strdup ("backup_label" );
837+ file -> path = strdup (PG_BACKUP_LABEL_FILE );
827838parray_append (backup_files_list ,file );
828839
829840/* Write tablespace_map */
@@ -847,7 +858,17 @@ pg_stop_backup(pgBackup *backup)
847858file -> path = strdup ("tablespace_map" );
848859parray_append (backup_files_list ,file );
849860}
861+
862+ if (sscanf (PQgetvalue (res ,0 ,3 ),XID_FMT ,& recovery_xid )!= 1 )
863+ elog (ERROR ,
864+ "result of txid_snapshot_xmax() is invalid: %s" ,
865+ PQerrorMessage (backup_conn ));
850866}
867+ else
868+ if (sscanf (PQgetvalue (res ,0 ,1 ),XID_FMT ,& recovery_xid )!= 1 )
869+ elog (ERROR ,
870+ "result of txid_snapshot_xmax() is invalid: %s" ,
871+ PQerrorMessage (backup_conn ));
851872
852873PQclear (res );
853874
@@ -857,63 +878,30 @@ pg_stop_backup(pgBackup *backup)
857878/* Fill in fields if backup exists */
858879if (backup != NULL )
859880{
860- backup -> tli = get_current_timeline (false);
861- backup -> stop_lsn = stop_backup_lsn ;
881+ char * xlog_path ,
882+ stream_xlog_path [ MAXPGPATH ] ;
862883
863- if (from_replica )
864- res = pgut_execute (backup_conn ,TXID_CURRENT_IF_SQL ,0 ,NULL );
884+ if (stream_wal )
885+ {
886+ join_path_components (stream_xlog_path ,pgdata ,PG_XLOG_DIR );
887+ xlog_path = stream_xlog_path ;
888+ }
865889else
866- res = pgut_execute (backup_conn ,TXID_CURRENT_SQL ,0 ,NULL );
867-
868- if (sscanf (PQgetvalue (res ,0 ,0 ),XID_FMT ,& backup -> recovery_xid )!= 1 )
869- elog (ERROR ,
870- "result of txid_current() is invalid: %s" ,
871- PQerrorMessage (backup_conn ));
872- backup -> recovery_time = time (NULL );
890+ xlog_path = arclog_path ;
873891
874- elog (LOG ,"finish backup: tli=%X lsn=%X/%08X xid=%s" ,
875- backup -> tli ,
876- (uint32 ) (backup -> stop_lsn >>32 ), (uint32 )backup -> stop_lsn ,
877- PQgetvalue (res ,0 ,0 ));
892+ backup -> tli = get_current_timeline (false);
893+ backup -> stop_lsn = stop_backup_lsn ;
878894
879- PQclear (res );
895+ if (!read_recovery_info (xlog_path ,backup -> tli ,
896+ backup -> start_lsn ,backup -> stop_lsn ,
897+ & backup -> recovery_time ,& backup -> recovery_xid ))
898+ {
899+ backup -> recovery_time = recovery_time ;
900+ backup -> recovery_xid = recovery_xid ;
901+ }
880902}
881903}
882904
883- /*
884- * Switch to a new WAL segment for master.
885- */
886- static void
887- pg_switch_xlog (void )
888- {
889- PGresult * res ;
890- XLogRecPtr lsn ;
891- uint32 xlogid ;
892- uint32 xrecoff ;
893-
894- /* Remove annoying NOTICE messages generated by backend */
895- res = pgut_execute (backup_conn ,"SET client_min_messages = warning;" ,0 ,
896- NULL );
897- PQclear (res );
898-
899- res = pgut_execute (backup_conn ,"SELECT * FROM pg_switch_xlog()" ,
900- 0 ,NULL );
901-
902- /*
903- * Extract timeline and LSN from results of pg_stop_backup()
904- * and friends.
905- */
906- XLogDataFromLSN (PQgetvalue (res ,0 ,0 ),& xlogid ,& xrecoff );
907- /* Calculate LSN */
908- lsn = (XLogRecPtr ) ((uint64 )xlogid <<32 ) |xrecoff ;
909-
910- PQclear (res );
911-
912- /* Wait for returned lsn - 1 in archive folder */
913- wait_archive_lsn (lsn , false);
914- }
915-
916-
917905/*
918906 * Check if node is a standby by looking at the presence of
919907 * recovery.conf.
@@ -957,11 +945,10 @@ backup_cleanup(bool fatal, void *userdata)
957945return ;
958946
959947/* If backup_label exist in $PGDATA, notify stop of backup to PostgreSQL */
960- snprintf (path ,lengthof (path ),"%s/backup_label" ,pgdata );
961- make_native_path (path );
948+ join_path_components (path ,pgdata ,PG_BACKUP_LABEL_FILE );
962949if (fileExists (path ))
963950{
964- elog (LOG ,"backup_label exists, stop backup" );
951+ elog (LOG ,"%s exists, stop backup" , PG_BACKUP_LABEL_FILE );
965952pg_stop_backup (NULL );/* don't care stop_lsn on error case */
966953}
967954
@@ -1240,7 +1227,7 @@ add_pgdata_files(parray *files, const char *root)
12401227relative = file -> path + strlen (root )+ 1 ;
12411228if (!path_is_prefix_of_path ("base" ,relative )&&
12421229/*!path_is_prefix_of_path("global", relative) &&*/ //TODO What's wrong with this line?
1243- !path_is_prefix_of_path ("pg_tblspc" ,relative ))
1230+ !path_is_prefix_of_path (PG_TBLSPC_DIR ,relative ))
12441231continue ;
12451232
12461233/* Get file name from path */
@@ -1508,7 +1495,7 @@ make_pagemap_from_ptrack(parray *files)
15081495}
15091496/* For unix only now */
15101497sscanf (tmp_path ,"%u/%u_ptrack" ,& db_oid ,& rel_oid );
1511- tablespace = strstr (p -> ptrack_path ,"pg_tblspc" );
1498+ tablespace = strstr (p -> ptrack_path ,PG_TBLSPC_DIR );
15121499if (tablespace != NULL )
15131500sscanf (tablespace + 10 ,"%i/" ,& tablespace_oid );
15141501