|
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 | * |
|