• Andres Freund's avatar
    snapshot scalability: Introduce dense array of in-progress xids. · 941697c3
    Andres Freund authored
    The new array contains the xids for all connected backends / in-use
    PGPROC entries in a dense manner (in contrast to the PGPROC/PGXACT
    arrays which can have unused entries interspersed).
    
    This improves performance because GetSnapshotData() always needs to
    scan the xids of all live procarray entries and now there's no need to
    go through the procArray->pgprocnos indirection anymore.
    
    As the set of running top-level xids changes rarely, compared to the
    number of snapshots taken, this substantially increases the likelihood
    of most data required for a snapshot being in l2 cache.  In
    read-mostly workloads scanning the xids[] array will sufficient to
    build a snapshot, as most backends will not have an xid assigned.
    
    To keep the xid array dense ProcArrayRemove() needs to move entries
    behind the to-be-removed proc's one further up in the array. Obviously
    moving array entries cannot happen while a backend sets it
    xid. I.e. locking needs to prevent that array entries are moved while
    a backend modifies its xid.
    
    To avoid locking ProcArrayLock in GetNewTransactionId() - a fairly hot
    spot already - ProcArrayAdd() / ProcArrayRemove() now needs to hold
    XidGenLock in addition to ProcArrayLock. Adding / Removing a procarray
    entry is not a very frequent operation, even taking 2PC into account.
    
    Due to the above, the dense array entries can only be read or modified
    while holding ProcArrayLock and/or XidGenLock. This prevents a
    concurrent ProcArrayRemove() from shifting the dense array while it is
    accessed concurrently.
    
    While the new dense array is very good when needing to look at all
    xids it is less suitable when accessing a single backend's xid. In
    particular it would be problematic to have to acquire a lock to access
    a backend's own xid. Therefore a backend's xid is not just stored in
    the dense array, but also in PGPROC. This also allows a backend to
    only access the shared xid value when the backend had acquired an
    xid.
    
    The infrastructure added in this commit will be used for the remaining
    PGXACT fields in subsequent commits. They are kept separate to make
    review easier.
    
    Author: Andres Freund <andres@anarazel.de>
    Reviewed-By: default avatarRobert Haas <robertmhaas@gmail.com>
    Reviewed-By: default avatarThomas Munro <thomas.munro@gmail.com>
    Reviewed-By: default avatarDavid Rowley <dgrowleyml@gmail.com>
    Discussion: https://postgr.es/m/20200301083601.ews6hz5dduc3w2se@alap3.anarazel.de
    941697c3
lock.c 137 KB