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

Commit0bada39

Browse files
committed
Fix inplace update buffer self-deadlock.
A CacheInvalidateHeapTuple* callee might callCatalogCacheInitializeCache(), which needs a relcache entry. Acquiringa valid relcache entry might scan pg_class. Hence, to preventundetected LWLock self-deadlock, CacheInvalidateHeapTuple* callers mustnot hold BUFFER_LOCK_EXCLUSIVE on buffers of pg_class. Move theCacheInvalidateHeapTupleInplace() before the BUFFER_LOCK_EXCLUSIVE. Noback-patch, since I've reverted commit243e9b4 from non-master branches.Reported by Alexander Lakhin. Reviewed by Alexander Lakhin.Discussion:https://postgr.es/m/10ec0bc3-5933-1189-6bb8-5dec4114558e@gmail.com
1 parentb412f40 commit0bada39

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

‎src/backend/access/heap/heapam.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6214,6 +6214,17 @@ heap_inplace_lock(Relation relation,
62146214

62156215
Assert(BufferIsValid(buffer));
62166216

6217+
/*
6218+
* Construct shared cache inval if necessary. Because we pass a tuple
6219+
* version without our own inplace changes or inplace changes other
6220+
* sessions complete while we wait for locks, inplace update mustn't
6221+
* change catcache lookup keys. But we aren't bothering with index
6222+
* updates either, so that's true a fortiori. After LockBuffer(), it
6223+
* would be too late, because this might reach a
6224+
* CatalogCacheInitializeCache() that locks "buffer".
6225+
*/
6226+
CacheInvalidateHeapTupleInplace(relation,oldtup_ptr,NULL);
6227+
62176228
LockTuple(relation,&oldtup.t_self,InplaceUpdateTupleLock);
62186229
LockBuffer(buffer,BUFFER_LOCK_EXCLUSIVE);
62196230

@@ -6309,6 +6320,7 @@ heap_inplace_lock(Relation relation,
63096320
if (!ret)
63106321
{
63116322
UnlockTuple(relation,&oldtup.t_self,InplaceUpdateTupleLock);
6323+
ForgetInplace_Inval();
63126324
InvalidateCatalogSnapshot();
63136325
}
63146326
returnret;
@@ -6345,14 +6357,6 @@ heap_inplace_update_and_unlock(Relation relation,
63456357
dst= (char*)htup+htup->t_hoff;
63466358
src= (char*)tuple->t_data+tuple->t_data->t_hoff;
63476359

6348-
/*
6349-
* Construct shared cache inval if necessary. Note that because we only
6350-
* pass the new version of the tuple, this mustn't be used for any
6351-
* operations that could change catcache lookup keys. But we aren't
6352-
* bothering with index updates either, so that's true a fortiori.
6353-
*/
6354-
CacheInvalidateHeapTupleInplace(relation,tuple,NULL);
6355-
63566360
/* Like RecordTransactionCommit(), log only if needed */
63576361
if (XLogStandbyInfoActive())
63586362
nmsgs=inplaceGetInvalidationMessages(&invalMessages,
@@ -6481,6 +6485,7 @@ heap_inplace_unlock(Relation relation,
64816485
{
64826486
LockBuffer(buffer,BUFFER_LOCK_UNLOCK);
64836487
UnlockTuple(relation,&oldtup->t_self,InplaceUpdateTupleLock);
6488+
ForgetInplace_Inval();
64846489
}
64856490

64866491
#defineFRM_NOOP0x0001

‎src/backend/utils/cache/inval.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,18 @@ AtInplace_Inval(void)
12011201
inplaceInvalInfo=NULL;
12021202
}
12031203

1204+
/*
1205+
* ForgetInplace_Inval
1206+
*Alternative to PreInplace_Inval()+AtInplace_Inval(): discard queued-up
1207+
*invalidations. This lets inplace update enumerate invalidations
1208+
*optimistically, before locking the buffer.
1209+
*/
1210+
void
1211+
ForgetInplace_Inval(void)
1212+
{
1213+
inplaceInvalInfo=NULL;
1214+
}
1215+
12041216
/*
12051217
* AtEOSubXact_Inval
12061218
*Process queued-up invalidation messages at end of subtransaction.

‎src/include/utils/inval.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ extern void AtEOXact_Inval(bool isCommit);
3030

3131
externvoidPreInplace_Inval(void);
3232
externvoidAtInplace_Inval(void);
33+
externvoidForgetInplace_Inval(void);
3334

3435
externvoidAtEOSubXact_Inval(boolisCommit);
3536

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp