Skip to content

Commit 0762a15

Browse files
committed
localbuf: Introduce InvalidateLocalBuffer()
Previously, there were three copies of this code, two of them identical. There's no good reason for that. This change is nice on its own, but the main motivation is the AIO patchset, which needs to add extra checks the deduplicated code, which of course is easier if there is only one version. Reviewed-by: Melanie Plageman <melanieplageman@gmail.com> Discussion: https://postgr.es/m/CAAKRu_b9anbWzEs5AAF9WCvcEVmgz-1AkHSQ-CLLy-p7WHzvFw@mail.gmail.com
1 parent fa6af9b commit 0762a15

File tree

1 file changed

+44
-48
lines changed

1 file changed

+44
-48
lines changed

src/backend/storage/buffer/localbuf.c

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ static int NLocalPinnedBuffers = 0;
5656
static void InitLocalBuffers(void);
5757
static Block GetLocalBufferStorage(void);
5858
static Buffer GetLocalVictimBuffer(void);
59+
static void InvalidateLocalBuffer(BufferDesc *bufHdr, bool check_unreferenced);
5960

6061

6162
/*
@@ -269,17 +270,7 @@ GetLocalVictimBuffer(void)
269270
*/
270271
if (pg_atomic_read_u32(&bufHdr->state) & BM_TAG_VALID)
271272
{
272-
uint32 buf_state = pg_atomic_read_u32(&bufHdr->state);
273-
LocalBufferLookupEnt *hresult;
274-
275-
hresult = (LocalBufferLookupEnt *)
276-
hash_search(LocalBufHash, &bufHdr->tag, HASH_REMOVE, NULL);
277-
if (!hresult) /* shouldn't happen */
278-
elog(ERROR, "local buffer hash table corrupted");
279-
/* mark buffer invalid just in case hash insert fails */
280-
ClearBufferTag(&bufHdr->tag);
281-
buf_state &= ~(BUF_FLAG_MASK | BUF_USAGECOUNT_MASK);
282-
pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state);
273+
InvalidateLocalBuffer(bufHdr, false);
283274

284275
pgstat_count_io_op(IOOBJECT_TEMP_RELATION, IOCONTEXT_NORMAL, IOOP_EVICT, 1, 0);
285276
}
@@ -492,6 +483,46 @@ MarkLocalBufferDirty(Buffer buffer)
492483
pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state);
493484
}
494485

486+
/*
487+
* InvalidateLocalBuffer -- mark a local buffer invalid.
488+
*
489+
* If check_unreferenced is true, error out if the buffer is still
490+
* pinned. Passing false is appropriate when calling InvalidateLocalBuffer()
491+
* as part of changing the identity of a buffer, instead of just dropping the
492+
* buffer.
493+
*
494+
* See also InvalidateBuffer().
495+
*/
496+
static void
497+
InvalidateLocalBuffer(BufferDesc *bufHdr, bool check_unreferenced)
498+
{
499+
Buffer buffer = BufferDescriptorGetBuffer(bufHdr);
500+
int bufid = -buffer - 1;
501+
uint32 buf_state;
502+
LocalBufferLookupEnt *hresult;
503+
504+
buf_state = pg_atomic_read_u32(&bufHdr->state);
505+
506+
if (check_unreferenced && LocalRefCount[bufid] != 0)
507+
elog(ERROR, "block %u of %s is still referenced (local %u)",
508+
bufHdr->tag.blockNum,
509+
relpathbackend(BufTagGetRelFileLocator(&bufHdr->tag),
510+
MyProcNumber,
511+
BufTagGetForkNum(&bufHdr->tag)).str,
512+
LocalRefCount[bufid]);
513+
514+
/* Remove entry from hashtable */
515+
hresult = (LocalBufferLookupEnt *)
516+
hash_search(LocalBufHash, &bufHdr->tag, HASH_REMOVE, NULL);
517+
if (!hresult) /* shouldn't happen */
518+
elog(ERROR, "local buffer hash table corrupted");
519+
/* Mark buffer invalid */
520+
ClearBufferTag(&bufHdr->tag);
521+
buf_state &= ~BUF_FLAG_MASK;
522+
buf_state &= ~BUF_USAGECOUNT_MASK;
523+
pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state);
524+
}
525+
495526
/*
496527
* DropRelationLocalBuffers
497528
* This function removes from the buffer pool all the pages of the
@@ -512,7 +543,6 @@ DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber forkNum,
512543
for (i = 0; i < NLocBuffer; i++)
513544
{
514545
BufferDesc *bufHdr = GetLocalBufferDescriptor(i);
515-
LocalBufferLookupEnt *hresult;
516546
uint32 buf_state;
517547

518548
buf_state = pg_atomic_read_u32(&bufHdr->state);
@@ -522,24 +552,7 @@ DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber forkNum,
522552
BufTagGetForkNum(&bufHdr->tag) == forkNum &&
523553
bufHdr->tag.blockNum >= firstDelBlock)
524554
{
525-
if (LocalRefCount[i] != 0)
526-
elog(ERROR, "block %u of %s is still referenced (local %u)",
527-
bufHdr->tag.blockNum,
528-
relpathbackend(BufTagGetRelFileLocator(&bufHdr->tag),
529-
MyProcNumber,
530-
BufTagGetForkNum(&bufHdr->tag)).str,
531-
LocalRefCount[i]);
532-
533-
/* Remove entry from hashtable */
534-
hresult = (LocalBufferLookupEnt *)
535-
hash_search(LocalBufHash, &bufHdr->tag, HASH_REMOVE, NULL);
536-
if (!hresult) /* shouldn't happen */
537-
elog(ERROR, "local buffer hash table corrupted");
538-
/* Mark buffer invalid */
539-
ClearBufferTag(&bufHdr->tag);
540-
buf_state &= ~BUF_FLAG_MASK;
541-
buf_state &= ~BUF_USAGECOUNT_MASK;
542-
pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state);
555+
InvalidateLocalBuffer(bufHdr, true);
543556
}
544557
}
545558
}
@@ -559,31 +572,14 @@ DropRelationAllLocalBuffers(RelFileLocator rlocator)
559572
for (i = 0; i < NLocBuffer; i++)
560573
{
561574
BufferDesc *bufHdr = GetLocalBufferDescriptor(i);
562-
LocalBufferLookupEnt *hresult;
563575
uint32 buf_state;
564576

565577
buf_state = pg_atomic_read_u32(&bufHdr->state);
566578

567579
if ((buf_state & BM_TAG_VALID) &&
568580
BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator))
569581
{
570-
if (LocalRefCount[i] != 0)
571-
elog(ERROR, "block %u of %s is still referenced (local %u)",
572-
bufHdr->tag.blockNum,
573-
relpathbackend(BufTagGetRelFileLocator(&bufHdr->tag),
574-
MyProcNumber,
575-
BufTagGetForkNum(&bufHdr->tag)).str,
576-
LocalRefCount[i]);
577-
/* Remove entry from hashtable */
578-
hresult = (LocalBufferLookupEnt *)
579-
hash_search(LocalBufHash, &bufHdr->tag, HASH_REMOVE, NULL);
580-
if (!hresult) /* shouldn't happen */
581-
elog(ERROR, "local buffer hash table corrupted");
582-
/* Mark buffer invalid */
583-
ClearBufferTag(&bufHdr->tag);
584-
buf_state &= ~BUF_FLAG_MASK;
585-
buf_state &= ~BUF_USAGECOUNT_MASK;
586-
pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state);
582+
InvalidateLocalBuffer(bufHdr, true);
587583
}
588584
}
589585
}

0 commit comments

Comments
 (0)