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

Commitc00dc33

Browse files
committed
Fix potential corruption of lock table in CREATE/DROP INDEX CONCURRENTLY.
If VirtualXactLock() has to wait for a transaction that holds its VXID lockas a fast-path lock, it must first convert the fast-path lock to a regularlock. It failed to take the required "partition" lock on the mainshared-memory lock table while doing so. This is the direct cause of theassert failure in GetLockStatusData() recently observed in the buildfarm,but more worryingly it could result in arbitrary corruption of the sharedlock table if some other process were concurrently engaged in modifying thesame partition of the lock table. Fortunately, VirtualXactLock() is onlyused by CREATE INDEX CONCURRENTLY and DROP INDEX CONCURRENTLY, so theopportunities for failure are fewer than they might have been.In passing, improve some comments and be a bit more consistent aboutorder of operations.
1 parentf31d5ba commitc00dc33

File tree

1 file changed

+25
-4
lines changed
  • src/backend/storage/lmgr

1 file changed

+25
-4
lines changed

‎src/backend/storage/lmgr/lock.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,12 @@ LockAcquireExtended(const LOCKTAG *locktag,
10171017
/*
10181018
* Find or create LOCK and PROCLOCK objects as needed for a new lock
10191019
* request.
1020+
*
1021+
* Returns the PROCLOCK object, or NULL if we failed to create the objects
1022+
* for lack of shared memory.
1023+
*
1024+
* The appropriate partition lock must be held at entry, and will be
1025+
* held at exit.
10201026
*/
10211027
staticPROCLOCK*
10221028
SetupLockInTable(LockMethodlockMethodTable,PGPROC*proc,
@@ -2414,6 +2420,8 @@ FastPathUnGrantRelationLock(Oid relid, LOCKMODE lockmode)
24142420
* FastPathTransferRelationLocks
24152421
*Transfer locks matching the given lock tag from per-backend fast-path
24162422
*arrays to the shared hash table.
2423+
*
2424+
* Returns true if successful, false if ran out of shared memory.
24172425
*/
24182426
staticbool
24192427
FastPathTransferRelationLocks(LockMethodlockMethodTable,constLOCKTAG*locktag,
@@ -2529,6 +2537,7 @@ FastPathGetRelationLockEntry(LOCALLOCK *locallock)
25292537
locallock->hashcode,lockmode);
25302538
if (!proclock)
25312539
{
2540+
LWLockRelease(partitionLock);
25322541
ereport(ERROR,
25332542
(errcode(ERRCODE_OUT_OF_MEMORY),
25342543
errmsg("out of shared memory"),
@@ -3422,9 +3431,6 @@ GetRunningTransactionLocks(int *nlocks)
34223431
for (i=0;i<NUM_LOCK_PARTITIONS;i++)
34233432
LWLockAcquire(FirstLockMgrLock+i,LW_SHARED);
34243433

3425-
/* Now scan the tables to copy the data */
3426-
hash_seq_init(&seqstat,LockMethodProcLockHash);
3427-
34283434
/* Now we can safely count the number of proclocks */
34293435
els=hash_get_num_entries(LockMethodProcLockHash);
34303436

@@ -3434,6 +3440,9 @@ GetRunningTransactionLocks(int *nlocks)
34343440
*/
34353441
accessExclusiveLocks=palloc(els*sizeof(xl_standby_lock));
34363442

3443+
/* Now scan the tables to copy the data */
3444+
hash_seq_init(&seqstat,LockMethodProcLockHash);
3445+
34373446
/*
34383447
* If lock is a currently granted AccessExclusiveLock then it will have
34393448
* just one proclock holder, so locks are never accessed twice in this
@@ -3978,22 +3987,34 @@ VirtualXactLock(VirtualTransactionId vxid, bool wait)
39783987

39793988
/*
39803989
* OK, we're going to need to sleep on the VXID. But first, we must set
3981-
* up the primary lock table entry, if needed.
3990+
* up the primary lock table entry, if needed (ie, convert the proc's
3991+
* fast-path lock on its VXID to a regular lock).
39823992
*/
39833993
if (proc->fpVXIDLock)
39843994
{
39853995
PROCLOCK*proclock;
39863996
uint32hashcode;
3997+
LWLockIdpartitionLock;
39873998

39883999
hashcode=LockTagHashCode(&tag);
4000+
4001+
partitionLock=LockHashPartitionLock(hashcode);
4002+
LWLockAcquire(partitionLock,LW_EXCLUSIVE);
4003+
39894004
proclock=SetupLockInTable(LockMethods[DEFAULT_LOCKMETHOD],proc,
39904005
&tag,hashcode,ExclusiveLock);
39914006
if (!proclock)
4007+
{
4008+
LWLockRelease(partitionLock);
39924009
ereport(ERROR,
39934010
(errcode(ERRCODE_OUT_OF_MEMORY),
39944011
errmsg("out of shared memory"),
39954012
errhint("You might need to increase max_locks_per_transaction.")));
4013+
}
39964014
GrantLock(proclock->tag.myLock,proclock,ExclusiveLock);
4015+
4016+
LWLockRelease(partitionLock);
4017+
39974018
proc->fpVXIDLock= false;
39984019
}
39994020

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp