@@ -1332,21 +1332,20 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_filenode,
1332
1332
2 , (const char * * )params );
1333
1333
1334
1334
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" ,
1336
1336
rel_filenode );
1337
1337
}
1338
1338
1339
1339
val = PQgetvalue (res , 0 , 0 );
1340
1340
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
+ */
1341
1345
if (strcmp ("x" , val + 1 ) == 0 )
1342
1346
{
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 ;
1350
1349
}
1351
1350
1352
1351
result = (char * ) PQunescapeBytea ((unsigned char * ) PQgetvalue (res , 0 , 0 ),
@@ -2360,7 +2359,6 @@ make_pagemap_from_ptrack(parray *files)
2360
2359
size_t i ;
2361
2360
Oid dbOid_with_ptrack_init = 0 ;
2362
2361
Oid tblspcOid_with_ptrack_init = 0 ;
2363
- bool ignore_ptrack_for_db = false;
2364
2362
char * ptrack_nonparsed = NULL ;
2365
2363
size_t ptrack_nonparsed_size = 0 ;
2366
2364
@@ -2376,7 +2374,6 @@ make_pagemap_from_ptrack(parray *files)
2376
2374
if (file -> is_database )
2377
2375
{
2378
2376
char * filename = strrchr (file -> path , '/' );
2379
- ignore_ptrack_for_db = false;
2380
2377
2381
2378
Assert (filename != NULL );
2382
2379
filename ++ ;
@@ -2390,7 +2387,6 @@ make_pagemap_from_ptrack(parray *files)
2390
2387
if ((file -> tblspcOid == GLOBALTABLESPACE_OID ) ||
2391
2388
pg_ptrack_get_and_clear_db (file -> dbOid , file -> tblspcOid ))
2392
2389
{
2393
- ignore_ptrack_for_db = true;
2394
2390
dbOid_with_ptrack_init = file -> dbOid ;
2395
2391
tblspcOid_with_ptrack_init = file -> tblspcOid ;
2396
2392
}
@@ -2400,13 +2396,12 @@ make_pagemap_from_ptrack(parray *files)
2400
2396
{
2401
2397
if (file -> tblspcOid == tblspcOid_with_ptrack_init
2402
2398
&& 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
+ }
2410
2405
2411
2406
/* get ptrack bitmap once for all segments of the file */
2412
2407
if (file -> segno == 0 )
@@ -2419,34 +2414,24 @@ make_pagemap_from_ptrack(parray *files)
2419
2414
file -> relOid , & ptrack_nonparsed_size );
2420
2415
}
2421
2416
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
-
2430
2417
if (ptrack_nonparsed != NULL )
2431
2418
{
2432
2419
/*
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
+ */
2442
2428
start_addr = (RELSEG_SIZE /HEAPBLOCKS_PER_BYTE )* file -> segno ;
2443
2429
2444
2430
if (start_addr + RELSEG_SIZE /HEAPBLOCKS_PER_BYTE > ptrack_nonparsed_size )
2445
2431
{
2446
2432
file -> pagemap .bitmapsize = ptrack_nonparsed_size - start_addr ;
2447
2433
elog (VERBOSE , "pagemap size: %i" , file -> pagemap .bitmapsize );
2448
2434
}
2449
-
2450
2435
else
2451
2436
{
2452
2437
file -> pagemap .bitmapsize = RELSEG_SIZE /HEAPBLOCKS_PER_BYTE ;
@@ -2457,7 +2442,18 @@ make_pagemap_from_ptrack(parray *files)
2457
2442
memcpy (file -> pagemap .bitmap , ptrack_nonparsed + start_addr , file -> pagemap .bitmapsize );
2458
2443
}
2459
2444
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
+ }
2461
2457
}
2462
2458
}
2463
2459
}
0 commit comments