Skip to content

Commit 372e3d8

Browse files
committed
Add ptrack_get_and_clear function.
1 parent a1843a5 commit 372e3d8

File tree

4 files changed

+90
-3
lines changed

4 files changed

+90
-3
lines changed

src/backend/access/heap/ptrack.c

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
#include "storage/smgr.h"
1616
#include "utils/inval.h"
1717
#include "utils/array.h"
18+
#include "utils/relfilenodemap.h"
1819
#include <unistd.h>
1920

20-
2121
/* Effective data size */
2222
#define MAPSIZE (BLCKSZ - MAXALIGN(SizeOfPageHeaderData))
2323

@@ -252,7 +252,7 @@ ptrack_clear(void)
252252
char *map = PageGetContents(page);
253253
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
254254
START_CRIT_SECTION();
255-
MemSet(map, 0, BLCKSZ-MAXALIGN(SizeOfPageHeaderData));
255+
MemSet(map, 0, MAPSIZE);
256256
MarkBufferDirty(buf);
257257
END_CRIT_SECTION_WITHOUT_TRACK();
258258
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
@@ -270,6 +270,79 @@ ptrack_clear(void)
270270
SetPtrackClearLSN(false);
271271
}
272272

273+
/* Get ptrack file as bytea and clear him */
274+
bytea *
275+
ptrack_get_and_clear(Oid tablespace_oid, Oid table_oid)
276+
{
277+
bytea *result = NULL;
278+
BlockNumber nblock;
279+
if (table_oid == InvalidOid)
280+
{
281+
elog(WARNING, "InvalidOid");
282+
goto full_end;
283+
}
284+
Relation rel = RelationIdGetRelation(RelidByRelfilenode(tablespace_oid,
285+
table_oid));
286+
287+
if (rel == InvalidRelation)
288+
{
289+
elog(WARNING, "InvalidRelation");
290+
goto full_end;
291+
}
292+
293+
RelationOpenSmgr(rel);
294+
if (rel->rd_smgr == NULL)
295+
goto end_rel;
296+
297+
LockSmgrForExtension(rel->rd_smgr, ExclusiveLock);
298+
299+
if (rel->rd_smgr->smgr_ptrack_nblocks == InvalidBlockNumber)
300+
{
301+
if (smgrexists(rel->rd_smgr, PAGESTRACK_FORKNUM))
302+
rel->rd_smgr->smgr_ptrack_nblocks = smgrnblocks(rel->rd_smgr,
303+
PAGESTRACK_FORKNUM);
304+
else
305+
rel->rd_smgr->smgr_ptrack_nblocks = 0;
306+
}
307+
if (rel->rd_smgr->smgr_ptrack_nblocks == 0)
308+
{
309+
UnlockSmgrForExtension(rel->rd_smgr, ExclusiveLock);
310+
goto end_rel;
311+
}
312+
result = (bytea *) palloc(rel->rd_smgr->smgr_ptrack_nblocks*MAPSIZE + VARHDRSZ);
313+
SET_VARSIZE(result, rel->rd_smgr->smgr_ptrack_nblocks*MAPSIZE + VARHDRSZ);
314+
315+
for(nblock = 0; nblock < rel->rd_smgr->smgr_ptrack_nblocks; nblock++)
316+
{
317+
Buffer buf = ReadBufferExtended(rel, PAGESTRACK_FORKNUM,
318+
nblock, RBM_ZERO_ON_ERROR, NULL);
319+
Page page = BufferGetPage(buf);
320+
char *map = PageGetContents(page);
321+
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
322+
START_CRIT_SECTION();
323+
memcpy(VARDATA(result) + nblock*MAPSIZE, map, MAPSIZE);
324+
MemSet(map, 0, MAPSIZE);
325+
MarkBufferDirty(buf);
326+
END_CRIT_SECTION_WITHOUT_TRACK();
327+
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
328+
ReleaseBuffer(buf);
329+
}
330+
331+
UnlockSmgrForExtension(rel->rd_smgr, ExclusiveLock);
332+
end_rel:
333+
RelationClose(rel);
334+
335+
SetPtrackClearLSN(false);
336+
full_end:
337+
if (result == NULL)
338+
{
339+
result = palloc0(VARHDRSZ);
340+
SET_VARSIZE(result, VARHDRSZ);
341+
}
342+
343+
return result;
344+
}
345+
273346
void
274347
SetPtrackClearLSN(bool set_invalid)
275348
{

src/backend/access/transam/xlogfuncs.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,17 @@ pg_ptrack_clear(PG_FUNCTION_ARGS)
115115
PG_RETURN_VOID();
116116
}
117117

118+
Datum
119+
pg_ptrack_get_and_clear(PG_FUNCTION_ARGS)
120+
{
121+
if (!superuser() && !has_rolreplication(GetUserId()))
122+
ereport(ERROR,
123+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
124+
(errmsg("must be superuser or replication role to clear ptrack files"))));
125+
126+
PG_RETURN_BYTEA_P(ptrack_get_and_clear(PG_GETARG_OID(0), PG_GETARG_OID(1)));
127+
}
128+
118129
/*
119130
* pg_switch_xlog: switch to next xlog file
120131
*/

src/include/access/ptrack.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ extern void ptrack_save(void);
1616
extern void ptrack_add_block(BlockNumber block_number, RelFileNode rel);
1717

1818
extern void ptrack_clear(void);
19+
extern bytea *ptrack_get_and_clear(Oid tablespace_oid, Oid table_oid);
1920
extern void assign_ptrack_enable(bool newval, void *extra);
2021

21-
#endif /* VISIBILITYMAP_H */
22+
#endif /* PTRACK_H */

src/include/catalog/pg_proc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3147,6 +3147,8 @@ DATA(insert OID = 6016 ( pg_ptrack_clear PGNSP PGUID 12 1 0 0 0 f f f f t f v 0
31473147
DESCR("clear ptrack fork files");
31483148
DATA(insert OID = 6017 ( pg_ptrack_test PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 2277 "26" _null_ _null_ _null_ _null_ _null_ pg_ptrack_test _null_ _null_ _null_ ));
31493149
DESCR("test ptrack fork relation");
3150+
DATA(insert OID = 6018 ( pg_ptrack_get_and_clear PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 17 "26 26" _null_ _null_ _null_ _null_ _null_ pg_ptrack_get_and_clear _null_ _null_ _null_ ));
3151+
DESCR("get ptrack file as bytea and clear him");
31503152
DATA(insert OID = 3098 ( pg_create_restore_point PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 3220 "25" _null_ _null_ _null_ _null_ _null_ pg_create_restore_point _null_ _null_ _null_ ));
31513153
DESCR("create a named restore point");
31523154
DATA(insert OID = 2849 ( pg_current_xlog_location PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 3220 "" _null_ _null_ _null_ _null_ _null_ pg_current_xlog_location _null_ _null_ _null_ ));

0 commit comments

Comments
 (0)