@@ -1268,6 +1268,7 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_filenode,
12681268 * res ;
12691269 char * params [2 ];
12701270 char * result ;
1271+ char * val ;
12711272
12721273 params [0 ] = palloc (64 );
12731274 params [1 ] = palloc (64 );
@@ -1325,6 +1326,19 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_filenode,
13251326 rel_filenode );
13261327 }
13271328
1329+ val = PQgetvalue (res , 0 , 0 );
1330+
1331+ if (strcmp ("x" , val + 1 ) == 0 )
1332+ {
1333+ /*
1334+ * Ptrack file is missing!
1335+ * TODO COMPARE FILE CHECKSUMM to this file version from previous backup
1336+ * if they are equal, skip this file
1337+ *
1338+ */
1339+ return false;
1340+ }
1341+
13281342 result = (char * ) PQunescapeBytea ((unsigned char * ) PQgetvalue (res , 0 , 0 ),
13291343 result_size );
13301344 PQclear (res );
@@ -2337,12 +2351,12 @@ make_pagemap_from_ptrack(parray *files)
23372351 Oid dbOid_with_ptrack_init = 0 ;
23382352 Oid tblspcOid_with_ptrack_init = 0 ;
23392353 bool ignore_ptrack_for_db = false;
2354+ char * ptrack_nonparsed = NULL ;
2355+ size_t ptrack_nonparsed_size = 0 ;
23402356
23412357 for (i = 0 ; i < parray_num (files ); i ++ )
23422358 {
23432359 pgFile * file = (pgFile * ) parray_get (files , i );
2344- char * ptrack_nonparsed = NULL ;
2345- size_t ptrack_nonparsed_size = 0 ;
23462360 size_t start_addr ;
23472361
23482362 /*
@@ -2374,42 +2388,66 @@ make_pagemap_from_ptrack(parray *files)
23742388
23752389 if (file -> is_datafile )
23762390 {
2391+ if (file -> tblspcOid == tblspcOid_with_ptrack_init
2392+ && file -> dbOid == dbOid_with_ptrack_init )
2393+ {
2394+ /* ignore ptrack */
2395+ Assert (ignore_ptrack_for_db );
2396+ elog (VERBOSE , "Ignoring ptrack because of ptrack_init for file: %s" , file -> path );
2397+ file -> pagemap .bitmapsize = -1 ;
2398+ continue ;
2399+ }
2400+
23772401 /* get ptrack bitmap once for all segments of the file */
23782402 if (file -> segno == 0 )
23792403 {
23802404 /* release previous value */
2381- if (ptrack_nonparsed != NULL )
2382- pg_free ( ptrack_nonparsed ) ;
2405+ pg_free (ptrack_nonparsed );
2406+ ptrack_nonparsed_size = 0 ;
23832407
23842408 ptrack_nonparsed = pg_ptrack_get_and_clear (file -> tblspcOid , file -> dbOid ,
23852409 file -> relOid , & ptrack_nonparsed_size );
23862410 }
23872411
2412+ /* If ptrack file is missing, then copy entire file */
2413+ if (!ptrack_nonparsed )
2414+ {
2415+ elog (VERBOSE , "Ptrack is missing for file: %s" , file -> path );
2416+ file -> pagemap .bitmapsize = -1 ;
2417+ continue ;
2418+ }
2419+
23882420 if (ptrack_nonparsed != NULL )
23892421 {
2390- if (file -> tblspcOid == tblspcOid_with_ptrack_init
2391- && file -> dbOid == dbOid_with_ptrack_init )
2422+ /*
2423+ * TODO When do we cut VARHDR from ptrack_nonparsed?
2424+ * pg_ptrack_get_and_clear returns ptrack with VARHDR cutted out.
2425+ * Compute the beginning of the ptrack map related to this segment
2426+ *
2427+ * HEAPBLOCKS_PER_BYTE. Number of heap pages one ptrack byte can track: 8
2428+ * RELSEG_SIZE. Number of Pages per segment: 131072
2429+ * RELSEG_SIZE/HEAPBLOCKS_PER_BYTE. number of bytes from ptrack file needed
2430+ * to keep track on one relsegment: 16384
2431+ */
2432+ start_addr = (RELSEG_SIZE /HEAPBLOCKS_PER_BYTE )* file -> segno ;
2433+
2434+ if (start_addr + RELSEG_SIZE /HEAPBLOCKS_PER_BYTE > ptrack_nonparsed_size )
23922435 {
2393- /* ignore ptrack */
2394- Assert ( ignore_ptrack_for_db );
2436+ file -> pagemap . bitmapsize = ptrack_nonparsed_size - start_addr ;
2437+ elog ( VERBOSE , "pagemap size: %i" , file -> pagemap . bitmapsize );
23952438 }
2439+
23962440 else
23972441 {
2398- /*
2399- * TODO When do we cut VARHDR from ptrack_nonparsed?
2400- * Compute the beginning of the ptrack map related to this segment
2401- */
2402- start_addr = (RELSEG_SIZE /HEAPBLOCKS_PER_BYTE )* file -> segno ;
2403-
2404- if (start_addr + RELSEG_SIZE /HEAPBLOCKS_PER_BYTE > ptrack_nonparsed_size )
2405- file -> pagemap .bitmapsize = ptrack_nonparsed_size - start_addr ;
2406- else
2407- file -> pagemap .bitmapsize = RELSEG_SIZE /HEAPBLOCKS_PER_BYTE ;
2408-
2409- file -> pagemap .bitmap = pg_malloc (file -> pagemap .bitmapsize );
2410- memcpy (file -> pagemap .bitmap , ptrack_nonparsed + start_addr , file -> pagemap .bitmapsize );
2442+ file -> pagemap .bitmapsize = RELSEG_SIZE /HEAPBLOCKS_PER_BYTE ;
2443+ elog (VERBOSE , "pagemap size: %i" , file -> pagemap .bitmapsize );
24112444 }
2445+
2446+ file -> pagemap .bitmap = pg_malloc (file -> pagemap .bitmapsize );
2447+ memcpy (file -> pagemap .bitmap , ptrack_nonparsed + start_addr , file -> pagemap .bitmapsize );
24122448 }
2449+ else
2450+ elog (ERROR , "Ptrack content should not be empty. File: %s" , file -> path );
24132451 }
24142452 }
24152453}
0 commit comments