Tom Lane wrote:
Why is InitIndexFreeSpaceMap coded to test for the FSM file already
existing?  AFAICS it cannot yet exist and it should be an error anyway
if it does.

Hmm. The FSM file can exist, if the index isn't created anew, but truncated and rebuilt. However, we normally create a new relfilenode in that case, so the only place where that actually happens is with a temporary ON COMMIT DELETE ROWS table. We could instead drop any extra relforks when the main fork is truncated, and let index_build recreate the FSM, see attached patch. That approach does seem cleaner to me, but it's actually even worse from a performance point of view, FWIW, because instead of just truncating the file, it's unlinked and recreated.

 The smgrexists probe is hardly free, so losing it would be
good.

Well, it's only done in index build, so I'm not too worried.

--
  Heikki Linnakangas
  EnterpriseDB   http://www.enterprisedb.com
*** src/backend/catalog/heap.c
--- src/backend/catalog/heap.c
***************
*** 2257,2262 **** RelationTruncateIndexes(Relation heapRelation)
--- 2257,2263 ----
  		Oid			indexId = lfirst_oid(indlist);
  		Relation	currentIndex;
  		IndexInfo  *indexInfo;
+ 		ForkNumber forknum;
  
  		/* Open the index relation; use exclusive lock, just to be sure */
  		currentIndex = index_open(indexId, AccessExclusiveLock);
***************
*** 2265,2275 **** RelationTruncateIndexes(Relation heapRelation)
  		indexInfo = BuildIndexInfo(currentIndex);
  
  		/*
! 		 * Now truncate the actual file (and discard buffers). The indexam
! 		 * is responsible for truncating the FSM in index_build(), if
! 		 * applicable.
  		 */
  		RelationTruncate(currentIndex, 0);
  
  		/* Initialize the index and rebuild */
  		/* Note: we do not need to re-establish pkey setting */
--- 2266,2280 ----
  		indexInfo = BuildIndexInfo(currentIndex);
  
  		/*
! 		 * Now truncate the actual file (and discard buffers), and drop any
! 		 * additional forks. This leaves us in the same state as after
! 		 * heap_create().
  		 */
  		RelationTruncate(currentIndex, 0);
+ 		for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
+ 			if (smgrexists(currentIndex->rd_smgr, forknum))
+ 				smgrdounlink(currentIndex->rd_smgr, forknum,
+ 							 currentIndex->rd_istemp, false);
  
  		/* Initialize the index and rebuild */
  		/* Note: we do not need to re-establish pkey setting */
*** src/backend/storage/freespace/indexfsm.c
--- src/backend/storage/freespace/indexfsm.c
***************
*** 38,47 **** InitIndexFreeSpaceMap(Relation rel)
  {
  	/* Create FSM fork if it doesn't exist yet, or truncate it if it does */
  	RelationOpenSmgr(rel);
! 	if (!smgrexists(rel->rd_smgr, FSM_FORKNUM))
! 		smgrcreate(rel->rd_smgr, FSM_FORKNUM, rel->rd_istemp, false);
! 	else
! 		smgrtruncate(rel->rd_smgr, FSM_FORKNUM, 0, rel->rd_istemp);
  }
  
  /*
--- 38,44 ----
  {
  	/* Create FSM fork if it doesn't exist yet, or truncate it if it does */
  	RelationOpenSmgr(rel);
! 	smgrcreate(rel->rd_smgr, FSM_FORKNUM, rel->rd_istemp, false);
  }
  
  /*
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to