Skip to content

Commit 22cb8c6

Browse files
committed
PGPRO-1148 fix; ptrack fix for multiple segments and _ptrack missing cases
1 parent 39aa89a commit 22cb8c6

File tree

2 files changed

+61
-22
lines changed

2 files changed

+61
-22
lines changed

src/backup.c

Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

src/data.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ backup_data_file(const char *from_root, const char *to_root,
301301
* There are no changed blocks since last backup. We want make
302302
* incremental backup, so we should exit.
303303
*/
304+
elog(VERBOSE, "Skipping file because it didn`t changed: %s", file->path);
304305
return false;
305306
}
306307

@@ -357,7 +358,7 @@ backup_data_file(const char *from_root, const char *to_root,
357358
* Read each page, verify checksum and write it to backup.
358359
* If page map is empty backup all pages of the relation.
359360
*/
360-
if (file->pagemap.bitmapsize == 0)
361+
if (file->pagemap.bitmapsize == 0 || file->pagemap.bitmapsize == -1)
361362
{
362363
for (blknum = 0; blknum < nblocks; blknum++)
363364
{

0 commit comments

Comments
 (0)