@@ -130,12 +130,6 @@ static void check_system_identifiers(void);
130130static void confirm_block_size (const char * name , int blcksz );
131131static void set_cfs_datafiles (parray * files , const char * root , char * relative , size_t i );
132132
133- /*
134- * A little optimization used in process_block_change().
135- */
136- static pgFile * last_used_file = NULL ;
137-
138-
139133#define disconnect_and_exit (code ) \
140134 { \
141135 if (conn != NULL) PQfinish(conn); \
@@ -618,6 +612,19 @@ do_backup_instance(void)
618612 else
619613 dir_list_file (backup_files_list , pgdata , true, true, false);
620614
615+ /*
616+ * Sort pathname ascending. It is necessary to create intermediate
617+ * directories sequentially.
618+ *
619+ * For example:
620+ * 1 - create 'base'
621+ * 2 - create 'base/1'
622+ *
623+ * Sorted array is used at least in parse_backup_filelist_filenames(),
624+ * extractPageMap(), make_pagemap_from_ptrack().
625+ */
626+ parray_qsort (backup_files_list , pgFileComparePath );
627+
621628 /* Extract information about files in backup_list parsing their names:*/
622629 parse_backup_filelist_filenames (backup_files_list , pgdata );
623630
@@ -635,9 +642,6 @@ do_backup_instance(void)
635642 */
636643 if (current .backup_mode == BACKUP_MODE_DIFF_PAGE )
637644 {
638- /* Just in case initialize it to NULL */
639- last_used_file = NULL ;
640-
641645 /*
642646 * Build the page map. Obtain information about changed pages
643647 * reading WAL segments present in archives up to the point
@@ -651,26 +655,16 @@ do_backup_instance(void)
651655 */
652656 !current .from_replica , backup_files_list );
653657 }
654-
655- if (current .backup_mode == BACKUP_MODE_DIFF_PTRACK )
658+ else if (current .backup_mode == BACKUP_MODE_DIFF_PTRACK )
656659 {
657- parray_qsort (backup_files_list , pgFileComparePath );
660+ /*
661+ * Build the page map from ptrack information.
662+ */
658663 make_pagemap_from_ptrack (backup_files_list );
659664 }
660665
661666 /*
662- * Sort pathname ascending. It is necessary to create intermediate
663- * directories sequentially.
664- *
665- * For example:
666- * 1 - create 'base'
667- * 2 - create 'base/1'
668- */
669- parray_qsort (backup_files_list , pgFileComparePath );
670-
671- /*
672- * Make directories before backup
673- * and setup threads at the same time
667+ * Make directories before backup and setup threads at the same time
674668 */
675669 for (i = 0 ; i < parray_num (backup_files_list ); i ++ )
676670 {
@@ -771,12 +765,14 @@ do_backup_instance(void)
771765 for (i = 0 ; i < parray_num (xlog_files_list ); i ++ )
772766 {
773767 pgFile * file = (pgFile * ) parray_get (xlog_files_list , i );
768+
774769 if (S_ISREG (file -> mode ))
775770 calc_file_checksum (file );
776771 /* Remove file path root prefix*/
777772 if (strstr (file -> path , database_path ) == file -> path )
778773 {
779774 char * ptr = file -> path ;
775+
780776 file -> path = pstrdup (GetRelativePath (ptr , database_path ));
781777 free (ptr );
782778 }
@@ -2300,27 +2296,6 @@ write_backup_file_list(parray *files, const char *root)
23002296 elog (ERROR , "cannot write file list \"%s\": %s" , path , strerror (errno ));
23012297}
23022298
2303- /*
2304- * A helper function to create the path of a relation file and segment.
2305- * The returned path is palloc'd
2306- */
2307- static char *
2308- datasegpath (RelFileNode rnode , ForkNumber forknum , BlockNumber segno )
2309- {
2310- char * path ;
2311- char * segpath ;
2312-
2313- path = relpathperm (rnode , forknum );
2314- if (segno > 0 )
2315- {
2316- segpath = psprintf ("%s.%u" , path , segno );
2317- pfree (path );
2318- return segpath ;
2319- }
2320- else
2321- return path ;
2322- }
2323-
23242299/*
23252300 * Find pgfile by given rnode in the backup_files_list
23262301 * and add given blkno to its pagemap.
@@ -2332,36 +2307,24 @@ process_block_change(ForkNumber forknum, RelFileNode rnode, BlockNumber blkno)
23322307 char * rel_path ;
23332308 BlockNumber blkno_inseg ;
23342309 int segno ;
2335- pgFile * file_item = NULL ;
2336- int j ;
2310+ pgFile * * file_item ;
2311+ pgFile f ;
23372312
23382313 segno = blkno / RELSEG_SIZE ;
23392314 blkno_inseg = blkno % RELSEG_SIZE ;
23402315
2341- rel_path = datasegpath (rnode , forknum , segno );
2342- path = pg_malloc (strlen (rel_path ) + strlen (pgdata ) + 2 );
2343- sprintf (path , "%s/%s" , pgdata , rel_path );
2344-
2345- /*
2346- * Little optimization in case if we need the same file as in the previoius
2347- * call.
2348- */
2349- if (last_used_file && strcmp (last_used_file -> path , path ) == 0 )
2350- file_item = last_used_file ;
2316+ rel_path = relpathperm (rnode , forknum );
2317+ if (segno > 0 )
2318+ path = psprintf ("%s/%s.%u" , pgdata , rel_path , segno );
23512319 else
2352- {
2353- for (j = 0 ; j < parray_num (backup_files_list ); j ++ )
2354- {
2355- pgFile * p = (pgFile * ) parray_get (backup_files_list , j );
2320+ path = psprintf ("%s/%s" , pgdata , rel_path );
23562321
2357- if (strcmp (p -> path , path ) == 0 )
2358- {
2359- file_item = p ;
2360- last_used_file = p ;
2361- break ;
2362- }
2363- }
2364- }
2322+ pg_free (rel_path );
2323+
2324+ f .path = path ;
2325+ /* backup_files_list should be sorted before */
2326+ file_item = (pgFile * * ) parray_bsearch (backup_files_list , & f ,
2327+ pgFileComparePath );
23652328
23662329 /*
23672330 * If we don't have any record of this file in the file map, it means
@@ -2370,10 +2333,9 @@ process_block_change(ForkNumber forknum, RelFileNode rnode, BlockNumber blkno)
23702333 * backup would simply copy it as-is.
23712334 */
23722335 if (file_item )
2373- datapagemap_add (& file_item -> pagemap , blkno_inseg );
2336+ datapagemap_add (& ( * file_item ) -> pagemap , blkno_inseg );
23742337
23752338 pg_free (path );
2376- pg_free (rel_path );
23772339}
23782340
23792341/*
0 commit comments