8000 Don't force-assign transaction id when exporting a snapshot. · postgrespro/postgres_cluster@6c2003f · GitHub
[go: up one dir, main page]

Skip to content

Commit 6c2003f

Browse files
committed
Don't force-assign transaction id when exporting a snapshot.
Previously we required every exported transaction to have an xid assigned. That was used to check that the exporting transaction is still running, which in turn is needed to guarantee that that necessary rows haven't been removed in between exporting and importing the snapshot. The exported xid caused unnecessary problems with logical decoding, because slot creation has to wait for all concurrent xid to finish, which in turn serializes concurrent slot creation. It also prohibited snapshots to be exported on hot-standby replicas. Instead export the virtual transactionid, which avoids the unnecessary serialization and the inability to export snapshots on standbys. This changes the file name of the exported snapshot, but since we never documented what that one means, that seems ok. Author: Petr Jelinek, slightly editorialized by me Reviewed-By: Andres Freund Discussion: https://postgr.es/m/f598b4b8-8cd7-0d54-0939-adda763d8c34@2ndquadrant.com
1 parent b6966d4 commit 6c2003f

File tree

7 files changed

+115
-67
lines changed
  • utils/time
  • include/storage
  • 7 files changed

    +115
    -67
    lines changed

    doc/src/sgml/ref/set_transaction.sgml

    Lines changed: 3 additions & 3 deletions
    Original file line numberDiff line numberDiff line change
    @@ -222,8 +222,8 @@ SET SESSION CHARACTERISTICS AS TRANSACTION <replaceable class="parameter">transa
    222222
    BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
    223223
    SELECT pg_export_snapshot();
    224224
    pg_export_snapshot
    225-
    --------------------
    226-
    000003A1-1
    225+
    ---------------------
    226+
    00000003-0000001B-1
    227227
    (1 row)
    228228
    </programlisting>
    229229

    @@ -233,7 +233,7 @@ SELECT pg_export_snapshot();
    233233

    234234
    <programlisting>
    235235
    BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
    236-
    SET TRANSACTION SNAPSHOT '000003A1-1';
    236+
    SET TRANSACTION SNAPSHOT '00000003-0000001B-1';
    237237
    </programlisting></para>
    238238
    </refsect1>
    239239

    src/backend/replication/logical/snapbuild.c

    Lines changed: 7 additions & 7 deletions
    Original file line numberDiff line numberDiff line change
    @@ -262,7 +262,7 @@ static bool ExportInProgress = false;
    262262
    static void SnapBuildPurgeCommittedTxn(SnapBuild *builder);
    263263

    264264
    /* snapshot building/manipulation/distribution functions */
    265-
    static Snapshot SnapBuildBuildSnapshot(SnapBuild *builder, TransactionId xid);
    265+
    static Snapshot SnapBuildBuildSnapshot(SnapBuild *builder);
    266266

    267267
    static void SnapBuildFreeSnapshot(Snapshot snap);
    268268

    @@ -463,7 +463,7 @@ SnapBuildSnapDecRefcount(Snapshot snap)
    463463
    * and ->subxip/subxcnt values.
    464464
    */
    465465
    static Snapshot
    466-
    SnapBuildBuildSnapshot(SnapBuild *builder, TransactionId xid)
    466+
    SnapBuildBuildSnapshot(SnapBuild *builder)
    467467
    {
    468468
    Snapshot snapshot;
    469469
    Size ssize;
    @@ -562,7 +562,7 @@ SnapBuildInitialSnapshot(SnapBuild *builder)
    562562
    if (TransactionIdIsValid(MyPgXact->xmin))
    563563
    elog(ERROR, "cannot build an initial slot snapshot when MyPgXact->xmin already is valid");
    564564

    565-
    snap = SnapBuildBuildSnapshot(builder, GetTopTransactionId());
    565+
    snap = SnapBuildBuildSnapshot(builder);
    566566

    567567
    /*
    568568
    * We know that snap->xmin is alive, enforced by the logical xmin
    @@ -679,7 +679,7 @@ SnapBuildGetOrBuildSnapshot(SnapBuild *builder, TransactionId xid)
    679679
    /* only build a new snapshot if we don't have a prebuilt one */
    680680
    if (builder->snapshot == NULL)
    681681
    {
    682-
    builder->snapshot = SnapBuildBuildSnapshot(builder, xid);
    682+
    builder->snapshot = SnapBuildBuildSnapshot(builder);
    683683
    /* increase refcount for the snapshot builder */
    684684
    SnapBuildSnapIncRefcount(builder->snapshot);
    685685
    }
    @@ -743,7 +743,7 @@ SnapBuildProcessChange(SnapBuild *builder, TransactionId xid, XLogRecPtr lsn)
    743743
    /* only build a new snapshot if we don't have a prebuilt one */
    744744
    if (builder->snapshot == NULL)
    745745
    {
    746-
    builder->snapshot = SnapBuildBuildSnapshot(builder, xid);
    746+
    builder->snapshot = SnapBuildBuildSnapshot(builder);
    747747
    /* increase refcount for the snapshot builder */
    748748
    SnapBuildSnapIncRefcount(builder->snapshot);
    749749
    }
    @@ -1061,7 +1061,7 @@ SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, TransactionId xid,
    10611061
    if (builder->snapshot)
    10621062
    SnapBuildSnapDecRefcount(builder->snapshot);
    10631063

    1064-
    builder->snapshot = SnapBuildBuildSnapshot(builder, xid);
    1064+
    builder->snapshot = SnapBuildBuildSnapshot(builder);
    10651065

    10661066
    /* we might need to execute invalidations, add snapshot */
    10671067
    if (!ReorderBufferXidHasBaseSnapshot(builder->reorder, xid))
    @@ -1831,7 +1831,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
    18311831
    {
    18321832
    SnapBuildSnapDecRefcount(builder->snapshot);
    18331833
    }
    1834-
    builder->snapshot = SnapBuildBuildSnapshot(builder, InvalidTransactionId);
    1834+
    builder->snapshot = SnapBuildBuildSnapshot(builder);
    18351835
    SnapBuildSnapIncRefcount(builder->snapshot);
    18361836

    18371837
    ReorderBufferSetRestartPoint(builder->reorder, lsn);

    src/backend/storage/ipc/procarray.c

    Lines changed: 7 additions & 4 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1793,14 +1793,15 @@ GetSnapshotData(Snapshot snapshot)
    17931793
    * Returns TRUE if successful, FALSE if source xact is no longer running.
    17941794
    */
    17951795
    bool
    1796-
    ProcArrayInstallImportedXmin(TransactionId xmin, TransactionId sourcexid)
    1796+
    ProcArrayInstallImportedXmin(TransactionId xmin,
    1797+
    VirtualTransactionId *sourcevxid)
    17971798
    {
    17981799
    bool result = false;
    17991800
    ProcArrayStruct *arrayP = procArray;
    18001801
    int index;
    18011802

    18021803
    Assert(TransactionIdIsNormal(xmin));
    1803-
    if (!TransactionIdIsNormal(sourcexid))
    1804+
    if (!sourcevxid)
    18041805
    return false;
    18051806

    18061807
    /* Get lock so source xact can't end while we're doing this */
    @@ -1817,8 +1818,10 @@ ProcArrayInstallImportedXmin(TransactionId xmin, TransactionId sourcexid)
    18171818
    if (pgxact->vacuumFlags & PROC_IN_VACUUM)
    18181819
    continue;
    18191820

    1820-
    xid = pgxact->xid; /* fetch just once */
    1821-
    if (xid != sourcexid)
    1821+
    /* We are only interested in the specific virtual transaction. */
    1822+
    if (proc->backendId != sourcevxid->backendId)
    1823+
    continue;
    1824+
    if (proc->lxid != sourcevxid->localTransactionId)
    18221825
    continue;
    18231826

    18241827
    /*

    src/backend/storage/lmgr/predicate.c

    Lines changed: 15 additions & 11 deletions
    Original file line numberDiff line numberDiff line change
    @@ -148,7 +148,7 @@
    148148
    * predicate lock maintenance
    149149
    * GetSerializableTransactionSnapshot(Snapshot snapshot)
    150150
    * SetSerializableTransactionSnapshot(Snapshot snapshot,
    151-
    * TransactionId sourcexid)
    151+
    * VirtualTransactionId *sourcevxid)
    152152
    * RegisterPredicateLockingXid(void)
    153153
    * PredicateLockRelation(Relation relation, Snapshot snapshot)
    154154
    * PredicateLockPage(Relation relation, BlockNumber blkno,
    @@ -434,7 +434,8 @@ static uint32 predicatelock_hash(const void *key, Size keysize);
    434434
    static void SummarizeOldestCommittedSxact(void);
    435435
    static Snapshot GetSafeSnapshot(Snapshot snapshot);
    436436
    static Snapshot GetSerializableTransactionSnapshotInt(Snapshot snapshot,
    437-
    TransactionId sourcexid);
    437+
    VirtualTransactionId *sourcevxid,
    438+
    int sourcepid);
    438439
    static bool PredicateLockExists(const PREDICATELOCKTARGETTAG *targettag);
    439440
    static bool GetParentPredicateLockTag(const PREDICATELOCKTARGETTAG *tag,
    440441
    PREDICATELOCKTARGETTAG *parent);
    @@ -1510,7 +1511,7 @@ GetSafeSnapshot(Snapshot origSnapshot)
    15101511
    * one passed to it, but we avoid assuming that here.
    15111512
    */
    15121513
    snapshot = GetSerializableTransactionSnapshotInt(origSnapshot,
    1513-
    InvalidTransactionId);
    1514+
    NULL, InvalidPid);
    15141515

    15151516
    if (MySerializableXact == InvalidSerializableXact)
    15161517
    return snapshot; /* no concurrent r/w xacts; it's safe */
    @@ -1643,7 +1644,7 @@ GetSerializableTransactionSnapshot(Snapshot snapshot)
    16431644
    return GetSafeSnapshot(snapshot);
    16441645

    16451646
    return GetSerializableTransactionSnapshotInt(snapshot,
    1646-
    InvalidTransactionId);
    1647+
    NULL, InvalidPid);
    16471648
    }
    16481649

    16491650
    /*
    @@ -1658,7 +1659,8 @@ GetSerializableTransactionSnapshot(Snapshot snapshot)
    16581659
    */
    16591660
    void
    16601661
    SetSerializableTransactionSnapshot(Snapshot snapshot,
    1661-
    TransactionId sourcexid)
    1662+
    VirtualTransactionId *sourcevxid,
    1663+
    int sourcepid)
    16621664
    {
    16631665
    Assert(IsolationIsSerializable());
    16641666

    @@ -1673,7 +1675,8 @@ SetSerializableTransactionSnapshot(Snapshot snapshot,
    16731675
    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    16741676
    errmsg("a snapshot-importing transaction must not be READ ONLY DEFERRABLE")));
    16751677

    1676-
    (void) GetSerializableTransactionSnapshotInt(snapshot, sourcexid);
    1678+
    (void) GetSerializableTransactionSnapshotInt(snapshot, sourcevxid,
    1679+
    sourcepid);
    16771680
    }
    16781681

    16791682
    /*
    @@ -1687,7 +1690,8 @@ SetSerializableTransactionSnapshot(Snapshot snapshot,
    16871690
    */
    16881691
    static Snapshot
    16891692
    GetSerializableTransactionSnapshotInt(Snapshot snapshot,
    1690-
    TransactionId sourcexid)
    1693+
    VirtualTransactionId *sourcevxid,
    1694+
    int sourcepid)
    16911695
    {
    16921696
    PGPROC *proc;
    16931697
    VirtualTransactionId vxid;
    @@ -1741,17 +1745,17 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot,
    17411745
    } while (!sxact);
    17421746

    17431747
    /* Get the snapshot, or check that it's safe to use */
    1744-
    if (!TransactionIdIsValid(sourcexid))
    1748+
    if (!sourcevxid)
    17451749
    snapshot = GetSnapshotData(snapshot);
    1746-
    else if (!ProcArrayInstallImportedXmin(snapshot->xmin, sourcexid))
    1750+
    else if (!ProcArrayInstallImportedXmin(snapshot->xmin, sourcevxid))
    17471751
    {
    17481752
    ReleasePredXact(sxact);
    17491753
    LWLockRelease(SerializableXactHashLock);
    17501754
    ereport(ERROR,
    17511755
    (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
    17521756
    errmsg("could not import the requested snapshot"),
    1753-
    errdetail("The source transaction %u is not running anymore.",
    1754-
    sourcexid)));
    1757+
    errdetail("The source process with pid %d is not running anymore.",
    1758+
    sourcepid)));
    17551759
    }
    17561760

    17571761
    /*

    0 commit comments

    Comments
     (0)
    0