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);
}
/*