|
37 | 37 | *
|
38 | 38 | *
|
39 | 39 | * IDENTIFICATION
|
40 |
| - * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.62 2010/04/06 10:50:57 sriggs Exp $ |
| 40 | + * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.63 2010/04/18 18:05:55 sriggs Exp $ |
41 | 41 | *
|
42 | 42 | *-------------------------------------------------------------------------
|
43 | 43 | */
|
@@ -1091,89 +1091,90 @@ GetSnapshotData(Snapshot snapshot)
|
1091 | 1091 | globalxmin=xmin=xmax;
|
1092 | 1092 |
|
1093 | 1093 | /*
|
1094 |
| - * Spin over procArray checking xid, xmin, and subxids. The goal is to |
1095 |
| - * gather all active xids, find the lowest xmin, and try to record |
1096 |
| - * subxids. |
| 1094 | + * If in recovery get any known assigned xids. |
1097 | 1095 | */
|
1098 |
| -for (index=0;index<arrayP->numProcs;index++) |
| 1096 | +if (!snapshot->takenDuringRecovery) |
1099 | 1097 | {
|
1100 |
| -volatilePGPROC*proc=arrayP->procs[index]; |
1101 |
| -TransactionIdxid; |
1102 |
| - |
1103 |
| -/* Ignore procs running LAZY VACUUM */ |
1104 |
| -if (proc->vacuumFlags&PROC_IN_VACUUM) |
1105 |
| -continue; |
1106 |
| - |
1107 |
| -/* Update globalxmin to be the smallest valid xmin */ |
1108 |
| -xid=proc->xmin;/* fetch just once */ |
1109 |
| -if (TransactionIdIsNormal(xid)&& |
1110 |
| -TransactionIdPrecedes(xid,globalxmin)) |
1111 |
| -globalxmin=xid; |
1112 |
| - |
1113 |
| -/* Fetch xid just once - see GetNewTransactionId */ |
1114 |
| -xid=proc->xid; |
1115 |
| - |
1116 | 1098 | /*
|
1117 |
| - * If the transaction has been assigned an xid < xmax we add it to the |
1118 |
| - * snapshot, and update xmin if necessary.There's no need to store |
1119 |
| - * XIDs >= xmax, since we'll treat them as running anyway. We don't |
1120 |
| - * bother to examine their subxids either. |
1121 |
| - * |
1122 |
| - * We don't include our own XID (if any) in the snapshot, but we must |
1123 |
| - * include it into xmin. |
| 1099 | + * Spin over procArray checking xid, xmin, and subxids. The goal is to |
| 1100 | + * gather all active xids, find the lowest xmin, and try to record |
| 1101 | + * subxids. During recovery no xids will be assigned, so all normal |
| 1102 | + * backends can be ignored, nor are there any VACUUMs running. All |
| 1103 | + * prepared transaction xids are held in KnownAssignedXids, so these |
| 1104 | + * will be seen without needing to loop through procs here. |
1124 | 1105 | */
|
1125 |
| -if (TransactionIdIsNormal(xid)) |
| 1106 | +for (index=0;index<arrayP->numProcs;index++) |
1126 | 1107 | {
|
1127 |
| -Assert(!snapshot->takenDuringRecovery); |
1128 |
| -if (TransactionIdFollowsOrEquals(xid,xmax)) |
| 1108 | +volatilePGPROC*proc=arrayP->procs[index]; |
| 1109 | +TransactionIdxid; |
| 1110 | + |
| 1111 | +/* Ignore procs running LAZY VACUUM */ |
| 1112 | +if (proc->vacuumFlags&PROC_IN_VACUUM) |
1129 | 1113 | continue;
|
1130 |
| -if (proc!=MyProc) |
1131 |
| -snapshot->xip[count++]=xid; |
1132 |
| -if (TransactionIdPrecedes(xid,xmin)) |
1133 |
| -xmin=xid; |
1134 |
| -} |
1135 | 1114 |
|
1136 |
| -/* |
1137 |
| - * Save subtransaction XIDs if possible (if we've already overflowed, |
1138 |
| - * there's no point). Note that the subxact XIDs must be later than |
1139 |
| - * their parent, so no need to check them against xmin. We could |
1140 |
| - * filter against xmax, but it seems better not to do that much work |
1141 |
| - * while holding the ProcArrayLock. |
1142 |
| - * |
1143 |
| - * The other backend can add more subxids concurrently, but cannot |
1144 |
| - * remove any.Hence it's important to fetch nxids just once. Should |
1145 |
| - * be safe to use memcpy, though. (We needn't worry about missing any |
1146 |
| - *xids added concurrently, because they must postdatexmax.) |
1147 |
| - * |
1148 |
| - *Again, our own XIDs are not included in the snapshot. |
1149 |
| - */ |
1150 |
| -if (!suboverflowed&&proc!=MyProc) |
1151 |
| -{ |
1152 |
| -if (proc->subxids.overflowed) |
1153 |
| -suboverflowed= true; |
1154 |
| -else |
| 1115 | +/* Update globalxmin to be the smallest valid xmin */ |
| 1116 | +xid=proc->xmin;/* fetch just once */ |
| 1117 | +if (TransactionIdIsNormal(xid)&& |
| 1118 | +TransactionIdPrecedes(xid,globalxmin)) |
| 1119 | +globalxmin=xid; |
| 1120 | + |
| 1121 | +/* Fetch xid just once - see GetNewTransactionId */ |
| 1122 | +xid=proc->xid; |
| 1123 | + |
| 1124 | +/* |
| 1125 | + *If the transaction has been assigned an xid <xmax we add it to the |
| 1126 | + * snapshot, and update xmin if necessary.There's no need to store |
| 1127 | + *XIDs >= xmax, since we'll treat them as running anyway. We don't |
| 1128 | + * bother to examine their subxids either. |
| 1129 | + * |
| 1130 | + * We don't include our own XID (if any) in the snapshot, but we must |
| 1131 | + * include it into xmin. |
| 1132 | + */ |
| 1133 | +if (TransactionIdIsNormal(xid)) |
1155 | 1134 | {
|
1156 |
| -intnxids=proc->subxids.nxids; |
| 1135 | +if (TransactionIdFollowsOrEquals(xid,xmax)) |
| 1136 | +continue; |
| 1137 | +if (proc!=MyProc) |
| 1138 | +snapshot->xip[count++]=xid; |
| 1139 | +if (TransactionIdPrecedes(xid,xmin)) |
| 1140 | +xmin=xid; |
| 1141 | +} |
1157 | 1142 |
|
1158 |
| -if (nxids>0) |
| 1143 | +/* |
| 1144 | + * Save subtransaction XIDs if possible (if we've already overflowed, |
| 1145 | + * there's no point). Note that the subxact XIDs must be later than |
| 1146 | + * their parent, so no need to check them against xmin. We could |
| 1147 | + * filter against xmax, but it seems better not to do that much work |
| 1148 | + * while holding the ProcArrayLock. |
| 1149 | + * |
| 1150 | + * The other backend can add more subxids concurrently, but cannot |
| 1151 | + * remove any.Hence it's important to fetch nxids just once. Should |
| 1152 | + * be safe to use memcpy, though. (We needn't worry about missing any |
| 1153 | + * xids added concurrently, because they must postdate xmax.) |
| 1154 | + * |
| 1155 | + * Again, our own XIDs are not included in the snapshot. |
| 1156 | + */ |
| 1157 | +if (!suboverflowed&&proc!=MyProc) |
| 1158 | +{ |
| 1159 | +if (proc->subxids.overflowed) |
| 1160 | +suboverflowed= true; |
| 1161 | +else |
1159 | 1162 | {
|
1160 |
| -Assert(!snapshot->takenDuringRecovery); |
1161 |
| -memcpy(snapshot->subxip+subcount, |
1162 |
| - (void*)proc->subxids.xids, |
1163 |
| -nxids*sizeof(TransactionId)); |
1164 |
| -subcount+=nxids; |
| 1163 | +intnxids=proc->subxids.nxids; |
| 1164 | + |
| 1165 | +if (nxids>0) |
| 1166 | +{ |
| 1167 | +memcpy(snapshot->subxip+subcount, |
| 1168 | + (void*)proc->subxids.xids, |
| 1169 | +nxids*sizeof(TransactionId)); |
| 1170 | +subcount+=nxids; |
| 1171 | +} |
1165 | 1172 | }
|
1166 | 1173 | }
|
1167 | 1174 | }
|
1168 | 1175 | }
|
1169 |
| - |
1170 |
| -/* |
1171 |
| - * If in recovery get any known assigned xids. |
1172 |
| - */ |
1173 |
| -if (snapshot->takenDuringRecovery) |
| 1176 | +else |
1174 | 1177 | {
|
1175 |
| -Assert(count==0); |
1176 |
| - |
1177 | 1178 | /*
|
1178 | 1179 | * We store all xids directly into subxip[]. Here's why:
|
1179 | 1180 | *
|
|