• Andres Freund's avatar
    Fix race condition leading to hanging logical slot creation. · 955a684e
    Andres Freund authored
    The snapshot assembly during the creation of logical slots relied
    waiting for transactions in xl_running_xacts to end, by checking for
    their commit/abort records.  Unfortunately, despite locking, it is
    possible to see an xl_running_xact record listing transactions as
    ready, that have already WAL-logged an commit/abort record, as the
    locking just prevents the ProcArray to be adjusted, and the commit
    record has to be logged first.
    
    That lead to either delayed or hanging snapshot creation, because
    snapbuild.c would wait "forever" to see commit/abort records for some
    transactions.  That hang resolved only if a xl_running_xacts record
    without any running transactions happened to be logged, far from
    certain on a busy server.
    
    It's impractical to prevent that via more heavyweight locking, the
    likelihood of deadlocks and significantly increased contention would
    be too big.
    
    Instead change the initial snapshot creation to be solely based on
    tracking the oldest running transaction via
    xl_running_xacts->oldestRunningXid - that actually ends up
    significantly simplifying the code.  That has two disadvantages:
    1) Because we cannot fully "trust" the contents of xl_running_xacts,
       we cannot use it to build the initial snapshot.  Instead we have to
       wait twice for all running transactions to finish.
    2) Previously a slot, unless the race occurred, could be created when
       the all transaction perceived as running based on commit/abort
       records, now we have to wait for the next xl_running_xacts record.
    To address that, trigger logging new xl_running_xacts record from
    within snapbuild.c exactly when necessary.
    
    Unfortunately snabuild.c's SnapBuild is stored on disk, one of the
    stupider ideas of a certain Mr Freund, so we can't change it in a
    minor release.  As this is going to be backpatched, we have to hack
    around a bit to keep on-disk compatibility.  A later commit will
    rejigger that on master.
    
    Author: Andres Freund, based on a quite different patch from Petr Jelinek
    Analyzed-By: Petr Jelinek
    Reviewed-By: Petr Jelinek
    Discussion: https://postgr.es/m/f37e975c-908f-858e-707f-058d3b1eb214@2ndquadrant.com
    Backpatch: 9.4-, where logical decoding has been introduced
    955a684e
reorderbuffer.c 88.8 KB