speedup_truncate_forks_fujii.patch
application/octet-stream
Filename: speedup_truncate_forks_fujii.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| contrib/pg_visibility/pg_visibility.c | 0 | 0 |
| sindex 3cc886f7fe..b8c9b6f9c6 100644 | 0 | 0 |
| sindex 5b5a80e890..b50c69b438 100644 | 0 | 0 |
diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c
index 1372bb638f..75b6d96440 100644
*** a/contrib/pg_visibility/pg_visibility.c
--- b/contrib/pg_visibility/pg_visibility.c
***************
*** 383,388 **** pg_truncate_visibility_map(PG_FUNCTION_ARGS)
--- 383,390 ----
{
Oid relid = PG_GETARG_OID(0);
Relation rel;
+ ForkNumber fork;
+ BlockNumber block;
rel = relation_open(relid, AccessExclusiveLock);
***************
*** 392,398 **** pg_truncate_visibility_map(PG_FUNCTION_ARGS)
RelationOpenSmgr(rel);
rel->rd_smgr->smgr_vm_nblocks = InvalidBlockNumber;
! visibilitymap_truncate(rel, 0);
if (RelationNeedsWAL(rel))
{
--- 394,405 ----
RelationOpenSmgr(rel);
rel->rd_smgr->smgr_vm_nblocks = InvalidBlockNumber;
! block = visibilitymap_prepare_truncate(rel, 0);
! if (BlockNumberIsValid(block))
! {
! fork = VISIBILITYMAP_FORKNUM;
! smgrtruncate(rel->rd_smgr, &fork, 1, &block);
! }
if (RelationNeedsWAL(rel))
{
***************
*** 418,424 **** pg_truncate_visibility_map(PG_FUNCTION_ARGS)
* here and when we sent the messages at our eventual commit. However,
* we're currently only sending a non-transactional smgr invalidation,
* which will have been posted to shared memory immediately from within
! * visibilitymap_truncate. Therefore, there should be no race here.
*
* The reason why it's desirable to release the lock early here is because
* of the possibility that someone will need to use this to blow away many
--- 425,431 ----
* here and when we sent the messages at our eventual commit. However,
* we're currently only sending a non-transactional smgr invalidation,
* which will have been posted to shared memory immediately from within
! * smgr_truncate. Therefore, there should be no race here.
*
* The reason why it's desirable to release the lock early here is because
* of the possibility that someone will need to use this to blow away many
diff --git a/src/backend/access/heap/visibilindex a08922b079..262876772f 100644
*** a/src/backend/access/heap/visibilitymap.c
--- b/src/backend/access/heap/visibilitymap.c
***************
*** 17,23 ****
* visibilitymap_set - set a bit in a previously pinned page
* visibilitymap_get_status - get status of bits
* visibilitymap_count - count number of bits set in visibility map
! * visibilitymap_truncate - truncate the visibility map
*
* NOTES
*
--- 17,24 ----
* visibilitymap_set - set a bit in a previously pinned page
* visibilitymap_get_status - get status of bits
* visibilitymap_count - count number of bits set in visibility map
! * visibilitymap_prepare_truncate -
! * prepare for truncation of the visibility map
*
* NOTES
*
***************
*** 430,445 **** visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_fro
}
/*
! * visibilitymap_truncate - truncate the visibility map
! *
! * The caller must hold AccessExclusiveLock on the relation, to ensure that
! * other backends receive the smgr invalidation event that this function sends
! * before they access the VM again.
*
* nheapblocks is the new size of the heap.
*/
! void
! visibilitymap_truncate(Relation rel, BlockNumber nheapblocks)
{
BlockNumber newnblocks;
--- 431,448 ----
}
/*
! * visibilitymap_prepare_truncate -
! * prepare for truncation of the visibility map
*
* nheapblocks is the new size of the heap.
+ *
+ * Return the number of blocks of new visibility map after it's truncated.
+ * If it's InvalidBlockNumber, there is nothing to truncate;
+ * otherwise the caller is responsible for calling smgrtruncate()
+ * to truncate the visibility map pages.
*/
! BlockNumber
! visibilitymap_prepare_truncate(Relation rel, BlockNumber nheapblocks)
{
BlockNumber newnblocks;
***************
*** 459,465 **** visibilitymap_truncate(Relation rel, BlockNumber nheapblocks)
* nothing to truncate.
*/
if (!smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM))
! return;
/*
* Unless the new size is exactly at a visibility map page boundary, the
--- 462,468 ----
* nothing to truncate.
*/
if (!smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM))
! return InvalidBlockNumber;
/*
* Unless the new size is exactly at a visibility map page boundary, the
***************
*** 480,486 **** visibilitymap_truncate(Relation rel, BlockNumber nheapblocks)
if (!BufferIsValid(mapBuffer))
{
/* nothing to do, the file was already smaller */
! return;
}
page = BufferGetPage(mapBuffer);
--- 483,489 ----
if (!BufferIsValid(mapBuffer))
{
/* nothing to do, the file was already smaller */
! return InvalidBlockNumber;
}
page = BufferGetPage(mapBuffer);
***************
*** 528,547 **** visibilitymap_truncate(Relation rel, BlockNumber nheapblocks)
if (smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM) <= newnblocks)
{
/* nothing to do, the file was already smaller than requested size */
! return;
}
! /* Truncate the unused VM pages, and send smgr inval message */
! smgrtruncate(rel->rd_smgr, VISIBILITYMAP_FORKNUM, newnblocks);
!
! /*
! * We might as well update the local smgr_vm_nblocks setting. smgrtruncate
! * sent an smgr cache inval message, which will cause other backends to
! * invalidate their copy of smgr_vm_nblocks, and this one too at the next
! * command boundary. But this ensures it isn't outright wrong until then.
! */
! if (rel->rd_smgr)
! rel->rd_smgr->smgr_vm_nblocks = newnblocks;
}
/*
--- 531,540 ----
if (smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM) <= newnblocks)
{
/* nothing to do, the file was already smaller than requested size */
! return InvalidBlockNumber;
}
! return newnblocks;
}
/*
diff --git a/src/backend/catalog/storage.c b/sindex 3cc886f7fe..b8c9b6f9c6 100644
*** a/src/backend/catalog/storage.c
--- b/src/backend/catalog/storage.c
***************
*** 231,236 **** RelationTruncate(Relation rel, BlockNumber nblocks)
--- 231,240 ----
{
bool fsm;
bool vm;
+ bool need_fsm_vacuum = false;
+ ForkNumber forks[MAX_FORKNUM];
+ BlockNumber blocks[MAX_FORKNUM];
+ int nforks = 0;
/* Open it at the smgr level if not already done */
RelationOpenSmgr(rel);
***************
*** 242,256 **** RelationTruncate(Relation rel, BlockNumber nblocks)
rel->rd_smgr->smgr_fsm_nblocks = InvalidBlockNumber;
rel->rd_smgr->smgr_vm_nblocks = InvalidBlockNumber;
! /* Truncate the FSM first if it exists */
fsm = smgrexists(rel->rd_smgr, FSM_FORKNUM);
if (fsm)
! FreeSpaceMapTruncateRel(rel, nblocks);
! /* Truncate the visibility map too if it exists. */
vm = smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM);
if (vm)
! visibilitymap_truncate(rel, nblocks);
/*
* We WAL-log the truncation before actually truncating, which means
--- 246,280 ----
rel->rd_smgr->smgr_fsm_nblocks = InvalidBlockNumber;
rel->rd_smgr->smgr_vm_nblocks = InvalidBlockNumber;
! /* Prepare for truncation of MAIN fork of the relation */
! forks[nforks] = MAIN_FORKNUM;
! blocks[nforks] = nblocks;
! nforks++;
!
! /* Prepare for truncation of the FSM if it exists */
fsm = smgrexists(rel->rd_smgr, FSM_FORKNUM);
if (fsm)
! {
! blocks[nforks] = FreeSpaceMapPrepareTruncateRel(rel, nblocks);
! if (BlockNumberIsValid(blocks[nforks]))
! {
! forks[nforks] = FSM_FORKNUM;
! nforks++;
! need_fsm_vacuum = true;
! }
! }
! /* Prepare for truncation of the visibility map too if it exists */
vm = smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM);
if (vm)
! {
! blocks[nforks] = visibilitymap_prepare_truncate(rel, nblocks);
! if (BlockNumberIsValid(blocks[nforks]))
! {
! forks[nforks] = VISIBILITYMAP_FORKNUM;
! nforks++;
! }
! }
/*
* We WAL-log the truncation before actually truncating, which means
***************
*** 290,297 **** RelationTruncate(Relation rel, BlockNumber nblocks)
XLogFlush(lsn);
}
! /* Do the real work */
! smgrtruncate(rel->rd_smgr, MAIN_FORKNUM, nblocks);
}
/*
--- 314,329 ----
XLogFlush(lsn);
}
! /* Do the real work to truncate relation forks */
! smgrtruncate(rel->rd_smgr, forks, nforks, blocks);
!
! /*
! * Update upper-level FSM pages to account for the truncation.
! * This is important because the just-truncated pages were likely
! * marked as all-free, and would be preferentially selected.
! */
! if (need_fsm_vacuum)
! FreeSpaceMapVacuumRange(rel, nblocks, InvalidBlockNumber);
}
/*
***************
*** 588,593 **** smgr_redo(XLogReaderState *record)
--- 620,629 ----
xl_smgr_truncate *xlrec = (xl_smgr_truncate *) XLogRecGetData(record);
SMgrRelation reln;
Relation rel;
+ ForkNumber forks[MAX_FORKNUM];
+ BlockNumber blocks[MAX_FORKNUM];
+ int nforks = 0;
+ bool need_fsm_vacuum = false;
reln = smgropen(xlrec->rnode, InvalidBackendId);
***************
*** 616,638 **** smgr_redo(XLogReaderState *record)
*/
XLogFlush(lsn);
if ((xlrec->flags & SMGR_TRUNCATE_HEAP) != 0)
{
! smgrtruncate(reln, MAIN_FORKNUM, xlrec->blkno);
/* Also tell xlogutils.c about it */
XLogTruncateRelation(xlrec->rnode, MAIN_FORKNUM, xlrec->blkno);
}
! /* Truncate FSM and VM too */
rel = CreateFakeRelcacheEntry(xlrec->rnode);
if ((xlrec->flags & SMGR_TRUNCATE_FSM) != 0 &&
smgrexists(reln, FSM_FORKNUM))
! FreeSpaceMapTruncateRel(rel, xlrec->blkno);
if ((xlrec->flags & SMGR_TRUNCATE_VM) != 0 &&
smgrexists(reln, VISIBILITYMAP_FORKNUM))
! visibilitymap_truncate(rel, xlrec->blkno);
FreeFakeRelcacheEntry(rel);
}
--- 652,705 ----
*/
XLogFlush(lsn);
+ /* Prepare for truncation of MAIN fork */
if ((xlrec->flags & SMGR_TRUNCATE_HEAP) != 0)
{
! forks[nforks] = MAIN_FORKNUM;
! blocks[nforks] = xlrec->blkno;
! nforks++;
/* Also tell xlogutils.c about it */
XLogTruncateRelation(xlrec->rnode, MAIN_FORKNUM, xlrec->blkno);
}
! /* Prepare for truncation of FSM and VM too */
rel = CreateFakeRelcacheEntry(xlrec->rnode);
if ((xlrec->flags & SMGR_TRUNCATE_FSM) != 0 &&
smgrexists(reln, FSM_FORKNUM))
! {
! blocks[nforks] = FreeSpaceMapPrepareTruncateRel(rel, xlrec->blkno);
! if (BlockNumberIsValid(blocks[nforks]))
! {
! forks[nforks] = FSM_FORKNUM;
! nforks++;
! need_fsm_vacuum = true;
! }
! }
if ((xlrec->flags & SMGR_TRUNCATE_VM) != 0 &&
smgrexists(reln, VISIBILITYMAP_FORKNUM))
! {
! blocks[nforks] = visibilitymap_prepare_truncate(rel, xlrec->blkno);
! if (BlockNumberIsValid(blocks[nforks]))
! {
! forks[nforks] = VISIBILITYMAP_FORKNUM;
! nforks++;
! }
! }
!
! /* Do the real work to truncate relation forks */
! if (nforks > 0)
! smgrtruncate(reln, forks, nforks, blocks);
!
! /*
! * Update upper-level FSM pages to account for the truncation.
! * This is important because the just-truncated pages were likely
! * marked as all-free, and would be preferentially selected.
! */
! if (need_fsm_vacuum)
! FreeSpaceMapVacuumRange(rel, xlrec->blkno,
! InvalidBlockNumber);
FreeFakeRelcacheEntry(rel);
}
diff --git a/src/backend/storage/bufindex 6f3a402854..483f705305 100644
*** a/src/backend/storage/buffer/bufmgr.c
--- b/src/backend/storage/buffer/bufmgr.c
***************
*** 2901,2907 **** BufferGetLSNAtomic(Buffer buffer)
* DropRelFileNodeBuffers
*
* This function removes from the buffer pool all the pages of the
! * specified relation fork that have block numbers >= firstDelBlock.
* (In particular, with firstDelBlock = 0, all pages are removed.)
* Dirty pages are simply dropped, without bothering to write them
* out first. Therefore, this is NOT rollback-able, and so should be
--- 2901,2907 ----
* DropRelFileNodeBuffers
*
* This function removes from the buffer pool all the pages of the
! * specified relation forks that have block numbers >= firstDelBlock.
* (In particular, with firstDelBlock = 0, all pages are removed.)
* Dirty pages are simply dropped, without bothering to write them
* out first. Therefore, this is NOT rollback-able, and so should be
***************
*** 2924,2939 **** BufferGetLSNAtomic(Buffer buffer)
* --------------------------------------------------------------------
*/
void
! DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum,
! BlockNumber firstDelBlock)
{
int i;
/* If it's a local relation, it's localbuf.c's problem. */
if (RelFileNodeBackendIsTemp(rnode))
{
if (rnode.backend == MyBackendId)
! DropRelFileNodeLocalBuffers(rnode.node, forkNum, firstDelBlock);
return;
}
--- 2924,2944 ----
* --------------------------------------------------------------------
*/
void
! DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber *forkNum,
! int nforks, BlockNumber *firstDelBlock)
{
int i;
+ int j;
/* If it's a local relation, it's localbuf.c's problem. */
if (RelFileNodeBackendIsTemp(rnode))
{
if (rnode.backend == MyBackendId)
! {
! for (j = 0; j < nforks; j++)
! DropRelFileNodeLocalBuffers(rnode.node, forkNum[j],
! firstDelBlock[j]);
! }
return;
}
***************
*** 2962,2972 **** DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum,
continue;
buf_state = LockBufHdr(bufHdr);
! if (RelFileNodeEquals(bufHdr->tag.rnode, rnode.node) &&
! bufHdr->tag.forkNum == forkNum &&
! bufHdr->tag.blockNum >= firstDelBlock)
! InvalidateBuffer(bufHdr); /* releases spinlock */
! else
UnlockBufHdr(bufHdr, buf_state);
}
}
--- 2967,2984 ----
continue;
buf_state = LockBufHdr(bufHdr);
!
! for (j = 0; j < nforks; j++)
! {
! if (RelFileNodeEquals(bufHdr->tag.rnode, rnode.node) &&
! bufHdr->tag.forkNum == forkNum[j] &&
! bufHdr->tag.blockNum >= firstDelBlock[j])
! {
! InvalidateBuffer(bufHdr); /* releases spinlock */
! break;
! }
! }
! if (j >= nforks)
UnlockBufHdr(bufHdr, buf_state);
}
}
diff --git a/src/backend/storage/freespaceindex 2383094cfd..b7a048c96c 100644
*** a/src/backend/storage/freespace/freespace.c
--- b/src/backend/storage/freespace/freespace.c
***************
*** 247,262 **** GetRecordedFreeSpace(Relation rel, BlockNumber heapBlk)
}
/*
! * FreeSpaceMapTruncateRel - adjust for truncation of a relation.
! *
! * The caller must hold AccessExclusiveLock on the relation, to ensure that
! * other backends receive the smgr invalidation event that this function sends
! * before they access the FSM again.
*
* nblocks is the new size of the heap.
*/
! void
! FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks)
{
BlockNumber new_nfsmblocks;
FSMAddress first_removed_address;
--- 247,264 ----
}
/*
! * FreeSpaceMapPrepareTruncateRel - prepare for truncation of a relation.
*
* nblocks is the new size of the heap.
+ *
+ * Return the number of blocks of new FSM after it's truncated.
+ * If it's InvalidBlockNumber, there is nothing to truncate;
+ * otherwise the caller is responsible for calling smgrtruncate()
+ * to truncate the FSM pages, and FreeSpaceMapVacuumRange()
+ * to update upper-level pages in the FSM.
*/
! BlockNumber
! FreeSpaceMapPrepareTruncateRel(Relation rel, BlockNumber nblocks)
{
BlockNumber new_nfsmblocks;
FSMAddress first_removed_address;
***************
*** 270,276 **** FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks)
* truncate.
*/
if (!smgrexists(rel->rd_smgr, FSM_FORKNUM))
! return;
/* Get the location in the FSM of the first removed heap block */
first_removed_address = fsm_get_location(nblocks, &first_removed_slot);
--- 272,278 ----
* truncate.
*/
if (!smgrexists(rel->rd_smgr, FSM_FORKNUM))
! return InvalidBlockNumber;
/* Get the location in the FSM of the first removed heap block */
first_removed_address = fsm_get_location(nblocks, &first_removed_slot);
***************
*** 285,291 **** FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks)
{
buf = fsm_readbuf(rel, first_removed_address, false);
if (!BufferIsValid(buf))
! return; /* nothing to do; the FSM was already smaller */
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
/* NO EREPORT(ERROR) from here till changes are logged */
--- 287,293 ----
{
buf = fsm_readbuf(rel, first_removed_address, false);
if (!BufferIsValid(buf))
! return InvalidBlockNumber; /* nothing to do; the FSM was already smaller */
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
/* NO EREPORT(ERROR) from here till changes are logged */
***************
*** 315,342 **** FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks)
{
new_nfsmblocks = fsm_logical_to_physical(first_removed_address);
if (smgrnblocks(rel->rd_smgr, FSM_FORKNUM) <= new_nfsmblocks)
! return; /* nothing to do; the FSM was already smaller */
}
! /* Truncate the unused FSM pages, and send smgr inval message */
! smgrtruncate(rel->rd_smgr, FSM_FORKNUM, new_nfsmblocks);
!
! /*
! * We might as well update the local smgr_fsm_nblocks setting.
! * smgrtruncate sent an smgr cache inval message, which will cause other
! * backends to invalidate their copy of smgr_fsm_nblocks, and this one too
! * at the next command boundary. But this ensures it isn't outright wrong
! * until then.
! */
! if (rel->rd_smgr)
! rel->rd_smgr->smgr_fsm_nblocks = new_nfsmblocks;
!
! /*
! * Update upper-level FSM pages to account for the truncation. This is
! * important because the just-truncated pages were likely marked as
! * all-free, and would be preferentially selected.
! */
! FreeSpaceMapVacuumRange(rel, nblocks, InvalidBlockNumber);
}
/*
--- 317,326 ----
{
new_nfsmblocks = fsm_logical_to_physical(first_removed_address);
if (smgrnblocks(rel->rd_smgr, FSM_FORKNUM) <= new_nfsmblocks)
! return InvalidBlockNumber; /* nothing to do; the FSM was already smaller */
}
! return new_nfsmblocks;
}
/*
diff --git a/src/backend/storage/smgr/smgr.c b/sindex 5b5a80e890..b50c69b438 100644
*** a/src/backend/storage/smgr/smgr.c
--- b/src/backend/storage/smgr/smgr.c
***************
*** 469,474 **** smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo)
--- 469,475 ----
pfree(rnodes);
}
+
/*
* smgrextend() -- Add a new block to a file.
*
***************
*** 557,575 **** smgrnblocks(SMgrRelation reln, ForkNumber forknum)
}
/*
! * smgrtruncate() -- Truncate supplied relation to the specified number
! * of blocks
*
* The truncation is done immediately, so this can't be rolled back.
*/
void
! smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks)
{
/*
* Get rid of any buffers for the about-to-be-deleted blocks. bufmgr will
* just drop them without bothering to write the contents.
*/
! DropRelFileNodeBuffers(reln->smgr_rnode, forknum, nblocks);
/*
* Send a shared-inval message to force other backends to close any smgr
--- 558,582 ----
}
/*
! * smgrtruncate() -- Truncate the given forks of supplied relation to
! * each specified numbers of blocks
*
* The truncation is done immediately, so this can't be rolled back.
+ *
+ * The caller must hold AccessExclusiveLock on the relation, to ensure that
+ * other backends receive the smgr invalidation event that this function sends
+ * before they access any forks of the relation again.
*/
void
! smgrtruncate(SMgrRelation reln, ForkNumber *forknum, int nforks, BlockNumber *nblocks)
{
+ int i;
+
/*
* Get rid of any buffers for the about-to-be-deleted blocks. bufmgr will
* just drop them without bothering to write the contents.
*/
! DropRelFileNodeBuffers(reln->smgr_rnode, forknum, nforks, nblocks);
/*
* Send a shared-inval message to force other backends to close any smgr
***************
*** 583,592 **** smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks)
*/
CacheInvalidateSmgr(reln->smgr_rnode);
! /*
! * Do the truncation.
! */
! smgrsw[reln->smgr_which].smgr_truncate(reln, forknum, nblocks);
}
/*
--- 590,613 ----
*/
CacheInvalidateSmgr(reln->smgr_rnode);
! /* Do the truncation */
! for (i = 0; i < nforks; i++)
! {
! smgrsw[reln->smgr_which].smgr_truncate(reln, forknum[i], nblocks[i]);
!
! /*
! * We might as well update the local smgr_fsm_nblocks and
! * smgr_vm_nblocks settings. The smgr cache inval message that
! * this function sent will cause other backends to invalidate
! * their copies of smgr_fsm_nblocks and smgr_vm_nblocks,
! * and these ones too at the next command boundary.
! * But these ensure they aren't outright wrong until then.
! */
! if (forknum[i] == FSM_FORKNUM)
! reln->smgr_fsm_nblocks = nblocks[i];
! if (forknum[i] == VISIBILITYMAP_FORKNUM)
! reln->smgr_vm_nblocks = nblocks[i];
! }
}
/*
diff --git a/src/include/access/visibiindex 2d8804351a..0532b04e34 100644
*** a/src/include/access/visibilitymap.h
--- b/src/include/access/visibilitymap.h
***************
*** 44,49 **** extern void visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf,
uint8 flags);
extern uint8 visibilitymap_get_status(Relation rel, BlockNumber heapBlk, Buffer *vmbuf);
extern void visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_frozen);
! extern void visibilitymap_truncate(Relation rel, BlockNumber nheapblocks);
#endif /* VISIBILITYMAP_H */
--- 44,50 ----
uint8 flags);
extern uint8 visibilitymap_get_status(Relation rel, BlockNumber heapBlk, Buffer *vmbuf);
extern void visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_frozen);
! extern BlockNumber visibilitymap_prepare_truncate(Relation rel,
! BlockNumber nheapblocks);
#endif /* VISIBILITYMAP_H */
diff --git a/src/include/storage/bufmgr.hindex 509f4b7ef1..17b97f7e38 100644
*** a/src/include/storage/bufmgr.h
--- b/src/include/storage/bufmgr.h
***************
*** 190,197 **** extern BlockNumber RelationGetNumberOfBlocksInFork(Relation relation,
extern void FlushOneBuffer(Buffer buffer);
extern void FlushRelationBuffers(Relation rel);
extern void FlushDatabaseBuffers(Oid dbid);
! extern void DropRelFileNodeBuffers(RelFileNodeBackend rnode,
! ForkNumber forkNum, BlockNumber firstDelBlock);
extern void DropRelFileNodesAllBuffers(RelFileNodeBackend *rnodes, int nnodes);
extern void DropDatabaseBuffers(Oid dbid);
--- 190,197 ----
extern void FlushOneBuffer(Buffer buffer);
extern void FlushRelationBuffers(Relation rel);
extern void FlushDatabaseBuffers(Oid dbid);
! extern void DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber *forkNum,
! int nforks, BlockNumber *firstDelBlock);
extern void DropRelFileNodesAllBuffers(RelFileNodeBackend *rnodes, int nnodes);
extern void DropDatabaseBuffers(Oid dbid);
diff --git a/src/include/storage/frindex 8d8c465d7b..b75f6fe946 100644
*** a/src/include/storage/freespace.h
--- b/src/include/storage/freespace.h
***************
*** 30,36 **** extern void RecordPageWithFreeSpace(Relation rel, BlockNumber heapBlk,
extern void XLogRecordPageWithFreeSpace(RelFileNode rnode, BlockNumber heapBlk,
Size spaceAvail);
! extern void FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks);
extern void FreeSpaceMapVacuum(Relation rel);
extern void FreeSpaceMapVacuumRange(Relation rel, BlockNumber start,
BlockNumber end);
--- 30,37 ----
extern void XLogRecordPageWithFreeSpace(RelFileNode rnode, BlockNumber heapBlk,
Size spaceAvail);
! extern BlockNumber FreeSpaceMapPrepareTruncateRel(Relation rel,
! BlockNumber nblocks);
extern void FreeSpaceMapVacuum(Relation rel);
extern void FreeSpaceMapVacuumRange(Relation rel, BlockNumber start,
BlockNumber end);
diff --git a/src/include/storage/smgr.index 7393727a4b..1543d8d870 100644
*** a/src/include/storage/smgr.h
--- b/src/include/storage/smgr.h
***************
*** 101,108 **** extern void smgrwrite(SMgrRelation reln, ForkNumber forknum,
extern void smgrwriteback(SMgrRelation reln, ForkNumber forknum,
BlockNumber blocknum, BlockNumber nblocks);
extern BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum);
! extern void smgrtruncate(SMgrRelation reln, ForkNumber forknum,
! BlockNumber nblocks);
extern void smgrimmedsync(SMgrRelation reln, ForkNumber forknum);
extern void AtEOXact_SMgr(void);
--- 101,108 ----
extern void smgrwriteback(SMgrRelation reln, ForkNumber forknum,
BlockNumber blocknum, BlockNumber nblocks);
extern BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum);
! extern void smgrtruncate(SMgrRelation reln, ForkNumber *forknum,
! int nforks, BlockNumber *nblocks);
extern void smgrimmedsync(SMgrRelation reln, ForkNumber forknum);
extern void AtEOXact_SMgr(void);