2
2
*
3
3
* backup.c: backup DB cluster, archived WAL, serverlog.
4
4
*
5
- * Copyright (c) 2009-2010 , NIPPON TELEGRAPH AND TELEPHONE CORPORATION
5
+ * Copyright (c) 2009-2011 , NIPPON TELEGRAPH AND TELEPHONE CORPORATION
6
6
*
7
7
*-------------------------------------------------------------------------
8
8
*/
@@ -41,6 +41,7 @@ static void pg_start_backup(const char *label, bool smooth, pgBackup *backup);
41
41
static void pg_stop_backup (pgBackup * backup );
42
42
static void pg_switch_xlog (pgBackup * backup );
43
43
static void get_lsn (PGresult * res , TimeLineID * timeline , XLogRecPtr * lsn );
44
+ static void get_xid (PGresult * res , uint32 * xid );
44
45
45
46
static void delete_arclog_link (void );
46
47
static void delete_online_wal_backup (void );
@@ -75,8 +76,26 @@ do_backup_database(parray *backup_list, bool smooth_checkpoint)
75
76
XLogRecPtr * lsn = NULL ;
76
77
char prev_file_txt [MAXPGPATH ]; /* path of the previous backup list file */
77
78
78
- if (!HAVE_DATABASE (& current ))
79
- return NULL ;
79
+ if (!HAVE_DATABASE (& current )) {
80
+ /* check if arclog backup. if arclog backup and no suitable full backup, */
81
+ /* take full backup instead. */
82
+ if (HAVE_ARCLOG (& current )) {
83
+ pgBackup * prev_backup ;
84
+
85
+ /* find last completed database backup */
86
+ prev_backup = catalog_get_last_data_backup (backup_list );
87
+ if (prev_backup == NULL )
88
+ {
89
+ elog (ERROR_SYSTEM , _ ("There is indeed a full backup but it is not validated."
90
+ "So I can't take any arclog backup."
91
+ "Please validate it and retry." ));
92
+ /// elog(INFO, _("no previous full backup, performing a full backup instead"));
93
+ /// current.backup_mode = BACKUP_MODE_FULL;
94
+ }
95
+ }
96
+ else
97
+ return NULL ;
98
+ }
80
99
81
100
elog (INFO , _ ("database backup start" ));
82
101
@@ -89,6 +108,16 @@ do_backup_database(parray *backup_list, bool smooth_checkpoint)
89
108
strncat (label , " with pg_rman" , lengthof (label ));
90
109
pg_start_backup (label , smooth_checkpoint , & current );
91
110
111
+ /* If backup_label does not exist in $PGDATA, stop taking backup */
112
+ snprintf (path , lengthof (path ), "%s/backup_label" , pgdata );
113
+ make_native_path (path );
114
+ if (!fileExists (path )) {
115
+ if (verbose )
116
+ printf (_ ("backup_label does not exist, stop backup\n" ));
117
+ pg_stop_backup (NULL );
118
+ elog (ERROR_SYSTEM , _ ("backup_label does not exist in PGDATA." ));
119
+ }
120
+
92
121
/*
93
122
* list directories and symbolic links with the physical path to make
94
123
* mkdirs.sh
@@ -127,10 +156,13 @@ do_backup_database(parray *backup_list, bool smooth_checkpoint)
127
156
128
157
/* find last completed database backup */
129
158
prev_backup = catalog_get_last_data_backup (backup_list );
130
- if (prev_backup == NULL )
159
+ if (prev_backup == NULL || prev_backup -> tli != current . tli )
131
160
{
132
- elog (INFO , _ ("no previous full backup, do a full backup instead" ));
133
- current .backup_mode = BACKUP_MODE_FULL ;
161
+ elog (ERROR_SYSTEM , _ ("There is indeed a full backup but it is not validated."
162
+ "So I can't take any incremental backup."
163
+ "Please validate it and retry." ));
164
+ /// elog(INFO, _("no previous full backup, performing a full backup instead"));
165
+ /// current.backup_mode = BACKUP_MODE_FULL;
134
166
}
135
167
else
136
168
{
@@ -440,7 +472,7 @@ do_backup_arclog(parray *backup_list)
440
472
*/
441
473
prev_backup = catalog_get_last_arclog_backup (backup_list );
442
474
if (verbose && prev_backup == NULL )
443
- printf (_ ("no previous full backup, do a full backup instead\n" ));
475
+ printf (_ ("no previous full backup, performing a full backup instead\n" ));
444
476
445
477
if (prev_backup )
446
478
{
@@ -564,7 +596,7 @@ do_backup_srvlog(parray *backup_list)
564
596
*/
565
597
prev_backup = catalog_get_last_srvlog_backup (backup_list );
566
598
if (verbose && prev_backup == NULL )
567
- printf (_ ("no previous full backup, do a full backup instead\n" ));
599
+ printf (_ ("no previous full backup, performing a full backup instead\n" ));
568
600
569
601
if (prev_backup )
570
602
{
@@ -695,6 +727,8 @@ do_backup(bool smooth_checkpoint,
695
727
current .write_bytes = 0 ; /* write_bytes is valid always */
696
728
current .block_size = BLCKSZ ;
697
729
current .wal_block_size = XLOG_BLCKSZ ;
730
+ current .recovery_xid = 0 ;
731
+ current .recovery_time = (time_t ) 0 ;
698
732
699
733
/* create backup directory and backup.ini */
700
734
if (!check )
@@ -708,6 +742,9 @@ do_backup(bool smooth_checkpoint,
708
742
709
743
/* get list of backups already taken */
710
744
backup_list = catalog_get_backup_list (NULL );
745
+ if (!backup_list ){
746
+ elog (ERROR_SYSTEM , _ ("can't process any more." ));
747
+ }
711
748
712
749
/* set the error processing function for the backup process */
713
750
pgut_atexit_push (backup_cleanup , NULL );
@@ -893,6 +930,12 @@ wait_for_archive(pgBackup *backup, const char *sql)
893
930
elog (LOG , "%s() wait for %s" , __FUNCTION__ , ready_path );
894
931
895
932
PQclear (res );
933
+
934
+ res = execute (TXID_CURRENT_SQL , 0 , NULL );
935
+ if (backup != NULL ){
936
+ get_xid (res , & backup -> recovery_xid );
937
+ backup -> recovery_time = time (NULL );
938
+ }
896
939
disconnect ();
897
940
898
941
/* wait until switched WAL is archived */
@@ -960,6 +1003,26 @@ get_lsn(PGresult *res, TimeLineID *timeline, XLogRecPtr *lsn)
960
1003
lsn -> xrecoff += off_upper << 24 ;
961
1004
}
962
1005
1006
+ /*
1007
+ * Get XID from result of txid_current() after pg_stop_backup().
1008
+ */
1009
+ static void
1010
+ get_xid (PGresult * res , uint32 * xid )
1011
+ {
1012
+ if (res == NULL || PQntuples (res ) != 1 || PQnfields (res ) != 1 )
1013
+ elog (ERROR_PG_COMMAND ,
1014
+ _ ("result of txid_current() is invalid: %s" ),
1015
+ PQerrorMessage (connection ));
1016
+
1017
+ if (sscanf (PQgetvalue (res , 0 , 0 ), "%u" , xid ) != 1 )
1018
+ {
1019
+ elog (ERROR_PG_COMMAND ,
1020
+ _ ("result of txid_current() is invalid: %s" ),
1021
+ PQerrorMessage (connection ));
1022
+ }
1023
+ elog (LOG , "%s():%s" , __FUNCTION__ , PQgetvalue (res , 0 , 0 ));
1024
+ }
1025
+
963
1026
/*
964
1027
* Return true if the path is a existing regular file.
965
1028
*/
@@ -1055,6 +1118,11 @@ backup_files(const char *from_root,
1055
1118
1056
1119
pgFile * file = (pgFile * ) parray_get (files , i );
1057
1120
1121
+ /* If current time is rewinded, abort this backup. */
1122
+ if (tv .tv_sec < file -> mtime ){
1123
+ elog (ERROR_SYSTEM , _ ("current time may be rewound. Please retry with full backup mode." ));
1124
+ }
1125
+
1058
1126
/* check for interrupt */
1059
1127
if (interrupted )
1060
1128
elog (ERROR_INTERRUPTED , _ ("interrupted during backup" ));
@@ -1101,8 +1169,9 @@ backup_files(const char *from_root,
1101
1169
char dirpath [MAXPGPATH ];
1102
1170
1103
1171
join_path_components (dirpath , to_root , JoinPathEnd (file -> path , from_root ));
1104
- if (!check )
1172
+ if (!check ){
1105
1173
dir_create_dir (dirpath , DIR_PERMISSION );
1174
+ }
1106
1175
if (verbose )
1107
1176
printf (_ ("directory\n" ));
1108
1177
}
@@ -1143,7 +1212,7 @@ backup_files(const char *from_root,
1143
1212
prev_file = * p ;
1144
1213
}
1145
1214
1146
- if (prev_file && prev_file -> mtime > = file -> mtime )
1215
+ if (prev_file && prev_file -> mtime = = file -> mtime )
1147
1216
{
1148
1217
/* record as skipped file in file_xxx.txt */
1149
1218
file -> write_size = BYTES_INVALID ;
@@ -1158,7 +1227,8 @@ backup_files(const char *from_root,
1158
1227
* file should contain all modifications at the clock of mtime.
1159
1228
* timer resolution of ext3 file system is one second.
1160
1229
*/
1161
- if (tv .tv_sec <= file -> mtime )
1230
+
1231
+ if (tv .tv_sec == file -> mtime )
1162
1232
{
1163
1233
/* update time and recheck */
1164
1234
gettimeofday (& tv , NULL );
0 commit comments