Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit24ace40

Browse files
committed
Retry after buffer locking failure during SPGiST index creation.
The original coding thought this case was impossible, but it can happenif the bgwriter or checkpointer processes decide to write out an indexpage while creation is still proceeding, leading to a bogus "unexpectedspgdoinsert() failure" error. Problem reported by Jonathan S. Katz.Teodor Sigaev
1 parentbffd1ce commit24ace40

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

‎src/backend/access/spgist/spgdoinsert.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,9 +1946,12 @@ spgdoinsert(Relation index, SpGistState *state,
19461946
* Attempt to acquire lock on child page. We must beware of
19471947
* deadlock against another insertion process descending from that
19481948
* page to our parent page (see README). If we fail to get lock,
1949-
* abandon the insertion and tell our caller to start over. XXX
1950-
* this could be improved; perhaps it'd be worth sleeping a bit
1951-
* before giving up?
1949+
* abandon the insertion and tell our caller to start over.
1950+
*
1951+
* XXX this could be improved, because failing to get lock on a
1952+
* buffer is not proof of a deadlock situation; the lock might be
1953+
* held by a reader, or even just background writer/checkpointer
1954+
* process. Perhaps it'd be worth retrying after sleeping a bit?
19521955
*/
19531956
if (!ConditionalLockBuffer(current.buffer))
19541957
{

‎src/backend/access/spgist/spginsert.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,17 @@ spgistBuildCallback(Relation index, HeapTuple htup, Datum *values,
4545
/* Work in temp context, and reset it after each tuple */
4646
oldCtx=MemoryContextSwitchTo(buildstate->tmpCtx);
4747

48-
/* No concurrent insertions can be happening, so failure is unexpected */
49-
if (!spgdoinsert(index,&buildstate->spgstate,&htup->t_self,
50-
*values,*isnull))
51-
elog(ERROR,"unexpected spgdoinsert() failure");
48+
/*
49+
* Even though no concurrent insertions can be happening, we still might
50+
* get a buffer-locking failure due to bgwriter or checkpointer taking a
51+
* lock on some buffer. So we need to be willing to retry. We can flush
52+
* any temp data when retrying.
53+
*/
54+
while (!spgdoinsert(index,&buildstate->spgstate,&htup->t_self,
55+
*values,*isnull))
56+
{
57+
MemoryContextReset(buildstate->tmpCtx);
58+
}
5259

5360
MemoryContextSwitchTo(oldCtx);
5461
MemoryContextReset(buildstate->tmpCtx);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp