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

Commit15732b3

Browse files
committed
Add WaitForLockers in lmgr, refactoring index.c code
This is in support of a future REINDEX CONCURRENTLY feature.Michael Paquier
1 parentdddc91d commit15732b3

File tree

4 files changed

+81
-50
lines changed

4 files changed

+81
-50
lines changed

‎src/backend/catalog/index.c

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,6 @@ index_drop(Oid indexId, bool concurrent)
13231323
indexrelid;
13241324
LOCKTAGheaplocktag;
13251325
LOCKMODElockmode;
1326-
VirtualTransactionId*old_lockholders;
13271326

13281327
/*
13291328
* To drop an index safely, we must grab exclusive lock on its parent
@@ -1445,30 +1444,17 @@ index_drop(Oid indexId, bool concurrent)
14451444

14461445
/*
14471446
* Now we must wait until no running transaction could be using the
1448-
* index for a query. To do this, inquire which xacts currently would
1449-
* conflict with AccessExclusiveLock on the table -- ie, which ones
1450-
* have a lock of any kind on the table. Then wait for each of these
1451-
* xacts to commit or abort. Note we do not need to worry about xacts
1452-
* that open the table for reading after this point; they will see the
1447+
* index for a query. Note we do not need to worry about xacts that
1448+
* open the table for reading after this point; they will see the
14531449
* index as invalid when they open the relation.
14541450
*
14551451
* Note: the reason we use actual lock acquisition here, rather than
14561452
* just checking the ProcArray and sleeping, is that deadlock is
14571453
* possible if one of the transactions in question is blocked trying
14581454
* to acquire an exclusive lock on our table. The lock code will
14591455
* detect deadlock and error out properly.
1460-
*
1461-
* Note: GetLockConflicts() never reports our own xid, hence we need
1462-
* not check for that.Also, prepared xacts are not reported, which
1463-
* is fine since they certainly aren't going to do anything more.
14641456
*/
1465-
old_lockholders=GetLockConflicts(&heaplocktag,AccessExclusiveLock);
1466-
1467-
while (VirtualTransactionIdIsValid(*old_lockholders))
1468-
{
1469-
VirtualXactLock(*old_lockholders, true);
1470-
old_lockholders++;
1471-
}
1457+
WaitForLockers(heaplocktag,AccessExclusiveLock);
14721458

14731459
/*
14741460
* No more predicate locks will be acquired on this index, and we're
@@ -1510,15 +1496,9 @@ index_drop(Oid indexId, bool concurrent)
15101496

15111497
/*
15121498
* Wait till every transaction that saw the old index state has
1513-
* finished. The logic here is the same as above.
1499+
* finished.
15141500
*/
1515-
old_lockholders=GetLockConflicts(&heaplocktag,AccessExclusiveLock);
1516-
1517-
while (VirtualTransactionIdIsValid(*old_lockholders))
1518-
{
1519-
VirtualXactLock(*old_lockholders, true);
1520-
old_lockholders++;
1521-
}
1501+
WaitForLockers(heaplocktag,AccessExclusiveLock);
15221502

15231503
/*
15241504
* Re-open relations to allow us to complete our actions.

‎src/backend/commands/indexcmds.c

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,6 @@ DefineIndex(IndexStmt *stmt,
321321
IndexInfo*indexInfo;
322322
intnumberOfAttributes;
323323
TransactionIdlimitXmin;
324-
VirtualTransactionId*old_lockholders;
325324
VirtualTransactionId*old_snapshots;
326325
intn_old_snapshots;
327326
LockRelIdheaprelid;
@@ -652,30 +651,17 @@ DefineIndex(IndexStmt *stmt,
652651
* for an overview of how this works)
653652
*
654653
* Now we must wait until no running transaction could have the table open
655-
* with the old list of indexes. To do this, inquire which xacts
656-
* currently would conflict with ShareLock on the table -- ie, which ones
657-
* have a lock that permits writing the table.Then wait for each of
658-
* these xacts to commit or abort.Note we do not need to worry about
659-
* xacts that open the table for writing after this point; they will see
660-
* the new index when they open it.
654+
* with the old list of indexes. Note we do not need to worry about xacts
655+
* that open the table for writing after this point; they will see the new
656+
* index when they open it.
661657
*
662658
* Note: the reason we use actual lock acquisition here, rather than just
663659
* checking the ProcArray and sleeping, is that deadlock is possible if
664660
* one of the transactions in question is blocked trying to acquire an
665661
* exclusive lock on our table. The lock code will detect deadlock and
666662
* error out properly.
667-
*
668-
* Note: GetLockConflicts() never reports our own xid, hence we need not
669-
* check for that.Also, prepared xacts are not reported, which is fine
670-
* since they certainly aren't going to do anything more.
671663
*/
672-
old_lockholders=GetLockConflicts(&heaplocktag,ShareLock);
673-
674-
while (VirtualTransactionIdIsValid(*old_lockholders))
675-
{
676-
VirtualXactLock(*old_lockholders, true);
677-
old_lockholders++;
678-
}
664+
WaitForLockers(heaplocktag,ShareLock);
679665

680666
/*
681667
* At this moment we are sure that there are no transactions with the
@@ -739,13 +725,7 @@ DefineIndex(IndexStmt *stmt,
739725
* We once again wait until no transaction can have the table open with
740726
* the index marked as read-only for updates.
741727
*/
742-
old_lockholders=GetLockConflicts(&heaplocktag,ShareLock);
743-
744-
while (VirtualTransactionIdIsValid(*old_lockholders))
745-
{
746-
VirtualXactLock(*old_lockholders, true);
747-
old_lockholders++;
748-
}
728+
WaitForLockers(heaplocktag,ShareLock);
749729

750730
/*
751731
* Now take the "reference snapshot" that will be used by validate_index()

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

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,73 @@ ConditionalXactLockTableWait(TransactionId xid)
533533
return true;
534534
}
535535

536+
/*
537+
* WaitForLockersMultiple
538+
*Wait until no transaction holds locks that conflict with the given
539+
*locktags at the given lockmode.
540+
*
541+
* To do this, obtain the current list of lockers, and wait on their VXIDs
542+
* until they are finished.
543+
*
544+
* Note we don't try to acquire the locks on the given locktags, only the VXIDs
545+
* of its lock holders; if somebody grabs a conflicting lock on the objects
546+
* after we obtained our initial list of lockers, we will not wait for them.
547+
*/
548+
void
549+
WaitForLockersMultiple(List*locktags,LOCKMODElockmode)
550+
{
551+
List*holders=NIL;
552+
ListCell*lc;
553+
554+
/* Done if no locks to wait for */
555+
if (list_length(locktags)==0)
556+
return;
557+
558+
/* Collect the transactions we need to wait on */
559+
foreach(lc,locktags)
560+
{
561+
LOCKTAG*locktag=lfirst(lc);
562+
563+
holders=lappend(holders,GetLockConflicts(locktag,lockmode));
564+
}
565+
566+
/*
567+
* Note: GetLockConflicts() never reports our own xid, hence we need not
568+
* check for that.Also, prepared xacts are not reported, which is fine
569+
* since they certainly aren't going to do anything anymore.
570+
*/
571+
572+
/* Finally wait for each such transaction to complete */
573+
foreach(lc,holders)
574+
{
575+
VirtualTransactionId*lockholders=lfirst(lc);
576+
577+
while (VirtualTransactionIdIsValid(*lockholders))
578+
{
579+
VirtualXactLock(*lockholders, true);
580+
lockholders++;
581+
}
582+
}
583+
584+
list_free_deep(holders);
585+
}
586+
587+
/*
588+
* WaitForLockers
589+
*
590+
* Same as WaitForLockersMultiple, for a single lock tag.
591+
*/
592+
void
593+
WaitForLockers(LOCKTAGheaplocktag,LOCKMODElockmode)
594+
{
595+
List*l;
596+
597+
l=list_make1(&heaplocktag);
598+
WaitForLockersMultiple(l,lockmode);
599+
list_free(l);
600+
}
601+
602+
536603
/*
537604
*LockDatabaseObject
538605
*

‎src/include/storage/lmgr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ extern void XactLockTableDelete(TransactionId xid);
5757
externvoidXactLockTableWait(TransactionIdxid);
5858
externboolConditionalXactLockTableWait(TransactionIdxid);
5959

60+
/* Lock VXIDs, specified by conflicting locktags */
61+
externvoidWaitForLockers(LOCKTAGheaplocktag,LOCKMODElockmode);
62+
externvoidWaitForLockersMultiple(List*locktags,LOCKMODElockmode);
63+
6064
/* Lock a general object (other than a relation) of the current database */
6165
externvoidLockDatabaseObject(Oidclassid,Oidobjid,uint16objsubid,
6266
LOCKMODElockmode);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp