@@ -53,6 +53,13 @@ static int is_ptrack_enable = false;
5353/* Backup connection */
5454static PGconn * backup_conn = NULL ;
5555
56+ /* PostgreSQL server version from "backup_conn" */
57+ static int server_version = 0 ;
58+
59+ static bool exclusive_backup = false;
60+ /* Is pg_start_backup() was executed */
61+ static bool backup_in_progress = false;
62+
5663typedef struct
5764{
5865const char * from_root ;
@@ -159,7 +166,7 @@ do_backup_database(parray *backup_list)
159166 * If backup_label does not exist in $PGDATA, stop taking backup.
160167 * NOTE. We can check it only on master, though.
161168 */
162- if (! from_replica )
169+ if ( exclusive_backup )
163170{
164171char label_path [MAXPGPATH ];
165172join_path_components (label_path ,pgdata ,PG_BACKUP_LABEL_FILE );
@@ -399,13 +406,15 @@ do_backup(void)
399406backup_conn = pgut_connect (pgut_dbname );
400407pgut_atexit_push (backup_disconnect ,NULL );
401408
402- /* Confirm that this server version is supported */
403- check_server_version ();
404409/* Confirm data block size and xlog block size are compatible */
405410confirm_block_size ("block_size" ,BLCKSZ );
406411confirm_block_size ("wal_block_size" ,XLOG_BLCKSZ );
407412
408413from_replica = pg_is_in_recovery ();
414+
415+ /* Confirm that this server version is supported */
416+ check_server_version ();
417+
409418current .checksum_version = get_data_checksum_version (true);
410419current .stream = stream_wal ;
411420
@@ -489,7 +498,6 @@ do_backup(void)
489498static void
490499check_server_version (void )
491500{
492- static int server_version = 0 ;
493501/* confirm server version */
494502server_version = PQserverVersion (backup_conn );
495503
@@ -506,6 +514,9 @@ check_server_version(void)
506514server_version /10000 ,
507515 (server_version /100 ) %100 ,
508516server_version %100 ,"9.6" );
517+
518+ /* Do exclusive backup only for PostgreSQL 9.5 */
519+ exclusive_backup = server_version < 90600 ;
509520}
510521
511522/*
@@ -581,7 +592,7 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
581592
582593/* 2nd argument is 'fast'*/
583594params [1 ]= smooth ?"false" :"true" ;
584- if (from_replica )
595+ if (! exclusive_backup )
585596res = pgut_execute (backup_conn ,
586597"SELECT pg_start_backup($1, $2, false)" ,
5875982 ,
@@ -592,6 +603,8 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
5926032 ,
593604params );
594605
606+ backup_in_progress = true;
607+
595608/* Extract timeline and LSN from results of pg_start_backup() */
596609XLogDataFromLSN (PQgetvalue (res ,0 ,0 ),& xlogid ,& xrecoff );
597610/* Calculate LSN */
@@ -629,13 +642,13 @@ pg_switch_wal(void)
629642NULL );
630643PQclear (res );
631644
632- # ifPG_VERSION_NUM >=100000
633- res = pgut_execute (backup_conn ,"SELECT * FROM pg_switch_wal()" ,0 ,
634- NULL );
635- # else
636- res = pgut_execute (backup_conn ,"SELECT * FROM pg_switch_xlog()" ,0 ,
637- NULL );
638- #endif
645+ if ( server_version >=100000 )
646+ res = pgut_execute (backup_conn ,"SELECT * FROM pg_switch_wal()" ,0 ,
647+ NULL );
648+ else
649+ res = pgut_execute (backup_conn ,"SELECT * FROM pg_switch_xlog()" ,0 ,
650+ NULL );
651+
639652PQclear (res );
640653}
641654
@@ -891,12 +904,15 @@ pg_stop_backup(pgBackup *backup)
891904time_t recovery_time ;
892905TransactionId recovery_xid ;
893906
907+ if (!backup_in_progress )
908+ elog (FATAL ,"backup is not in progress" );
909+
894910/* Remove annoying NOTICE messages generated by backend */
895911res = pgut_execute (backup_conn ,"SET client_min_messages = warning;" ,
8969120 ,NULL );
897913PQclear (res );
898914
899- if (from_replica )
915+ if (! exclusive_backup )
900916/*
901917 * Stop the non-exclusive backup. Besides stop_lsn it returns from
902918 * pg_stop_backup(false) copy of the backup label and tablespace map
@@ -914,13 +930,15 @@ pg_stop_backup(pgBackup *backup)
914930" FROM pg_stop_backup()" ,
9159310 ,NULL );
916932
933+ backup_in_progress = false;
934+
917935/* Extract timeline and LSN from results of pg_stop_backup() */
918936XLogDataFromLSN (PQgetvalue (res ,0 ,0 ),& xlogid ,& xrecoff );
919937/* Calculate LSN */
920938stop_backup_lsn = (XLogRecPtr ) ((uint64 )xlogid <<32 ) |xrecoff ;
921939
922940/* Write backup_label and tablespace_map for backup from replica */
923- if (from_replica )
941+ if (! exclusive_backup )
924942{
925943char path [MAXPGPATH ];
926944char backup_label [MAXPGPATH ];
@@ -1081,8 +1099,6 @@ fileExists(const char *path)
10811099static void
10821100backup_cleanup (bool fatal ,void * userdata )
10831101{
1084- char path [MAXPGPATH ];
1085-
10861102/*
10871103 * Update status of backup in BACKUP_CONTROL_FILE to ERROR.
10881104 * end_time != 0 means backup finished
@@ -1096,13 +1112,11 @@ backup_cleanup(bool fatal, void *userdata)
10961112}
10971113
10981114/*
1099- * If backup_label exists in $PGDATA, notify stop of backup to PostgreSQL
1100- * TODO Do we need this?
1115+ * If backup is in progress, notify stop of backup to PostgreSQL
11011116 */
1102- join_path_components (path ,pgdata ,PG_BACKUP_LABEL_FILE );
1103- if (fileExists (path ))
1117+ if (backup_in_progress )
11041118{
1105- elog (LOG ,"%s exists , stop backup" , PG_BACKUP_LABEL_FILE );
1119+ elog (LOG ,"backup in progress , stop backup" );
11061120pg_stop_backup (NULL );/* don't care stop_lsn on error case */
11071121}
11081122}