1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

Retry after buffer locking failure during SPGiST index creation.

The original coding thought this case was impossible, but it can happen
if the bgwriter or checkpointer processes decide to write out an index
page while creation is still proceeding, leading to a bogus "unexpected
spgdoinsert() failure" error.  Problem reported by Jonathan S. Katz.

Teodor Sigaev
This commit is contained in:
Tom Lane
2013-11-02 16:45:42 -04:00
parent bffd1ce92c
commit 24ace4053d
2 changed files with 17 additions and 7 deletions

View File

@ -45,10 +45,17 @@ spgistBuildCallback(Relation index, HeapTuple htup, Datum *values,
/* Work in temp context, and reset it after each tuple */
oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx);
/* No concurrent insertions can be happening, so failure is unexpected */
if (!spgdoinsert(index, &buildstate->spgstate, &htup->t_self,
*values, *isnull))
elog(ERROR, "unexpected spgdoinsert() failure");
/*
* Even though no concurrent insertions can be happening, we still might
* get a buffer-locking failure due to bgwriter or checkpointer taking a
* lock on some buffer. So we need to be willing to retry. We can flush
* any temp data when retrying.
*/
while (!spgdoinsert(index, &buildstate->spgstate, &htup->t_self,
*values, *isnull))
{
MemoryContextReset(buildstate->tmpCtx);
}
MemoryContextSwitchTo(oldCtx);
MemoryContextReset(buildstate->tmpCtx);