@@ -77,7 +77,8 @@ do_merge(time_t backup_id)
7777 {
7878 if (backup -> status != BACKUP_STATUS_OK &&
7979 /* It is possible that previous merging was interrupted */
80- backup -> status != BACKUP_STATUS_MERGING )
80+ backup -> status != BACKUP_STATUS_MERGING &&
81+ backup -> status != BACKUP_STATUS_DELETING )
8182 elog (ERROR , "Backup %s has status: %s" ,
8283 base36enc (backup -> start_time ), status2str (backup -> status ));
8384
@@ -164,7 +165,14 @@ merge_backups(pgBackup *to_backup, pgBackup *from_backup)
164165 int i ;
165166 bool merge_isok = true;
166167
167- elog (LOG , "Merging backup %s with backup %s" , from_backup_id , to_backup_id );
168+ elog (INFO , "Merging backup %s with backup %s" , from_backup_id , to_backup_id );
169+
170+ /*
171+ * Previous merging was interrupted during deleting source backup. It is
172+ * safe just to delete it again.
173+ */
174+ if (from_backup -> status == BACKUP_STATUS_DELETING )
175+ goto delete_source_backup ;
168176
169177 to_backup -> status = BACKUP_STATUS_MERGING ;
170178 write_backup_status (to_backup );
@@ -244,37 +252,38 @@ merge_backups(pgBackup *to_backup, pgBackup *from_backup)
244252 elog (ERROR , "Data files merging failed" );
245253
246254 /*
247- * Files were copied into to_backup and deleted from from_backup. Remove
248- * remaining directories from from_backup.
255+ * Update to_backup metadata.
249256 */
250- parray_qsort (files , pgFileComparePathDesc );
257+ to_backup -> status = BACKUP_STATUS_OK ;
258+ /* Compute summary of size of regular files in the backup */
259+ to_backup -> data_bytes = 0 ;
251260 for (i = 0 ; i < parray_num (files ); i ++ )
252261 {
253262 pgFile * file = (pgFile * ) parray_get (files , i );
254263
255- if (!S_ISDIR (file -> mode ))
256- continue ;
257-
258- if (rmdir (file -> path ))
259- elog (ERROR , "Could not remove directory \"%s\": %s" ,
260- file -> path , strerror (errno ));
264+ if (S_ISDIR (file -> mode ))
265+ to_backup -> data_bytes += 4096 ;
266+ /* Count the amount of the data actually copied */
267+ else if (S_ISREG (file -> mode ))
268+ to_backup -> data_bytes += file -> write_size ;
261269 }
262- if (rmdir (from_database_path ))
263- elog (ERROR , "Could not remove directory \"%s\": %s" ,
264- from_database_path , strerror (errno ));
265- if (unlink (control_file ))
266- elog (ERROR , "Could not remove file \"%s\": %s" ,
267- control_file , strerror (errno ));
270+ /* compute size of wal files of this backup stored in the archive */
271+ if (!to_backup -> stream )
272+ to_backup -> wal_bytes = xlog_seg_size *
273+ (to_backup -> stop_lsn / xlog_seg_size -
274+ to_backup -> start_lsn / xlog_seg_size + 1 );
275+ else
276+ to_backup -> wal_bytes = BYTES_INVALID ;
268277
269- pgBackupGetPath (from_backup , control_file , lengthof (control_file ),
270- BACKUP_CONTROL_FILE );
271- if (unlink (control_file ))
272- elog (ERROR , "Could not remove file \"%s\": %s" ,
273- control_file , strerror (errno ));
278+ write_backup_filelist (to_backup , files , from_database_path );
279+ write_backup (to_backup );
274280
275- if (rmdir (from_backup_path ))
276- elog (ERROR , "Could not remove directory \"%s\": %s" ,
277- from_backup_path , strerror (errno ));
281+ delete_source_backup :
282+ /*
283+ * Files were copied into to_backup. It is time to remove source backup
284+ * entirely.
285+ */
286+ delete_backup_files (from_backup );
278287
279288 /*
280289 * Delete files which are not in from_backup file list.
@@ -286,7 +295,7 @@ merge_backups(pgBackup *to_backup, pgBackup *from_backup)
286295 if (parray_bsearch (files , file , pgFileComparePathDesc ) == NULL )
287296 {
288297 pgFileDelete (file );
289- elog (LOG , "Deleted \"%s\"" , file -> path );
298+ elog (VERBOSE , "Deleted \"%s\"" , file -> path );
290299 }
291300 }
292301
@@ -298,34 +307,14 @@ merge_backups(pgBackup *to_backup, pgBackup *from_backup)
298307 to_backup_path , from_backup_path , strerror (errno ));
299308
300309 /*
301- * Update to_backup metadata .
310+ * Merging finished, now we can safely update ID of the destination backup .
302311 */
303312 pgBackupCopy (to_backup , from_backup );
313+ elog (INFO , "to_backup: %s" , base36enc (to_backup -> start_time ));
304314 /* Correct metadata */
305315 to_backup -> backup_mode = BACKUP_MODE_FULL ;
306316 to_backup -> status = BACKUP_STATUS_OK ;
307317 to_backup -> parent_backup = INVALID_BACKUP_ID ;
308- /* Compute summary of size of regular files in the backup */
309- to_backup -> data_bytes = 0 ;
310- for (i = 0 ; i < parray_num (files ); i ++ )
311- {
312- pgFile * file = (pgFile * ) parray_get (files , i );
313-
314- if (S_ISDIR (file -> mode ))
315- to_backup -> data_bytes += 4096 ;
316- /* Count the amount of the data actually copied */
317- else if (S_ISREG (file -> mode ))
318- to_backup -> data_bytes += file -> write_size ;
319- }
320- /* compute size of wal files of this backup stored in the archive */
321- if (!to_backup -> stream )
322- to_backup -> wal_bytes = xlog_seg_size *
323- (to_backup -> stop_lsn / xlog_seg_size -
324- to_backup -> start_lsn / xlog_seg_size + 1 );
325- else
326- to_backup -> wal_bytes = BYTES_INVALID ;
327-
328- pgBackupWriteFileList (to_backup , files , from_database_path );
329318 write_backup (to_backup );
330319
331320 /* Cleanup */
@@ -508,10 +497,9 @@ merge_files(void *arg)
508497 file -> write_size = pgFileSize (to_path_tmp );
509498 file -> crc = pgFileGetCRC (to_path_tmp , false);
510499 }
511- pgFileDelete (file );
512500 }
513501 else
514- move_file (argument -> from_root , argument -> to_root , file );
502+ copy_file (argument -> from_root , argument -> to_root , file );
515503
516504 if (file -> write_size != BYTES_INVALID )
517505 elog (LOG , "Moved file \"%s\": " INT64_FORMAT " bytes" ,
0 commit comments