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

Commitc973051

Browse files
committed
A session that does not have any live snapshots does not have to be waited for
when we are waiting for old snapshots to go away during a concurrent indexbuild. In particular, this rule lets us avoid waiting foridle-in-transaction sessions.This logic could be improved further if we had some way to wake up whenthe session we are currently waiting for goes idle-in-transaction. Howeverthat would be a significantly more complex/invasive patch, so it'll have towait for some other day.Simon Riggs, with some improvements by Tom.
1 parent1c2d408 commitc973051

File tree

4 files changed

+101
-32
lines changed

4 files changed

+101
-32
lines changed

‎src/backend/commands/indexcmds.c

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.183 2009/03/31 22:12:47 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.184 2009/04/04 17:40:36 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -130,12 +130,14 @@ DefineIndex(RangeVar *heapRelation,
130130
intnumberOfAttributes;
131131
VirtualTransactionId*old_lockholders;
132132
VirtualTransactionId*old_snapshots;
133+
intn_old_snapshots;
133134
LockRelIdheaprelid;
134135
LOCKTAGheaplocktag;
135136
Snapshotsnapshot;
136137
Relationpg_index;
137138
HeapTupleindexTuple;
138139
Form_pg_indexindexForm;
140+
inti;
139141

140142
/*
141143
* count attributes in index
@@ -611,7 +613,7 @@ DefineIndex(RangeVar *heapRelation,
611613
* snapshot treats as committed. If such a recently-committed transaction
612614
* deleted tuples in the table, we will not include them in the index; yet
613615
* those transactions which see the deleting one as still-in-progress will
614-
* expectthem to be there once we mark the index as valid.
616+
* expectsuch tuples to be there once we mark the index as valid.
615617
*
616618
* We solve this by waiting for all endangered transactions to exit before
617619
* we mark the index as valid.
@@ -634,10 +636,13 @@ DefineIndex(RangeVar *heapRelation,
634636
* transactions that might have older snapshots. Obtain a list of VXIDs
635637
* of such transactions, and wait for them individually.
636638
*
637-
* We can exclude any running transactions that have xmin >= the xmax of
638-
* our reference snapshot, since they are clearly not interested in any
639-
* missing older tuples. Transactions in other DBs aren't a problem
640-
* either, since they'll never even be able to see this index.
639+
* We can exclude any running transactions that have xmin > the xmin of
640+
* our reference snapshot; their oldest snapshot must be newer than ours.
641+
* We can also exclude any transactions that have xmin = zero, since they
642+
* evidently have no live snapshot at all (and any one they might be
643+
* in process of taking is certainly newer than ours). Transactions in
644+
* other DBs can be ignored too, since they'll never even be able to see
645+
* this index.
641646
*
642647
* We can also exclude autovacuum processes and processes running manual
643648
* lazy VACUUMs, because they won't be fazed by missing index entries
@@ -647,14 +652,54 @@ DefineIndex(RangeVar *heapRelation,
647652
*
648653
* Also, GetCurrentVirtualXIDs never reports our own vxid, so we need not
649654
* check for that.
655+
*
656+
* If a process goes idle-in-transaction with xmin zero, we do not need
657+
* to wait for it anymore, per the above argument. We do not have the
658+
* infrastructure right now to stop waiting if that happens, but we can
659+
* at least avoid the folly of waiting when it is idle at the time we
660+
* would begin to wait. We do this by repeatedly rechecking the output of
661+
* GetCurrentVirtualXIDs. If, during any iteration, a particular vxid
662+
* doesn't show up in the output, we know we can forget about it.
650663
*/
651-
old_snapshots=GetCurrentVirtualXIDs(snapshot->xmax, false,
652-
PROC_IS_AUTOVACUUM |PROC_IN_VACUUM);
664+
old_snapshots=GetCurrentVirtualXIDs(snapshot->xmin, true, false,
665+
PROC_IS_AUTOVACUUM |PROC_IN_VACUUM,
666+
&n_old_snapshots);
653667

654-
while (VirtualTransactionIdIsValid(*old_snapshots))
668+
for (i=0;i<n_old_snapshots;i++)
655669
{
656-
VirtualXactLockTableWait(*old_snapshots);
657-
old_snapshots++;
670+
if (!VirtualTransactionIdIsValid(old_snapshots[i]))
671+
continue;/* found uninteresting in previous cycle */
672+
673+
if (i>0)
674+
{
675+
/* see if anything's changed ... */
676+
VirtualTransactionId*newer_snapshots;
677+
intn_newer_snapshots;
678+
intj;
679+
intk;
680+
681+
newer_snapshots=GetCurrentVirtualXIDs(snapshot->xmin,
682+
true, false,
683+
PROC_IS_AUTOVACUUM |PROC_IN_VACUUM,
684+
&n_newer_snapshots);
685+
for (j=i;j<n_old_snapshots;j++)
686+
{
687+
if (!VirtualTransactionIdIsValid(old_snapshots[j]))
688+
continue;/* found uninteresting in previous cycle */
689+
for (k=0;k<n_newer_snapshots;k++)
690+
{
691+
if (VirtualTransactionIdEquals(old_snapshots[j],
692+
newer_snapshots[k]))
693+
break;
694+
}
695+
if (k >=n_newer_snapshots)/* not there anymore */
696+
SetInvalidVirtualTransactionId(old_snapshots[j]);
697+
}
698+
pfree(newer_snapshots);
699+
}
700+
701+
if (VirtualTransactionIdIsValid(old_snapshots[i]))
702+
VirtualXactLockTableWait(old_snapshots[i]);
658703
}
659704

660705
/*

‎src/backend/storage/ipc/procarray.c

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*
2424
*
2525
* IDENTIFICATION
26-
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.48 2009/03/31 05:18:33 heikki Exp $
26+
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.49 2009/04/04 17:40:36 tgl Exp $
2727
*
2828
*-------------------------------------------------------------------------
2929
*/
@@ -1022,25 +1022,42 @@ IsBackendPid(int pid)
10221022
/*
10231023
* GetCurrentVirtualXIDs -- returns an array of currently active VXIDs.
10241024
*
1025-
* The array is palloc'd and is terminated with an invalid VXID.
1025+
* The array is palloc'd. The number of valid entries is returned into *nvxids.
10261026
*
1027-
* If limitXmin is not InvalidTransactionId, we skip any backends
1028-
* with xmin >= limitXmin.If allDbs is false, we skip backends attached
1029-
* to other databases. If excludeVacuum isn't zero, we skip processes for
1030-
* which (excludeVacuum & vacuumFlags) is not zero. Also, our own process
1031-
* is always skipped.
1027+
* The arguments allow filtering the set of VXIDs returned. Our own process
1028+
* is always skipped. In addition:
1029+
*If limitXmin is not InvalidTransactionId, skip processes with
1030+
*xmin > limitXmin.
1031+
*If excludeXmin0 is true, skip processes with xmin = 0.
1032+
*If allDbs is false, skip processes attached to other databases.
1033+
*If excludeVacuum isn't zero, skip processes for which
1034+
*(vacuumFlags & excludeVacuum) is not zero.
1035+
*
1036+
* Note: the purpose of the limitXmin and excludeXmin0 parameters is to
1037+
* allow skipping backends whose oldest live snapshot is no older than
1038+
* some snapshot we have. Since we examine the procarray with only shared
1039+
* lock, there are race conditions: a backend could set its xmin just after
1040+
* we look. Indeed, on multiprocessors with weak memory ordering, the
1041+
* other backend could have set its xmin *before* we look. We know however
1042+
* that such a backend must have held shared ProcArrayLock overlapping our
1043+
* own hold of ProcArrayLock, else we would see its xmin update. Therefore,
1044+
* any snapshot the other backend is taking concurrently with our scan cannot
1045+
* consider any transactions as still running that we think are committed
1046+
* (since backends must hold ProcArrayLock exclusive to commit).
10321047
*/
10331048
VirtualTransactionId*
1034-
GetCurrentVirtualXIDs(TransactionIdlimitXmin,boolallDbs,intexcludeVacuum)
1049+
GetCurrentVirtualXIDs(TransactionIdlimitXmin,boolexcludeXmin0,
1050+
boolallDbs,intexcludeVacuum,
1051+
int*nvxids)
10351052
{
10361053
VirtualTransactionId*vxids;
10371054
ProcArrayStruct*arrayP=procArray;
10381055
intcount=0;
10391056
intindex;
10401057

1041-
/* allocateresult space with room for a terminator */
1058+
/* allocatewhat's certainly enough result space */
10421059
vxids= (VirtualTransactionId*)
1043-
palloc(sizeof(VirtualTransactionId)*(arrayP->maxProcs+1));
1060+
palloc(sizeof(VirtualTransactionId)*arrayP->maxProcs);
10441061

10451062
LWLockAcquire(ProcArrayLock,LW_SHARED);
10461063

@@ -1056,15 +1073,18 @@ GetCurrentVirtualXIDs(TransactionId limitXmin, bool allDbs, int excludeVacuum)
10561073

10571074
if (allDbs||proc->databaseId==MyDatabaseId)
10581075
{
1059-
/* Fetch xmin just once - might change on us? */
1076+
/* Fetch xmin just once - might change on us */
10601077
TransactionIdpxmin=proc->xmin;
10611078

1079+
if (excludeXmin0&& !TransactionIdIsValid(pxmin))
1080+
continue;
1081+
10621082
/*
1063-
*Note thatInvalidTransactionId precedes all other XIDs, so a
1064-
*proc thathasn't set xmin yet willalways beincluded.
1083+
* InvalidTransactionId precedes all other XIDs, so a proc that
1084+
* hasn't set xmin yet willnot berejected by this test.
10651085
*/
10661086
if (!TransactionIdIsValid(limitXmin)||
1067-
TransactionIdPrecedes(pxmin,limitXmin))
1087+
TransactionIdPrecedesOrEquals(pxmin,limitXmin))
10681088
{
10691089
VirtualTransactionIdvxid;
10701090

@@ -1077,10 +1097,7 @@ GetCurrentVirtualXIDs(TransactionId limitXmin, bool allDbs, int excludeVacuum)
10771097

10781098
LWLockRelease(ProcArrayLock);
10791099

1080-
/* add the terminator */
1081-
vxids[count].backendId=InvalidBackendId;
1082-
vxids[count].localTransactionId=InvalidLocalTransactionId;
1083-
1100+
*nvxids=count;
10841101
returnvxids;
10851102
}
10861103

‎src/include/storage/lock.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/storage/lock.h,v 1.115 2009/01/01 17:24:01 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/storage/lock.h,v 1.116 2009/04/04 17:40:36 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -67,6 +67,12 @@ typedef struct
6767
#defineVirtualTransactionIdIsValid(vxid) \
6868
(((vxid).backendId != InvalidBackendId) && \
6969
LocalTransactionIdIsValid((vxid).localTransactionId))
70+
#defineVirtualTransactionIdEquals(vxid1,vxid2) \
71+
((vxid1).backendId == (vxid2).backendId && \
72+
(vxid1).localTransactionId == (vxid2).localTransactionId)
73+
#defineSetInvalidVirtualTransactionId(vxid) \
74+
((vxid).backendId = InvalidBackendId, \
75+
(vxid).localTransactionId = InvalidLocalTransactionId)
7076
#defineGET_VXID_FROM_PGPROC(vxid,proc) \
7177
((vxid).backendId = (proc).backendId, \
7278
(vxid).localTransactionId = (proc).lxid)

‎src/include/storage/procarray.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.24 2009/01/01 17:24:01 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.25 2009/04/04 17:40:36 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -40,7 +40,8 @@ extern intBackendXidGetPid(TransactionId xid);
4040
externboolIsBackendPid(intpid);
4141

4242
externVirtualTransactionId*GetCurrentVirtualXIDs(TransactionIdlimitXmin,
43-
boolallDbs,intexcludeVacuum);
43+
boolexcludeXmin0,boolallDbs,intexcludeVacuum,
44+
int*nvxids);
4445
externintCountActiveBackends(void);
4546
externintCountDBBackends(Oiddatabaseid);
4647
externintCountUserBackends(Oidroleid);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp