@@ -53,6 +53,13 @@ static int is_ptrack_enable = false;
53
53
/* Backup connection */
54
54
static PGconn * backup_conn = NULL ;
55
55
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
+
56
63
typedef struct
57
64
{
58
65
const char * from_root ;
@@ -159,7 +166,7 @@ do_backup_database(parray *backup_list)
159
166
* If backup_label does not exist in $PGDATA, stop taking backup.
160
167
* NOTE. We can check it only on master, though.
161
168
*/
162
- if (! from_replica )
169
+ if ( exclusive_backup )
163
170
{
164
171
char label_path [MAXPGPATH ];
165
172
join_path_components (label_path , pgdata , PG_BACKUP_LABEL_FILE );
@@ -399,13 +406,15 @@ do_backup(void)
399
406
backup_conn = pgut_connect (pgut_dbname );
400
407
pgut_atexit_push (backup_disconnect , NULL );
401
408
402
- /* Confirm that this server version is supported */
403
- check_server_version ();
404
409
/* Confirm data block size and xlog block size are compatible */
405
410
confirm_block_size ("block_size" , BLCKSZ );
406
411
confirm_block_size ("wal_block_size" , XLOG_BLCKSZ );
407
412
408
413
from_replica = pg_is_in_recovery ();
414
+
415
+ /* Confirm that this server version is supported */
416
+ check_server_version ();
417
+
409
418
current .checksum_version = get_data_checksum_version (true);
410
419
current .stream = stream_wal ;
411
420
@@ -489,7 +498,6 @@ do_backup(void)
489
498
static void
490
499
check_server_version (void )
491
500
{
492
- static int server_version = 0 ;
493
501
/* confirm server version */
494
502
server_version = PQserverVersion (backup_conn );
495
503
@@ -506,6 +514,9 @@ check_server_version(void)
506
514
server_version / 10000 ,
507
515
(server_version / 100 ) % 100 ,
508
516
server_version % 100 , "9.6" );
517
+
518
+ /* Do exclusive backup only for PostgreSQL 9.5 */
519
+ exclusive_backup = server_version < 90600 ;
509
520
}
510
521
511
522
/*
@@ -581,7 +592,7 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
581
592
582
593
/* 2nd argument is 'fast'*/
583
594
params [1 ] = smooth ? "false" : "true" ;
584
- if (from_replica )
595
+ if (! exclusive_backup )
585
596
res = pgut_execute (backup_conn ,
586
597
"SELECT pg_start_backup($1, $2, false)" ,
587
598
2 ,
@@ -592,6 +603,8 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
592
603
2 ,
593
604
params );
594
605
606
+ backup_in_progress = true;
607
+
595
608
/* Extract timeline and LSN from results of pg_start_backup() */
596
609
XLogDataFromLSN (PQgetvalue (res , 0 , 0 ), & xlogid , & xrecoff );
597
610
/* Calculate LSN */
@@ -629,13 +642,13 @@ pg_switch_wal(void)
629
642
NULL );
630
643
PQclear (res );
631
644
632
- # if PG_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
+
639
652
PQclear (res );
640
653
}
641
654
@@ -891,12 +904,15 @@ pg_stop_backup(pgBackup *backup)
891
904
time_t recovery_time ;
892
905
TransactionId recovery_xid ;
893
906
907
+ if (!backup_in_progress )
908
+ elog (FATAL , "backup is not in progress" );
909
+
894
910
/* Remove annoying NOTICE messages generated by backend */
895
911
res = pgut_execute (backup_conn , "SET client_min_messages = warning;" ,
896
912
0 , NULL );
897
913
PQclear (res );
898
914
899
- if (from_replica )
915
+ if (! exclusive_backup )
900
916
/*
901
917
* Stop the non-exclusive backup. Besides stop_lsn it returns from
902
918
* pg_stop_backup(false) copy of the backup label and tablespace map
@@ -914,13 +930,15 @@ pg_stop_backup(pgBackup *backup)
914
930
" FROM pg_stop_backup()" ,
915
931
0 , NULL );
916
932
933
+ backup_in_progress = false;
934
+
917
935
/* Extract timeline and LSN from results of pg_stop_backup() */
918
936
XLogDataFromLSN (PQgetvalue (res , 0 , 0 ), & xlogid , & xrecoff );
919
937
/* Calculate LSN */
920
938
stop_backup_lsn = (XLogRecPtr ) ((uint64 ) xlogid << 32 ) | xrecoff ;
921
939
922
940
/* Write backup_label and tablespace_map for backup from replica */
923
- if (from_replica )
941
+ if (! exclusive_backup )
924
942
{
925
943
char path [MAXPGPATH ];
926
944
char backup_label [MAXPGPATH ];
@@ -1081,8 +1099,6 @@ fileExists(const char *path)
1081
1099
static void
1082
1100
backup_cleanup (bool fatal , void * userdata )
1083
1101
{
1084
- char path [MAXPGPATH ];
1085
-
1086
1102
/*
1087
1103
* Update status of backup in BACKUP_CONTROL_FILE to ERROR.
1088
1104
* end_time != 0 means backup finished
@@ -1096,13 +1112,11 @@ backup_cleanup(bool fatal, void *userdata)
1096
1112
}
1097
1113
1098
1114
/*
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
1101
1116
*/
1102
- join_path_components (path , pgdata , PG_BACKUP_LABEL_FILE );
1103
- if (fileExists (path ))
1117
+ if (backup_in_progress )
1104
1118
{
1105
- elog (LOG , "%s exists , stop backup" , PG_BACKUP_LABEL_FILE );
1119
+ elog (LOG , "backup in progress , stop backup" );
1106
1120
pg_stop_backup (NULL ); /* don't care stop_lsn on error case */
1107
1121
}
1108
1122
}
0 commit comments