• H
    When dispatching, send ActiveSnapshot along, not some random snapshot. · 4a95afc1
    Heikki Linnakangas 提交于
    If the caller specifies DF_WITH_SNAPSHOT, so that the command is dispatched
    to the segments with a snapshot, but it currently has no active snapshot in
    the QD itself, that seems like a mistake.
    
    In qdSerializeDtxContextInfo(), the comment talked about which snapshot to
    use when the transaction has already been aborted. I didn't quite
    understand that. I don't think the function is used to dispatch the "ABORT"
    statement itself, and we shouldn't be dispatching anything else in an
    already-aborted transaction.
    
    This makes it more clear which snapshot is dispatched along with the
    command. In theory, the latest or serializable snapshot can be different
    from the one being used when the command is dispatched, although I'm not
    sure if there are any such cases in practice.
    
    In the upcoming 8.4 merge, there are more changes coming up to snapshot
    management, which make it more difficult to get hold of the latest acquired
    snapshot in the transaction, so changing this now will ease the pain of
    merging that.
    
    I don't know why, but after making the change in qdSerializeDtxContextInfo,
    I started to get a lot of "Too many distributed transactions for snapshot
    (maxCount %d, count %d)" errors. Looking at the code, I don't understand
    how it ever worked. I don't see any no guarantee that the array in
    TempQDDtxContextInfo or TempDtxContextInfo was pre-allocated correctly.
    Or maybe it got allocated big enough to hold max_prepared_xacts, which
    was always large enough, but it seemed rather haphazard to me. So in
    the spirit of "if you don't understand it, rewrite it until you do", I
    changed the way the allocation of the inProgressXidArray array works.
    In statically allocated snapshots, i.e. SerializableSnapshot and
    LatestSnapshot, the array is malloc'd. In a snapshot copied with
    CopySnapshot(), it is points to a part of the palloc'd space for the
    snapshot. Nothing new so far, but I changed CopySnapshot() to set
    "maxCount" to -1 to indicate that it's not malloc'd. Then I modified
    DistributedSnapshot_Copy and DistributedSnapshot_Deserialize to not give up
    if the target array is not large enough, but enlarge it as needed. Finally,
    I made a little optimization in GetSnapshotData() when running in a QE, to
    move the copying of the distributed snapshot data to outside the section
    guarded by ProcArrayLock. ProcArrayLock can be heavily contended, so that's
    a nice little optimization anyway, but especially now that
    DistributedSnapshot_Copy() might need to realloc the array.
    4a95afc1
procarray.c 67.1 KB