Avoid re-checking for visibility map extension too frequently.

When testing bits (but not when setting or clearing them), we now
won't check whether the map has been extended.  This significantly
improves performance in the case where the visibility map doesn't
exist yet, by avoiding an extra system call per tuple.  To make
sure backends notice eventually, send an smgr inval on VM extension.

Dean Rasheed, with minor modifications by me.
This commit is contained in:
Robert Haas 2012-02-01 20:35:42 -05:00
parent 8a02339e9b
commit b4e0741727

View File

@ -88,6 +88,7 @@
#include "storage/bufmgr.h"
#include "storage/lmgr.h"
#include "storage/smgr.h"
#include "utils/inval.h"
/*#define TRACE_VISIBILITYMAP */
@ -482,16 +483,20 @@ vm_readbuf(Relation rel, BlockNumber blkno, bool extend)
{
Buffer buf;
/*
* We might not have opened the relation at the smgr level yet, or we might
* have been forced to close it by a sinval message. The code below won't
* necessarily notice relation extension immediately when extend = false,
* so we rely on sinval messages to ensure that our ideas about the size of
* the map aren't too far out of date.
*/
RelationOpenSmgr(rel);
/*
* If we haven't cached the size of the visibility map fork yet, check it
* first. Also recheck if the requested block seems to be past end, since
* our cached value might be stale. (We send smgr inval messages on
* truncation, but not on extension.)
* first.
*/
if (rel->rd_smgr->smgr_vm_nblocks == InvalidBlockNumber ||
blkno >= rel->rd_smgr->smgr_vm_nblocks)
if (rel->rd_smgr->smgr_vm_nblocks == InvalidBlockNumber)
{
if (smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM))
rel->rd_smgr->smgr_vm_nblocks = smgrnblocks(rel->rd_smgr,
@ -560,6 +565,7 @@ vm_extend(Relation rel, BlockNumber vm_nblocks)
vm_nblocks_now = smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM);
/* Now extend the file */
while (vm_nblocks_now < vm_nblocks)
{
smgrextend(rel->rd_smgr, VISIBILITYMAP_FORKNUM, vm_nblocks_now,
@ -567,6 +573,15 @@ vm_extend(Relation rel, BlockNumber vm_nblocks)
vm_nblocks_now++;
}
/*
* Send a shared-inval message to force other backends to close any smgr
* references they may have for this rel, which we are about to change.
* This is a useful optimization because it means that backends don't have
* to keep checking for creation or extension of the file, which happens
* infrequently.
*/
CacheInvalidateSmgr(rel->rd_smgr->smgr_rnode);
/* Update local cache with the up-to-date size */
rel->rd_smgr->smgr_vm_nblocks = vm_nblocks_now;