Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc5315f4

Browse files
committed
Cache smgrnblocks() results in recovery.
Avoid repeatedly calling lseek(SEEK_END) during recovery by cachingthe size of each fork. For now, we can't use the same technique inother processes, because we lack a shared invalidation mechanism.Do this by generalizing the pre-existing caching used by FSM and VMto support all forks.Discussion:https://postgr.es/m/CAEepm%3D3SSw-Ty1DFcK%3D1rU-K6GSzYzfdD4d%2BZwapdN7dTa6%3DnQ%40mail.gmail.com
1 parente3931d0 commitc5315f4

File tree

6 files changed

+66
-46
lines changed

6 files changed

+66
-46
lines changed

‎contrib/pg_visibility/pg_visibility.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ pg_truncate_visibility_map(PG_FUNCTION_ARGS)
392392
check_relation_relkind(rel);
393393

394394
RelationOpenSmgr(rel);
395-
rel->rd_smgr->smgr_vm_nblocks=InvalidBlockNumber;
395+
rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM]=InvalidBlockNumber;
396396

397397
block=visibilitymap_prepare_truncate(rel,0);
398398
if (BlockNumberIsValid(block))

‎src/backend/access/heap/visibilitymap.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -561,17 +561,16 @@ vm_readbuf(Relation rel, BlockNumber blkno, bool extend)
561561
* If we haven't cached the size of the visibility map fork yet, check it
562562
* first.
563563
*/
564-
if (rel->rd_smgr->smgr_vm_nblocks==InvalidBlockNumber)
564+
if (rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM]==InvalidBlockNumber)
565565
{
566566
if (smgrexists(rel->rd_smgr,VISIBILITYMAP_FORKNUM))
567-
rel->rd_smgr->smgr_vm_nblocks=smgrnblocks(rel->rd_smgr,
568-
VISIBILITYMAP_FORKNUM);
567+
smgrnblocks(rel->rd_smgr,VISIBILITYMAP_FORKNUM);
569568
else
570-
rel->rd_smgr->smgr_vm_nblocks=0;
569+
rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM]=0;
571570
}
572571

573572
/* Handle requests beyond EOF */
574-
if (blkno >=rel->rd_smgr->smgr_vm_nblocks)
573+
if (blkno >=rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM])
575574
{
576575
if (extend)
577576
vm_extend(rel,blkno+1);
@@ -641,11 +640,13 @@ vm_extend(Relation rel, BlockNumber vm_nblocks)
641640
* Create the file first if it doesn't exist. If smgr_vm_nblocks is
642641
* positive then it must exist, no need for an smgrexists call.
643642
*/
644-
if ((rel->rd_smgr->smgr_vm_nblocks==0||
645-
rel->rd_smgr->smgr_vm_nblocks==InvalidBlockNumber)&&
643+
if ((rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM]==0||
644+
rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM]==InvalidBlockNumber)&&
646645
!smgrexists(rel->rd_smgr,VISIBILITYMAP_FORKNUM))
647646
smgrcreate(rel->rd_smgr,VISIBILITYMAP_FORKNUM, false);
648647

648+
/* Invalidate cache so that smgrnblocks() asks the kernel. */
649+
rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM]=InvalidBlockNumber;
649650
vm_nblocks_now=smgrnblocks(rel->rd_smgr,VISIBILITYMAP_FORKNUM);
650651

651652
/* Now extend the file */
@@ -667,8 +668,5 @@ vm_extend(Relation rel, BlockNumber vm_nblocks)
667668
*/
668669
CacheInvalidateSmgr(rel->rd_smgr->smgr_rnode);
669670

670-
/* Update local cache with the up-to-date size */
671-
rel->rd_smgr->smgr_vm_nblocks=vm_nblocks_now;
672-
673671
UnlockRelationForExtension(rel,ExclusiveLock);
674672
}

‎src/backend/catalog/storage.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,8 @@ RelationTruncate(Relation rel, BlockNumber nblocks)
290290
* Make sure smgr_targblock etc aren't pointing somewhere past new end
291291
*/
292292
rel->rd_smgr->smgr_targblock=InvalidBlockNumber;
293-
rel->rd_smgr->smgr_fsm_nblocks=InvalidBlockNumber;
294-
rel->rd_smgr->smgr_vm_nblocks=InvalidBlockNumber;
293+
for (inti=0;i <=MAX_FORKNUM;++i)
294+
rel->rd_smgr->smgr_cached_nblocks[i]=InvalidBlockNumber;
295295

296296
/* Prepare for truncation of MAIN fork of the relation */
297297
forks[nforks]=MAIN_FORKNUM;

‎src/backend/storage/freespace/freespace.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -541,18 +541,19 @@ fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
541541
* value might be stale. (We send smgr inval messages on truncation, but
542542
* not on extension.)
543543
*/
544-
if (rel->rd_smgr->smgr_fsm_nblocks==InvalidBlockNumber||
545-
blkno >=rel->rd_smgr->smgr_fsm_nblocks)
544+
if (rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM]==InvalidBlockNumber||
545+
blkno >=rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM])
546546
{
547+
/* Invalidate the cache so smgrnblocks asks the kernel. */
548+
rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM]=InvalidBlockNumber;
547549
if (smgrexists(rel->rd_smgr,FSM_FORKNUM))
548-
rel->rd_smgr->smgr_fsm_nblocks=smgrnblocks(rel->rd_smgr,
549-
FSM_FORKNUM);
550+
smgrnblocks(rel->rd_smgr,FSM_FORKNUM);
550551
else
551-
rel->rd_smgr->smgr_fsm_nblocks=0;
552+
rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM]=0;
552553
}
553554

554555
/* Handle requests beyond EOF */
555-
if (blkno >=rel->rd_smgr->smgr_fsm_nblocks)
556+
if (blkno >=rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM])
556557
{
557558
if (extend)
558559
fsm_extend(rel,blkno+1);
@@ -621,14 +622,17 @@ fsm_extend(Relation rel, BlockNumber fsm_nblocks)
621622
RelationOpenSmgr(rel);
622623

623624
/*
624-
* Create the FSM file first if it doesn't exist. If smgr_fsm_nblocks is
625-
* positive then it must exist, no need for an smgrexists call.
625+
* Create the FSM file first if it doesn't exist. If
626+
* smgr_cached_nblocks[FSM_FORKNUM] is positive then it must exist, no
627+
* need for an smgrexists call.
626628
*/
627-
if ((rel->rd_smgr->smgr_fsm_nblocks==0||
628-
rel->rd_smgr->smgr_fsm_nblocks==InvalidBlockNumber)&&
629+
if ((rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM]==0||
630+
rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM]==InvalidBlockNumber)&&
629631
!smgrexists(rel->rd_smgr,FSM_FORKNUM))
630632
smgrcreate(rel->rd_smgr,FSM_FORKNUM, false);
631633

634+
/* Invalidate cache so that smgrnblocks() asks the kernel. */
635+
rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM]=InvalidBlockNumber;
632636
fsm_nblocks_now=smgrnblocks(rel->rd_smgr,FSM_FORKNUM);
633637

634638
while (fsm_nblocks_now<fsm_nblocks)
@@ -640,9 +644,6 @@ fsm_extend(Relation rel, BlockNumber fsm_nblocks)
640644
fsm_nblocks_now++;
641645
}
642646

643-
/* Update local cache with the up-to-date size */
644-
rel->rd_smgr->smgr_fsm_nblocks=fsm_nblocks_now;
645-
646647
UnlockRelationForExtension(rel,ExclusiveLock);
647648
}
648649

‎src/backend/storage/smgr/smgr.c

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
#include"postgres.h"
1919

20+
#include"access/xlog.h"
2021
#include"lib/ilist.h"
2122
#include"storage/bufmgr.h"
2223
#include"storage/ipc.h"
@@ -174,8 +175,8 @@ smgropen(RelFileNode rnode, BackendId backend)
174175
/* hash_search already filled in the lookup key */
175176
reln->smgr_owner=NULL;
176177
reln->smgr_targblock=InvalidBlockNumber;
177-
reln->smgr_fsm_nblocks=InvalidBlockNumber;
178-
reln->smgr_vm_nblocks=InvalidBlockNumber;
178+
for (inti=0;i <=MAX_FORKNUM;++i)
179+
reln->smgr_cached_nblocks[i]=InvalidBlockNumber;
179180
reln->smgr_which=0;/* we only have md.c at present */
180181

181182
/* implementation-specific initialization */
@@ -464,6 +465,16 @@ smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
464465
{
465466
smgrsw[reln->smgr_which].smgr_extend(reln,forknum,blocknum,
466467
buffer,skipFsync);
468+
469+
/*
470+
* Normally we expect this to increase nblocks by one, but if the cached
471+
* value isn't as expected, just invalidate it so the next call asks the
472+
* kernel.
473+
*/
474+
if (reln->smgr_cached_nblocks[forknum]==blocknum)
475+
reln->smgr_cached_nblocks[forknum]=blocknum+1;
476+
else
477+
reln->smgr_cached_nblocks[forknum]=InvalidBlockNumber;
467478
}
468479

469480
/*
@@ -537,7 +548,20 @@ smgrwriteback(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
537548
BlockNumber
538549
smgrnblocks(SMgrRelationreln,ForkNumberforknum)
539550
{
540-
returnsmgrsw[reln->smgr_which].smgr_nblocks(reln,forknum);
551+
BlockNumberresult;
552+
553+
/*
554+
* For now, we only use cached values in recovery due to lack of a shared
555+
* invalidation mechanism for changes in file size.
556+
*/
557+
if (InRecovery&&reln->smgr_cached_nblocks[forknum]!=InvalidBlockNumber)
558+
returnreln->smgr_cached_nblocks[forknum];
559+
560+
result=smgrsw[reln->smgr_which].smgr_nblocks(reln,forknum);
561+
562+
reln->smgr_cached_nblocks[forknum]=result;
563+
564+
returnresult;
541565
}
542566

543567
/*
@@ -576,20 +600,19 @@ smgrtruncate(SMgrRelation reln, ForkNumber *forknum, int nforks, BlockNumber *nb
576600
/* Do the truncation */
577601
for (i=0;i<nforks;i++)
578602
{
603+
/* Make the cached size is invalid if we encounter an error. */
604+
reln->smgr_cached_nblocks[forknum[i]]=InvalidBlockNumber;
605+
579606
smgrsw[reln->smgr_which].smgr_truncate(reln,forknum[i],nblocks[i]);
580607

581608
/*
582-
* We might as well update the local smgr_fsm_nblocks and
583-
* smgr_vm_nblocks settings. The smgr cache inval message that this
584-
* function sent will cause other backends to invalidate their copies
585-
* of smgr_fsm_nblocks and smgr_vm_nblocks, and these ones too at the
586-
* next command boundary. But these ensure they aren't outright wrong
587-
* until then.
609+
* We might as well update the local smgr_cached_nblocks values. The
610+
* smgr cache inval message that this function sent will cause other
611+
* backends to invalidate their copies of smgr_fsm_nblocks and
612+
* smgr_vm_nblocks, and these ones too at the next command boundary.
613+
* But these ensure they aren't outright wrong until then.
588614
*/
589-
if (forknum[i]==FSM_FORKNUM)
590-
reln->smgr_fsm_nblocks=nblocks[i];
591-
if (forknum[i]==VISIBILITYMAP_FORKNUM)
592-
reln->smgr_vm_nblocks=nblocks[i];
615+
reln->smgr_cached_nblocks[forknum[i]]=nblocks[i];
593616
}
594617
}
595618

‎src/include/storage/smgr.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,13 @@ typedef struct SMgrRelationData
4545
structSMgrRelationData**smgr_owner;
4646

4747
/*
48-
* These next three fields are not actually used or manipulated by smgr,
49-
* except that they are reset to InvalidBlockNumber upon a cache flush
50-
* event (in particular, upon truncation of the relation). Higher levels
51-
* store cached state here so that it will be reset when truncation
52-
* happens. In all three cases, InvalidBlockNumber means "unknown".
48+
* The following fields are reset to InvalidBlockNumber upon a cache flush
49+
* event, and hold the last known size for each fork. This information is
50+
* currently only reliable during recovery, since there is no cache
51+
* invalidation for fork extension.
5352
*/
5453
BlockNumbersmgr_targblock;/* current insertion target block */
55-
BlockNumbersmgr_fsm_nblocks;/* last known size of fsm fork */
56-
BlockNumbersmgr_vm_nblocks;/* last known size of vm fork */
54+
BlockNumbersmgr_cached_nblocks[MAX_FORKNUM+1];/* last known size */
5755

5856
/* additional public fields may someday exist here */
5957

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp