@@ -56,6 +56,7 @@ static int NLocalPinnedBuffers = 0;
56
56
static void InitLocalBuffers (void );
57
57
static Block GetLocalBufferStorage (void );
58
58
static Buffer GetLocalVictimBuffer (void );
59
+ static void InvalidateLocalBuffer (BufferDesc * bufHdr , bool check_unreferenced );
59
60
60
61
61
62
/*
@@ -269,17 +270,7 @@ GetLocalVictimBuffer(void)
269
270
*/
270
271
if (pg_atomic_read_u32 (& bufHdr -> state ) & BM_TAG_VALID )
271
272
{
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);
283
274
284
275
pgstat_count_io_op (IOOBJECT_TEMP_RELATION , IOCONTEXT_NORMAL , IOOP_EVICT , 1 , 0 );
285
276
}
@@ -492,6 +483,46 @@ MarkLocalBufferDirty(Buffer buffer)
492
483
pg_atomic_unlocked_write_u32 (& bufHdr -> state , buf_state );
493
484
}
494
485
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
+
495
526
/*
496
527
* DropRelationLocalBuffers
497
528
* This function removes from the buffer pool all the pages of the
@@ -512,7 +543,6 @@ DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber forkNum,
512
543
for (i = 0 ; i < NLocBuffer ; i ++ )
513
544
{
514
545
BufferDesc * bufHdr = GetLocalBufferDescriptor (i );
515
- LocalBufferLookupEnt * hresult ;
516
546
uint32 buf_state ;
517
547
518
548
buf_state = pg_atomic_read_u32 (& bufHdr -> state );
@@ -522,24 +552,7 @@ DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber forkNum,
522
552
BufTagGetForkNum (& bufHdr -> tag ) == forkNum &&
523
553
bufHdr -> tag .blockNum >= firstDelBlock )
524
554
{
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);
543
556
}
544
557
}
545
558
}
@@ -559,31 +572,14 @@ DropRelationAllLocalBuffers(RelFileLocator rlocator)
559
572
for (i = 0 ; i < NLocBuffer ; i ++ )
560
573
{
561
574
BufferDesc * bufHdr = GetLocalBufferDescriptor (i );
562
- LocalBufferLookupEnt * hresult ;
563
575
uint32 buf_state ;
564
576
565
577
buf_state = pg_atomic_read_u32 (& bufHdr -> state );
566
578
567
579
if ((buf_state & BM_TAG_VALID ) &&
568
580
BufTagMatchesRelFileLocator (& bufHdr -> tag , & rlocator ))
569
581
{
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);
587
583
}
588
584
}
589
585
}
0 commit comments