@@ -1332,21 +1332,20 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_filenode,
13321332 2 , (const char * * )params );
13331333
13341334 if (PQnfields (res ) != 1 )
1335- elog (ERROR , "cannot get ptrack file from pg_global tablespace and relation oid %u" ,
1335+ elog (ERROR , "cannot get ptrack file from pg_global tablespace and relation oid %u" ,
13361336 rel_filenode );
13371337 }
13381338
13391339 val = PQgetvalue (res , 0 , 0 );
13401340
1341+ /* TODO Now pg_ptrack_get_and_clear() returns bytea ending with \x.
1342+ * It should be fixed in future ptrack releases, but till then we
1343+ * can parse it.
1344+ */
13411345 if (strcmp ("x" , val + 1 ) == 0 )
13421346 {
1343- /*
1344- * Ptrack file is missing!
1345- * TODO COMPARE FILE CHECKSUMM to this file version from previous backup
1346- * if they are equal, skip this file
1347- *
1348- */
1349- return false;
1347+ /* Ptrack file is missing */
1348+ return NULL ;
13501349 }
13511350
13521351 result = (char * ) PQunescapeBytea ((unsigned char * ) PQgetvalue (res , 0 , 0 ),
@@ -2360,7 +2359,6 @@ make_pagemap_from_ptrack(parray *files)
23602359 size_t i ;
23612360 Oid dbOid_with_ptrack_init = 0 ;
23622361 Oid tblspcOid_with_ptrack_init = 0 ;
2363- bool ignore_ptrack_for_db = false;
23642362 char * ptrack_nonparsed = NULL ;
23652363 size_t ptrack_nonparsed_size = 0 ;
23662364
@@ -2376,7 +2374,6 @@ make_pagemap_from_ptrack(parray *files)
23762374 if (file -> is_database )
23772375 {
23782376 char * filename = strrchr (file -> path , '/' );
2379- ignore_ptrack_for_db = false;
23802377
23812378 Assert (filename != NULL );
23822379 filename ++ ;
@@ -2390,7 +2387,6 @@ make_pagemap_from_ptrack(parray *files)
23902387 if ((file -> tblspcOid == GLOBALTABLESPACE_OID ) ||
23912388 pg_ptrack_get_and_clear_db (file -> dbOid , file -> tblspcOid ))
23922389 {
2393- ignore_ptrack_for_db = true;
23942390 dbOid_with_ptrack_init = file -> dbOid ;
23952391 tblspcOid_with_ptrack_init = file -> tblspcOid ;
23962392 }
@@ -2400,13 +2396,12 @@ make_pagemap_from_ptrack(parray *files)
24002396 {
24012397 if (file -> tblspcOid == tblspcOid_with_ptrack_init
24022398 && file -> dbOid == dbOid_with_ptrack_init )
2403- {
2404- /* ignore ptrack */
2405- Assert (ignore_ptrack_for_db );
2406- elog (VERBOSE , "Ignoring ptrack because of ptrack_init for file: %s" , file -> path );
2407- file -> pagemap .bitmapsize = -1 ;
2408- continue ;
2409- }
2399+ {
2400+ /* ignore ptrack if ptrack_init exists */
2401+ elog (VERBOSE , "Ignoring ptrack because of ptrack_init for file: %s" , file -> path );
2402+ file -> pagemap .bitmapsize = PageBitmapIsAbsent ;
2403+ continue ;
2404+ }
24102405
24112406 /* get ptrack bitmap once for all segments of the file */
24122407 if (file -> segno == 0 )
@@ -2419,34 +2414,24 @@ make_pagemap_from_ptrack(parray *files)
24192414 file -> relOid , & ptrack_nonparsed_size );
24202415 }
24212416
2422- /* If ptrack file is missing, then copy entire file */
2423- if (!ptrack_nonparsed )
2424- {
2425- elog (VERBOSE , "Ptrack is missing for file: %s" , file -> path );
2426- file -> pagemap .bitmapsize = -1 ;
2427- continue ;
2428- }
2429-
24302417 if (ptrack_nonparsed != NULL )
24312418 {
24322419 /*
2433- * TODO When do we cut VARHDR from ptrack_nonparsed?
2434- * pg_ptrack_get_and_clear returns ptrack with VARHDR cutted out.
2435- * Compute the beginning of the ptrack map related to this segment
2436- *
2437- * HEAPBLOCKS_PER_BYTE. Number of heap pages one ptrack byte can track: 8
2438- * RELSEG_SIZE. Number of Pages per segment: 131072
2439- * RELSEG_SIZE/HEAPBLOCKS_PER_BYTE. number of bytes from ptrack file needed
2440- * to keep track on one relsegment: 16384
2441- */
2420+ * pg_ptrack_get_and_clear() returns ptrack with VARHDR cutted out.
2421+ * Compute the beginning of the ptrack map related to this segment
2422+ *
2423+ * HEAPBLOCKS_PER_BYTE. Number of heap pages one ptrack byte can track: 8
2424+ * RELSEG_SIZE. Number of Pages per segment: 131072
2425+ * RELSEG_SIZE/HEAPBLOCKS_PER_BYTE. number of bytes in ptrack file needed
2426+ * to keep track on one relsegment: 16384
2427+ */
24422428 start_addr = (RELSEG_SIZE /HEAPBLOCKS_PER_BYTE )* file -> segno ;
24432429
24442430 if (start_addr + RELSEG_SIZE /HEAPBLOCKS_PER_BYTE > ptrack_nonparsed_size )
24452431 {
24462432 file -> pagemap .bitmapsize = ptrack_nonparsed_size - start_addr ;
24472433 elog (VERBOSE , "pagemap size: %i" , file -> pagemap .bitmapsize );
24482434 }
2449-
24502435 else
24512436 {
24522437 file -> pagemap .bitmapsize = RELSEG_SIZE /HEAPBLOCKS_PER_BYTE ;
@@ -2457,7 +2442,18 @@ make_pagemap_from_ptrack(parray *files)
24572442 memcpy (file -> pagemap .bitmap , ptrack_nonparsed + start_addr , file -> pagemap .bitmapsize );
24582443 }
24592444 else
2460- elog (ERROR , "Ptrack content should not be empty. File: %s" , file -> path );
2445+ {
2446+ /*
2447+ * If ptrack file is missing, try to copy the entire file.
2448+ * It can happen in two cases:
2449+ * - files were created by commands that bypass buffer manager
2450+ * and, correspondingly, ptrack mechanism.
2451+ * i.e. CREATE DATABASE
2452+ * - target relation was deleted.
2453+ */
2454+ elog (VERBOSE , "Ptrack is missing for file: %s" , file -> path );
2455+ file -> pagemap .bitmapsize = PageBitmapIsAbsent ;
2456+ }
24612457 }
24622458 }
24632459}
0 commit comments