@@ -65,7 +65,7 @@ static void pg12_recovery_config(pgBackup *backup, bool add_include);
6565
6666static void restore_chain (pgBackup * dest_backup , parray * parent_chain ,
6767 parray * dbOid_exclude_list , pgRestoreParams * params ,
68- const char * pgdata_path );
68+ const char * pgdata_path , bool no_sync );
6969
7070static void * restore_files_new (void * arg );
7171
@@ -118,7 +118,7 @@ set_orphan_status(parray *backups, pgBackup *parent_backup)
118118 */
119119int
120120do_restore_or_validate (time_t target_backup_id , pgRecoveryTarget * rt ,
121- pgRestoreParams * params )
121+ pgRestoreParams * params , bool no_sync )
122122{
123123 int i = 0 ;
124124 int j = 0 ;
@@ -490,14 +490,14 @@ do_restore_or_validate(time_t target_backup_id, pgRecoveryTarget *rt,
490490 dest_backup -> server_version );
491491
492492 restore_chain (dest_backup , parent_chain , dbOid_exclude_list ,
493- params , instance_config .pgdata );
493+ params , instance_config .pgdata , no_sync );
494494
495495 /* Create recovery.conf with given recovery target parameters */
496496 create_recovery_conf (target_backup_id , rt , dest_backup , params );
497497 }
498498
499499 /* cleanup */
500- parray_walk (backups , pgBackupFree ); /* free backup->files */
500+ parray_walk (backups , pgBackupFree ); /* TODO: free backup->files */
501501 parray_free (backups );
502502 parray_free (parent_chain );
503503
@@ -512,7 +512,7 @@ do_restore_or_validate(time_t target_backup_id, pgRecoveryTarget *rt,
512512void
513513restore_chain (pgBackup * dest_backup , parray * parent_chain ,
514514 parray * dbOid_exclude_list , pgRestoreParams * params ,
515- const char * pgdata_path )
515+ const char * pgdata_path , bool no_sync )
516516{
517517 int i ;
518518 char control_file [MAXPGPATH ];
@@ -524,6 +524,7 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
524524 restore_files_arg_new * threads_args ;
525525 bool restore_isok = true;
526526
527+ char pretty_time [20 ];
527528 time_t start_time , end_time ;
528529
529530 /* Preparations for actual restoring */
@@ -637,6 +638,8 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
637638 pg_atomic_clear_flag (& file -> lock );
638639 }
639640
641+ fio_disconnect ();
642+
640643 threads = (pthread_t * ) palloc (sizeof (pthread_t ) * num_threads );
641644 threads_args = (restore_files_arg_new * ) palloc (sizeof (restore_files_arg_new ) *
642645 num_threads );
@@ -674,46 +677,56 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
674677 }
675678
676679 time (& end_time );
680+ pretty_time_interval (difftime (end_time , start_time ),
681+ pretty_time , lengthof (pretty_time ));
677682 if (restore_isok )
678- elog (INFO , "Backup files are restored, time elapsed: %.0f sec" ,
679- difftime (end_time , start_time ));
683+ elog (INFO , "Backup files are restored, time elapsed: %s" , pretty_time );
680684 else
681- elog (ERROR , "Backup files restoring failed, time elapsed: %.0f sec" ,
682- difftime (end_time , start_time ));
685+ elog (ERROR , "Backup files restoring failed, time elapsed: %s" , pretty_time );
683686
687+ if (no_sync )
688+ elog (WARNING , "Restored files are not synced to disk" );
689+ else
690+ {
691+ elog (INFO , "Syncing restored files to disk" );
692+ time (& start_time );
684693
685- elog (INFO , "Sync restored backup files to disk" );
686- time (& start_time );
694+ for (i = 0 ; i < parray_num (dest_files ); i ++ )
695+ {
696+ char to_fullpath [MAXPGPATH ];
697+ pgFile * dest_file = (pgFile * ) parray_get (dest_files , i );
687698
688- for (i = 0 ; i < parray_num (dest_files ); i ++ )
689- {
690- int out ;
691- char to_fullpath [MAXPGPATH ];
692- pgFile * dest_file = (pgFile * ) parray_get (dest_files , i );
693-
694- if (S_ISDIR (dest_file -> mode ) ||
695- dest_file -> external_dir_num > 0 ||
696- (strcmp (PG_TABLESPACE_MAP_FILE , dest_file -> rel_path ) == 0 ) ||
697- (strcmp (DATABASE_MAP , dest_file -> rel_path ) == 0 ))
698- continue ;
699+ if (S_ISDIR (dest_file -> mode ))
700+ continue ;
699701
700- join_path_components (to_fullpath , pgdata_path , dest_file -> rel_path );
702+ if (params -> skip_external_dirs && dest_file -> external_dir_num > 0 )
703+ continue ;
701704
702- /* open destination file */
703- out = fio_open (to_fullpath , O_WRONLY | PG_BINARY , FIO_DB_HOST );
704- if (out < 0 )
705- elog (ERROR , "Cannot open file \"%s\": %s" ,
706- to_fullpath , strerror (errno ));
707-
708- /* sync file */
709- if (fio_flush (out ) != 0 || fio_close (out ) != 0 )
710- elog (ERROR , "Cannot sync file \"%s\": %s" ,
711- to_fullpath , strerror (errno ));
712- }
705+ /* construct fullpath */
706+ if (dest_file -> external_dir_num == 0 )
707+ {
708+ if (strcmp (PG_TABLESPACE_MAP_FILE , dest_file -> rel_path ) == 0 )
709+ continue ;
710+ if (strcmp (DATABASE_MAP , dest_file -> rel_path ) == 0 )
711+ continue ;
712+ join_path_components (to_fullpath , pgdata_path , dest_file -> rel_path );
713+ }
714+ else
715+ {
716+ char * external_path = parray_get (external_dirs , dest_file -> external_dir_num - 1 );
717+ join_path_components (to_fullpath , external_path , dest_file -> rel_path );
718+ }
713719
714- time (& end_time );
715- elog (INFO , "Restored backup files are synced, time elapsed: %.0f sec" ,
716- difftime (end_time , start_time ));
720+ /* TODO: write test for case: file to be synced is missing */
721+ if (fio_sync (to_fullpath , FIO_DB_HOST ) != 0 )
722+ elog (ERROR , "Failed to sync file \"%s\": %s" , to_fullpath , strerror (errno ));
723+ }
724+
725+ time (& end_time );
726+ pretty_time_interval (difftime (end_time , start_time ),
727+ pretty_time , lengthof (pretty_time ));
728+ elog (INFO , "Restored backup files are synced, time elapsed: %s" , pretty_time );
729+ }
717730
718731 /* cleanup */
719732 pfree (threads );
@@ -724,8 +737,6 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
724737
725738 parray_walk (dest_files , pgFileFree );
726739 parray_free (dest_files );
727-
728- // elog(LOG, "Restore of backup %s is completed", base36enc(backup->start_time));
729740}
730741
731742/*
0 commit comments