0002-v1-Add-bool-param-in-arg-of-smgrextend-for-cached-block.patch
application/octet-stream
Filename: 0002-v1-Add-bool-param-in-arg-of-smgrextend-for-cached-block.patch
Type: application/octet-stream
Part: 1
Patch
Format: format-patch
Series: patch v1-0002
Subject: Add bool param in arg of smgrextend for cached blocks
| File | + | − |
|---|---|---|
| src/backend/access/gist/gistbuild.c | 3 | 1 |
| src/backend/access/heap/visibilitymap.c | 6 | 3 |
| src/backend/access/table/tableam.c | 3 | 2 |
| src/backend/access/transam/xlogutils.c | 2 | 1 |
| src/backend/catalog/storage.c | 4 | 2 |
| src/backend/storage/buffer/bufmgr.c | 8 | 4 |
| src/backend/storage/freespace/freespace.c | 6 | 3 |
| src/backend/storage/smgr/smgr.c | 18 | 1 |
| src/include/storage/smgr.h | 2 | 1 |
From cec0f764901cf33ba66dca40eb2efa5f475076fb Mon Sep 17 00:00:00 2001
From: Kirk Jamison <k.jamison@jp.fujitsu.com>
Date: Wed, 7 Oct 2020 09:57:53 +0000
Subject: [PATCH 2/3] Add bool param in arg of smgrextend for cached blocks
---
src/backend/access/gist/gistbuild.c | 4 +++-
src/backend/access/heap/visibilitymap.c | 9 ++++++---
src/backend/access/table/tableam.c | 5 +++--
src/backend/access/transam/xlogutils.c | 3 ++-
src/backend/catalog/storage.c | 6 ++++--
src/backend/storage/buffer/bufmgr.c | 12 ++++++++----
src/backend/storage/freespace/freespace.c | 9 ++++++---
src/backend/storage/smgr/smgr.c | 19 ++++++++++++++++++-
src/include/storage/smgr.h | 3 ++-
9 files changed, 52 insertions(+), 18 deletions(-)
diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c
index 28bc585..d599655 100644
--- a/src/backend/access/gist/gistbuild.c
+++ b/src/backend/access/gist/gistbuild.c
@@ -808,6 +808,7 @@ gistBuildCallback(Relation index,
GISTBuildState *buildstate = (GISTBuildState *) state;
IndexTuple itup;
MemoryContext oldCtx;
+ bool isCached;
oldCtx = MemoryContextSwitchTo(buildstate->giststate->tempCxt);
@@ -856,7 +857,8 @@ gistBuildCallback(Relation index,
*/
if ((buildstate->buildMode == GIST_BUFFERING_AUTO &&
buildstate->indtuples % BUFFERING_MODE_SWITCH_CHECK_STEP == 0 &&
- effective_cache_size < smgrnblocks(index->rd_smgr, MAIN_FORKNUM)) ||
+ effective_cache_size < smgrnblocks(index->rd_smgr, MAIN_FORKNUM,
+ &isCached)) ||
(buildstate->buildMode == GIST_BUFFERING_STATS &&
buildstate->indtuples >= BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET))
{
diff --git a/src/backend/access/heap/visibilitymap.c b/src/backend/access/heap/visibilitymap.c
index b107218..6d2be35 100644
--- a/src/backend/access/heap/visibilitymap.c
+++ b/src/backend/access/heap/visibilitymap.c
@@ -445,6 +445,7 @@ BlockNumber
visibilitymap_prepare_truncate(Relation rel, BlockNumber nheapblocks)
{
BlockNumber newnblocks;
+ bool cached;
/* last remaining block, byte, and bit */
BlockNumber truncBlock = HEAPBLK_TO_MAPBLOCK(nheapblocks);
@@ -528,7 +529,7 @@ visibilitymap_prepare_truncate(Relation rel, BlockNumber nheapblocks)
else
newnblocks = truncBlock;
- if (smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM) <= newnblocks)
+ if (smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM, &cached) <= newnblocks)
{
/* nothing to do, the file was already smaller than requested size */
return InvalidBlockNumber;
@@ -547,6 +548,7 @@ static Buffer
vm_readbuf(Relation rel, BlockNumber blkno, bool extend)
{
Buffer buf;
+ bool cached;
/*
* We might not have opened the relation at the smgr level yet, or we
@@ -564,7 +566,7 @@ vm_readbuf(Relation rel, BlockNumber blkno, bool extend)
if (rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] == InvalidBlockNumber)
{
if (smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM))
- smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM);
+ smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM, &cached);
else
rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] = 0;
}
@@ -618,6 +620,7 @@ vm_extend(Relation rel, BlockNumber vm_nblocks)
{
BlockNumber vm_nblocks_now;
PGAlignedBlock pg;
+ bool cached;
PageInit((Page) pg.data, BLCKSZ, 0);
@@ -647,7 +650,7 @@ vm_extend(Relation rel, BlockNumber vm_nblocks)
/* Invalidate cache so that smgrnblocks() asks the kernel. */
rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] = InvalidBlockNumber;
- vm_nblocks_now = smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM);
+ vm_nblocks_now = smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM, &cached);
/* Now extend the file */
while (vm_nblocks_now < vm_nblocks)
diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c
index 6438c45..e64451f 100644
--- a/src/backend/access/table/tableam.c
+++ b/src/backend/access/table/tableam.c
@@ -628,6 +628,7 @@ uint64
table_block_relation_size(Relation rel, ForkNumber forkNumber)
{
uint64 nblocks = 0;
+ bool cached;
/* Open it at the smgr level if not already done */
RelationOpenSmgr(rel);
@@ -636,10 +637,10 @@ table_block_relation_size(Relation rel, ForkNumber forkNumber)
if (forkNumber == InvalidForkNumber)
{
for (int i = 0; i < MAX_FORKNUM; i++)
- nblocks += smgrnblocks(rel->rd_smgr, i);
+ nblocks += smgrnblocks(rel->rd_smgr, i, &cached);
}
else
- nblocks = smgrnblocks(rel->rd_smgr, forkNumber);
+ nblocks = smgrnblocks(rel->rd_smgr, forkNumber, &cached);
return nblocks * BLCKSZ;
}
diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c
index 7e915bc..20eda81 100644
--- a/src/backend/access/transam/xlogutils.c
+++ b/src/backend/access/transam/xlogutils.c
@@ -444,6 +444,7 @@ XLogReadBufferExtended(RelFileNode rnode, ForkNumber forknum,
BlockNumber lastblock;
Buffer buffer;
SMgrRelation smgr;
+ bool cached;
Assert(blkno != P_NEW);
@@ -460,7 +461,7 @@ XLogReadBufferExtended(RelFileNode rnode, ForkNumber forknum,
*/
smgrcreate(smgr, forknum, true);
- lastblock = smgrnblocks(smgr, forknum);
+ lastblock = smgrnblocks(smgr, forknum, &cached);
if (blkno < lastblock)
{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index dbbd3aa..057e53b 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -410,6 +410,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
{
PGAlignedBlock buf;
Page page;
+ bool cached;
bool use_wal;
bool copying_initfork;
BlockNumber nblocks;
@@ -434,7 +435,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
use_wal = XLogIsNeeded() &&
(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
- nblocks = smgrnblocks(src, forkNum);
+ nblocks = smgrnblocks(src, forkNum, &cached);
for (blkno = 0; blkno < nblocks; blkno++)
{
@@ -703,6 +704,7 @@ smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
BlockNumber nblocks[MAX_FORKNUM + 1];
BlockNumber total_blocks = 0;
SMgrRelation srel;
+ bool cached;
srel = smgropen(pendingsync->rnode, InvalidBackendId);
@@ -720,7 +722,7 @@ smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
{
if (smgrexists(srel, fork))
{
- BlockNumber n = smgrnblocks(srel, fork);
+ BlockNumber n = smgrnblocks(srel, fork, &cached);
/* we shouldn't come here for unlogged relations */
Assert(fork != INIT_FORKNUM);
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index e549fa1..45897a3 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -720,6 +720,7 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum,
BufferDesc *bufHdr;
Block bufBlock;
bool found;
+ bool isCached;
bool isExtend;
bool isLocalBuf = SmgrIsTemp(smgr);
@@ -739,7 +740,7 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum,
/* Substitute proper block number if caller asked for P_NEW */
if (isExtend)
- blockNum = smgrnblocks(smgr, forkNum);
+ blockNum = smgrnblocks(smgr, forkNum, &isCached);
if (isLocalBuf)
{
@@ -2852,11 +2853,14 @@ RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum)
case RELKIND_SEQUENCE:
case RELKIND_INDEX:
case RELKIND_PARTITIONED_INDEX:
- /* Open it at the smgr level if not already done */
- RelationOpenSmgr(relation);
+ {
+ bool isCached;
- return smgrnblocks(relation->rd_smgr, forkNum);
+ /* Open it at the smgr level if not already done */
+ RelationOpenSmgr(relation);
+ return smgrnblocks(relation->rd_smgr, forkNum, &isCached);
+ }
case RELKIND_RELATION:
case RELKIND_TOASTVALUE:
case RELKIND_MATVIEW:
diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c
index 6a96126..f631878 100644
--- a/src/backend/storage/freespace/freespace.c
+++ b/src/backend/storage/freespace/freespace.c
@@ -264,6 +264,7 @@ FreeSpaceMapPrepareTruncateRel(Relation rel, BlockNumber nblocks)
FSMAddress first_removed_address;
uint16 first_removed_slot;
Buffer buf;
+ bool cached;
RelationOpenSmgr(rel);
@@ -317,7 +318,7 @@ FreeSpaceMapPrepareTruncateRel(Relation rel, BlockNumber nblocks)
else
{
new_nfsmblocks = fsm_logical_to_physical(first_removed_address);
- if (smgrnblocks(rel->rd_smgr, FSM_FORKNUM) <= new_nfsmblocks)
+ if (smgrnblocks(rel->rd_smgr, FSM_FORKNUM, &cached) <= new_nfsmblocks)
return InvalidBlockNumber; /* nothing to do; the FSM was already
* smaller */
}
@@ -532,6 +533,7 @@ fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
{
BlockNumber blkno = fsm_logical_to_physical(addr);
Buffer buf;
+ bool cached;
RelationOpenSmgr(rel);
@@ -547,7 +549,7 @@ fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
/* Invalidate the cache so smgrnblocks asks the kernel. */
rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM] = InvalidBlockNumber;
if (smgrexists(rel->rd_smgr, FSM_FORKNUM))
- smgrnblocks(rel->rd_smgr, FSM_FORKNUM);
+ smgrnblocks(rel->rd_smgr, FSM_FORKNUM, &cached);
else
rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM] = 0;
}
@@ -603,6 +605,7 @@ fsm_extend(Relation rel, BlockNumber fsm_nblocks)
{
BlockNumber fsm_nblocks_now;
PGAlignedBlock pg;
+ bool cached;
PageInit((Page) pg.data, BLCKSZ, 0);
@@ -633,7 +636,7 @@ fsm_extend(Relation rel, BlockNumber fsm_nblocks)
/* Invalidate cache so that smgrnblocks() asks the kernel. */
rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM] = InvalidBlockNumber;
- fsm_nblocks_now = smgrnblocks(rel->rd_smgr, FSM_FORKNUM);
+ fsm_nblocks_now = smgrnblocks(rel->rd_smgr, FSM_FORKNUM, &cached);
while (fsm_nblocks_now < fsm_nblocks)
{
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c
index f476b8e..6e2b680 100644
--- a/src/backend/storage/smgr/smgr.c
+++ b/src/backend/storage/smgr/smgr.c
@@ -551,23 +551,40 @@ smgrwriteback(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
/*
* smgrnblocks() -- Calculate the number of blocks in the
* supplied relation.
+ *
+ * This returns an InvalidBlockNumber when smgr_cached_nblocks is not
+ * available and when not in recovery path.
*/
BlockNumber
-smgrnblocks(SMgrRelation reln, ForkNumber forknum)
+smgrnblocks(SMgrRelation reln, ForkNumber forknum, bool *isCached)
{
BlockNumber result;
+ *isCached = false;
+
/*
* For now, we only use cached values in recovery due to lack of a shared
* invalidation mechanism for changes in file size.
*/
if (InRecovery && reln->smgr_cached_nblocks[forknum] != InvalidBlockNumber)
+ {
+ *isCached = true;
+
return reln->smgr_cached_nblocks[forknum];
+ }
result = smgrsw[reln->smgr_which].smgr_nblocks(reln, forknum);
reln->smgr_cached_nblocks[forknum] = result;
+ /*
+ * We cannot believe the result from smgr_nblocks is always accurate
+ * because lseek of buggy Linux kernels doesn't account for a recent
+ * write.
+ */
+ if (!InRecovery && result == InvalidBlockNumber)
+ return InvalidBlockNumber;
+
return result;
}
diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h
index f28a842..e247cce 100644
--- a/src/include/storage/smgr.h
+++ b/src/include/storage/smgr.h
@@ -98,7 +98,8 @@ extern void smgrwrite(SMgrRelation reln, ForkNumber forknum,
BlockNumber blocknum, char *buffer, bool skipFsync);
extern void smgrwriteback(SMgrRelation reln, ForkNumber forknum,
BlockNumber blocknum, BlockNumber nblocks);
-extern BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum);
+extern BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum,
+ bool *isCached);
extern void smgrtruncate(SMgrRelation reln, ForkNumber *forknum,
int nforks, BlockNumber *nblocks);
extern void smgrimmedsync(SMgrRelation reln, ForkNumber forknum);
--
1.8.3.1