@@ -131,7 +131,6 @@ do_merge(time_t backup_id)
131
131
{
132
132
pgBackup * from_backup = (pgBackup * ) parray_get (backups , i - 1 );
133
133
134
- full_backup = (pgBackup * ) parray_get (backups , i );
135
134
merge_backups (full_backup , from_backup );
136
135
}
137
136
@@ -168,8 +167,6 @@ merge_backups(pgBackup *to_backup, pgBackup *from_backup)
168
167
merge_files_arg * threads_args = NULL ;
169
168
int i ;
170
169
bool merge_isok = true;
171
- int64 to_data_bytes ,
172
- to_wal_bytes ;
173
170
174
171
elog (INFO , "Merging backup %s with backup %s" , from_backup_id , to_backup_id );
175
172
@@ -283,29 +280,37 @@ merge_backups(pgBackup *to_backup, pgBackup *from_backup)
283
280
* Update to_backup metadata.
284
281
*/
285
282
to_backup -> status = BACKUP_STATUS_OK ;
283
+ to_backup -> parent_backup = INVALID_BACKUP_ID ;
284
+ to_backup -> start_lsn = from_backup -> start_lsn ;
285
+ to_backup -> stop_lsn = from_backup -> stop_lsn ;
286
+ to_backup -> recovery_time = from_backup -> recovery_time ;
287
+ to_backup -> recovery_xid = from_backup -> recovery_xid ;
288
+ /*
289
+ * If one of the backups isn't "stream" backup then the target backup become
290
+ * non-stream backup too.
291
+ */
292
+ to_backup -> stream = to_backup -> stream && from_backup -> stream ;
286
293
/* Compute summary of size of regular files in the backup */
287
- to_data_bytes = 0 ;
294
+ to_backup -> data_bytes = 0 ;
288
295
for (i = 0 ; i < parray_num (files ); i ++ )
289
296
{
290
297
pgFile * file = (pgFile * ) parray_get (files , i );
291
298
292
299
if (S_ISDIR (file -> mode ))
293
- to_data_bytes += 4096 ;
300
+ to_backup -> data_bytes += 4096 ;
294
301
/* Count the amount of the data actually copied */
295
302
else if (S_ISREG (file -> mode ))
296
- to_data_bytes += file -> write_size ;
303
+ to_backup -> data_bytes += file -> write_size ;
297
304
}
298
305
/* compute size of wal files of this backup stored in the archive */
299
306
if (!to_backup -> stream )
300
- to_wal_bytes = instance_config .xlog_seg_size *
307
+ to_backup -> wal_bytes = instance_config .xlog_seg_size *
301
308
(to_backup -> stop_lsn / instance_config .xlog_seg_size -
302
309
to_backup -> start_lsn / instance_config .xlog_seg_size + 1 );
303
310
else
304
- to_wal_bytes = BYTES_INVALID ;
311
+ to_backup -> wal_bytes = BYTES_INVALID ;
305
312
306
313
write_backup_filelist (to_backup , files , from_database_path );
307
- to_backup -> data_bytes = to_data_bytes ;
308
- to_backup -> wal_bytes = to_wal_bytes ;
309
314
write_backup (to_backup );
310
315
311
316
delete_source_backup :
@@ -330,27 +335,6 @@ merge_backups(pgBackup *to_backup, pgBackup *from_backup)
330
335
}
331
336
}
332
337
333
- /*
334
- * Rename FULL backup directory.
335
- */
336
- elog (INFO , "Rename %s to %s" , to_backup_id , from_backup_id );
337
- if (rename (to_backup_path , from_backup_path ) == -1 )
338
- elog (ERROR , "Could not rename directory \"%s\" to \"%s\": %s" ,
339
- to_backup_path , from_backup_path , strerror (errno ));
340
-
341
- /*
342
- * Merging finished, now we can safely update ID of the destination backup.
343
- */
344
- pgBackupCopy (to_backup , from_backup );
345
- /* Correct metadata */
346
- to_backup -> backup_mode = BACKUP_MODE_FULL ;
347
- to_backup -> status = BACKUP_STATUS_OK ;
348
- to_backup -> parent_backup = INVALID_BACKUP_ID ;
349
- /* Restore sizes */
350
- to_backup -> data_bytes = to_data_bytes ;
351
- to_backup -> wal_bytes = to_wal_bytes ;
352
- write_backup (to_backup );
353
-
354
338
/* Cleanup */
355
339
if (threads )
356
340
{
@@ -384,6 +368,8 @@ merge_files(void *arg)
384
368
for (i = 0 ; i < num_files ; i ++ )
385
369
{
386
370
pgFile * file = (pgFile * ) parray_get (argument -> files , i );
371
+ pgFile * to_file ;
372
+ pgFile * * res_file ;
387
373
388
374
if (!pg_atomic_test_set_flag (& file -> lock ))
389
375
continue ;
@@ -392,17 +378,24 @@ merge_files(void *arg)
392
378
if (interrupted )
393
379
elog (ERROR , "Interrupted during merging backups" );
394
380
381
+ /* Directories were created before */
382
+ if (S_ISDIR (file -> mode ))
383
+ continue ;
384
+
395
385
if (progress )
396
386
elog (INFO , "Progress: (%d/%d). Process file \"%s\"" ,
397
387
i + 1 , num_files , file -> path );
398
388
389
+ res_file = parray_bsearch (argument -> to_files , file ,
390
+ pgFileComparePathDesc );
391
+ to_file = (res_file ) ? * res_file : NULL ;
392
+
399
393
/*
400
394
* Skip files which haven't changed since previous backup. But in case
401
395
* of DELTA backup we should consider n_blocks to truncate the target
402
396
* backup.
403
397
*/
404
- if (file -> write_size == BYTES_INVALID &&
405
- file -> n_blocks == -1 )
398
+ if (file -> write_size == BYTES_INVALID && file -> n_blocks == -1 )
406
399
{
407
400
elog (VERBOSE , "Skip merging file \"%s\", the file didn't change" ,
408
401
file -> path );
@@ -411,27 +404,16 @@ merge_files(void *arg)
411
404
* If the file wasn't changed in PAGE backup, retreive its
412
405
* write_size from previous FULL backup.
413
406
*/
414
- if (S_ISREG ( file -> mode ) )
407
+ if (to_file )
415
408
{
416
- pgFile * * res_file ;
417
-
418
- res_file = parray_bsearch (argument -> to_files , file ,
419
- pgFileComparePathDesc );
420
- if (res_file && * res_file )
421
- {
422
- file -> compress_alg = (* res_file )-> compress_alg ;
423
- file -> write_size = (* res_file )-> write_size ;
424
- file -> crc = (* res_file )-> crc ;
425
- }
409
+ file -> compress_alg = to_file -> compress_alg ;
410
+ file -> write_size = to_file -> write_size ;
411
+ file -> crc = to_file -> crc ;
426
412
}
427
413
428
414
continue ;
429
415
}
430
416
431
- /* Directories were created before */
432
- if (S_ISDIR (file -> mode ))
433
- continue ;
434
-
435
417
/*
436
418
* Move the file. We need to decompress it and compress again if
437
419
* necessary.
@@ -447,7 +429,7 @@ merge_files(void *arg)
447
429
file -> path + to_root_len + 1 );
448
430
449
431
/*
450
- * We need more complicate algorithm if target file exists and it is
432
+ * We need more complicate algorithm if target file should be
451
433
* compressed.
452
434
*/
453
435
if (to_backup -> compress_alg == PGLZ_COMPRESS ||
@@ -462,33 +444,36 @@ merge_files(void *arg)
462
444
463
445
/*
464
446
* Merge files:
465
- * - decompress first file
466
- * - decompress second file and merge with first decompressed file
447
+ * - if target file exists restore and decompress it to the temp
448
+ * path
449
+ * - decompress source file if necessary and merge it with the
450
+ * target decompressed file
467
451
* - compress result file
468
452
*/
469
453
470
- elog (VERBOSE , "File is compressed, decompress to the temporary file \"%s\"" ,
471
- tmp_file_path );
472
-
473
- prev_path = file -> path ;
474
454
/*
475
- * We need to decompress target file only if it exists.
455
+ * We need to decompress target file if it exists.
476
456
*/
477
- if (fileExists ( to_path_tmp ) )
457
+ if (to_file )
478
458
{
459
+ elog (VERBOSE , "Merge target and source files into the temporary path \"%s\"" ,
460
+ tmp_file_path );
461
+
479
462
/*
480
463
* file->path points to the file in from_root directory. But we
481
464
* need the file in directory to_root.
482
465
*/
483
- file -> path = to_path_tmp ;
484
-
485
- /* Decompress first/ target file */
486
- restore_data_file (tmp_file_path , file , false, false,
466
+ prev_path = to_file -> path ;
467
+ to_file -> path = to_path_tmp ;
468
+ /* Decompress target file into temporary one */
469
+ restore_data_file (tmp_file_path , to_file , false, false,
487
470
parse_program_version (to_backup -> program_version ));
488
-
489
- file -> path = prev_path ;
471
+ to_file -> path = prev_path ;
490
472
}
491
- /* Merge second/source file with first/target file */
473
+ else
474
+ elog (VERBOSE , "Restore source file into the temporary path \"%s\"" ,
475
+ tmp_file_path );
476
+ /* Merge source file with target file */
492
477
restore_data_file (tmp_file_path , file ,
493
478
from_backup -> backup_mode == BACKUP_MODE_DIFF_DELTA ,
494
479
false,
@@ -497,7 +482,8 @@ merge_files(void *arg)
497
482
elog (VERBOSE , "Compress file and save it to the directory \"%s\"" ,
498
483
argument -> to_root );
499
484
500
- /* Again we need change path */
485
+ /* Again we need to change path */
486
+ prev_path = file -> path ;
501
487
file -> path = tmp_file_path ;
502
488
/* backup_data_file() requires file size to calculate nblocks */
503
489
file -> size = pgFileSize (file -> path );
0 commit comments