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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy