mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-04 00:02:52 -05:00 
			
		
		
		
	Add pages deleted from pending list to FSM
Add pages deleted from GIN's pending list during cleanup to free space map immediately. Clean up process could be initiated by ordinary insert but adding page to FSM might occur only at vacuum. On some workload like never-vacuumed insert-only tables it could cause a huge bloat. Jeff Janes <jeff.janes@gmail.com>
This commit is contained in:
		
							parent
							
								
									a1c44e1af6
								
							
						
					
					
						commit
						e956808328
					
				@ -24,6 +24,7 @@
 | 
			
		||||
#include "miscadmin.h"
 | 
			
		||||
#include "utils/memutils.h"
 | 
			
		||||
#include "utils/rel.h"
 | 
			
		||||
#include "storage/indexfsm.h"
 | 
			
		||||
 | 
			
		||||
/* GUC parameter */
 | 
			
		||||
int			gin_pending_list_limit = 0;
 | 
			
		||||
@ -521,10 +522,12 @@ shiftList(Relation index, Buffer metabuffer, BlockNumber newHead,
 | 
			
		||||
		int64		nDeletedHeapTuples = 0;
 | 
			
		||||
		ginxlogDeleteListPages data;
 | 
			
		||||
		Buffer		buffers[GIN_NDELETE_AT_ONCE];
 | 
			
		||||
		BlockNumber	freespace[GIN_NDELETE_AT_ONCE];
 | 
			
		||||
 | 
			
		||||
		data.ndeleted = 0;
 | 
			
		||||
		while (data.ndeleted < GIN_NDELETE_AT_ONCE && blknoToDelete != newHead)
 | 
			
		||||
		{
 | 
			
		||||
			freespace[data.ndeleted] = blknoToDelete;
 | 
			
		||||
			buffers[data.ndeleted] = ReadBuffer(index, blknoToDelete);
 | 
			
		||||
			LockBuffer(buffers[data.ndeleted], GIN_EXCLUSIVE);
 | 
			
		||||
			page = BufferGetPage(buffers[data.ndeleted]);
 | 
			
		||||
@ -609,6 +612,10 @@ shiftList(Relation index, Buffer metabuffer, BlockNumber newHead,
 | 
			
		||||
			UnlockReleaseBuffer(buffers[i]);
 | 
			
		||||
 | 
			
		||||
		END_CRIT_SECTION();
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < data.ndeleted; i++)
 | 
			
		||||
			RecordFreeIndexPage(index, freespace[i]);
 | 
			
		||||
 | 
			
		||||
	} while (blknoToDelete != newHead);
 | 
			
		||||
 | 
			
		||||
	return false;
 | 
			
		||||
@ -744,6 +751,7 @@ ginInsertCleanup(GinState *ginstate,
 | 
			
		||||
	BuildAccumulator accum;
 | 
			
		||||
	KeyArray	datums;
 | 
			
		||||
	BlockNumber blkno;
 | 
			
		||||
	bool		fsm_vac = false;
 | 
			
		||||
 | 
			
		||||
	metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO);
 | 
			
		||||
	LockBuffer(metabuffer, GIN_SHARE);
 | 
			
		||||
@ -793,6 +801,7 @@ ginInsertCleanup(GinState *ginstate,
 | 
			
		||||
		{
 | 
			
		||||
			/* another cleanup process is running concurrently */
 | 
			
		||||
			UnlockReleaseBuffer(buffer);
 | 
			
		||||
			fsm_vac = false;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -857,6 +866,7 @@ ginInsertCleanup(GinState *ginstate,
 | 
			
		||||
				/* another cleanup process is running concurrently */
 | 
			
		||||
				UnlockReleaseBuffer(buffer);
 | 
			
		||||
				LockBuffer(metabuffer, GIN_UNLOCK);
 | 
			
		||||
				fsm_vac = false;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@ -895,9 +905,13 @@ ginInsertCleanup(GinState *ginstate,
 | 
			
		||||
			{
 | 
			
		||||
				/* another cleanup process is running concurrently */
 | 
			
		||||
				LockBuffer(metabuffer, GIN_UNLOCK);
 | 
			
		||||
				fsm_vac = false;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* At this point, some pending pages have been freed up */
 | 
			
		||||
			fsm_vac = true;
 | 
			
		||||
 | 
			
		||||
			Assert(blkno == metadata->head);
 | 
			
		||||
			LockBuffer(metabuffer, GIN_UNLOCK);
 | 
			
		||||
 | 
			
		||||
@ -931,6 +945,15 @@ ginInsertCleanup(GinState *ginstate,
 | 
			
		||||
 | 
			
		||||
	ReleaseBuffer(metabuffer);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * As pending list pages can have a high churn rate, it is
 | 
			
		||||
	 * desirable to recycle them immediately to the FreeSpace Map when
 | 
			
		||||
	 * ordinary backends clean the list.
 | 
			
		||||
	 */
 | 
			
		||||
	if (fsm_vac && !vac_delay)
 | 
			
		||||
		IndexFreeSpaceMapVacuum(index);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* Clean up temporary space */
 | 
			
		||||
	MemoryContextSwitchTo(oldCtx);
 | 
			
		||||
	MemoryContextDelete(opCtx);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user