LCOV - differential code coverage report
Current view: top level - src/backend/access/transam - subtrans.c (source / functions) Coverage Total Hit UNC UBC GIC GNC CBC DUB DCB
Current: 0e5ff9b9b45a657aea12440478dc002e9b01f138 vs 0123ce131fca454009439dfa3b2266d1d40737d7 Lines: 92.8 % 111 103 3 5 1 6 96 13
Current Date: 2026-03-14 14:10:32 -0400 Functions: 93.3 % 15 14 1 6 8 1
Baseline: lcov-20260315-024220-baseline Branches: 69.2 % 52 36 16 36 1 1
Baseline Date: 2026-03-14 15:27:56 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(1,7] days: 50.0 % 6 3 3 3
(30,360] days: 100.0 % 3 3 3
(360..) days: 95.1 % 102 97 5 1 96
Function coverage date bins:
(1,7] days: 0.0 % 1 0 1
(360..) days: 100.0 % 14 14 6 8
Branch coverage date bins:
(360..) days: 69.2 % 52 36 16 36

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * subtrans.c
                                  4                 :                :  *      PostgreSQL subtransaction-log manager
                                  5                 :                :  *
                                  6                 :                :  * The pg_subtrans manager is a pg_xact-like manager that stores the parent
                                  7                 :                :  * transaction Id for each transaction.  It is a fundamental part of the
                                  8                 :                :  * nested transactions implementation.  A main transaction has a parent
                                  9                 :                :  * of InvalidTransactionId, and each subtransaction has its immediate parent.
                                 10                 :                :  * The tree can easily be walked from child to parent, but not in the
                                 11                 :                :  * opposite direction.
                                 12                 :                :  *
                                 13                 :                :  * This code is based on xact.c, but the robustness requirements
                                 14                 :                :  * are completely different from pg_xact, because we only need to remember
                                 15                 :                :  * pg_subtrans information for currently-open transactions.  Thus, there is
                                 16                 :                :  * no need to preserve data over a crash and restart.
                                 17                 :                :  *
                                 18                 :                :  * There are no XLOG interactions since we do not care about preserving
                                 19                 :                :  * data across crashes.  During database startup, we simply force the
                                 20                 :                :  * currently-active page of SUBTRANS to zeroes.
                                 21                 :                :  *
                                 22                 :                :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
                                 23                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 24                 :                :  *
                                 25                 :                :  * src/backend/access/transam/subtrans.c
                                 26                 :                :  *
                                 27                 :                :  *-------------------------------------------------------------------------
                                 28                 :                :  */
                                 29                 :                : #include "postgres.h"
                                 30                 :                : 
                                 31                 :                : #include "access/slru.h"
                                 32                 :                : #include "access/subtrans.h"
                                 33                 :                : #include "access/transam.h"
                                 34                 :                : #include "miscadmin.h"
                                 35                 :                : #include "pg_trace.h"
                                 36                 :                : #include "utils/guc_hooks.h"
                                 37                 :                : #include "utils/snapmgr.h"
                                 38                 :                : 
                                 39                 :                : 
                                 40                 :                : /*
                                 41                 :                :  * Defines for SubTrans page sizes.  A page is the same BLCKSZ as is used
                                 42                 :                :  * everywhere else in Postgres.
                                 43                 :                :  *
                                 44                 :                :  * Note: because TransactionIds are 32 bits and wrap around at 0xFFFFFFFF,
                                 45                 :                :  * SubTrans page numbering also wraps around at
                                 46                 :                :  * 0xFFFFFFFF/SUBTRANS_XACTS_PER_PAGE, and segment numbering at
                                 47                 :                :  * 0xFFFFFFFF/SUBTRANS_XACTS_PER_PAGE/SLRU_PAGES_PER_SEGMENT.  We need take no
                                 48                 :                :  * explicit notice of that fact in this module, except when comparing segment
                                 49                 :                :  * and page numbers in TruncateSUBTRANS (see SubTransPagePrecedes) and zeroing
                                 50                 :                :  * them in StartupSUBTRANS.
                                 51                 :                :  */
                                 52                 :                : 
                                 53                 :                : /* We need four bytes per xact */
                                 54                 :                : #define SUBTRANS_XACTS_PER_PAGE (BLCKSZ / sizeof(TransactionId))
                                 55                 :                : 
                                 56                 :                : /*
                                 57                 :                :  * Although we return an int64 the actual value can't currently exceed
                                 58                 :                :  * 0xFFFFFFFF/SUBTRANS_XACTS_PER_PAGE.
                                 59                 :                :  */
                                 60                 :                : static inline int64
  837 akorotkov@postgresql       61                 :CBC       15089 : TransactionIdToPage(TransactionId xid)
                                 62                 :                : {
                                 63                 :          15089 :     return xid / (int64) SUBTRANS_XACTS_PER_PAGE;
                                 64                 :                : }
                                 65                 :                : 
                                 66                 :                : #define TransactionIdToEntry(xid) ((xid) % (TransactionId) SUBTRANS_XACTS_PER_PAGE)
                                 67                 :                : 
                                 68                 :                : 
                                 69                 :                : /*
                                 70                 :                :  * Link to shared-memory data structures for SUBTRANS control
                                 71                 :                :  */
                                 72                 :                : static SlruCtlData SubTransCtlData;
                                 73                 :                : 
                                 74                 :                : #define SubTransCtl  (&SubTransCtlData)
                                 75                 :                : 
                                 76                 :                : 
                                 77                 :                : static bool SubTransPagePrecedes(int64 page1, int64 page2);
                                 78                 :                : static int  subtrans_errdetail_for_io_error(const void *opaque_data);
                                 79                 :                : 
                                 80                 :                : 
                                 81                 :                : /*
                                 82                 :                :  * Record the parent of a subtransaction in the subtrans log.
                                 83                 :                :  */
                                 84                 :                : void
 3244 simon@2ndQuadrant.co       85                 :           8125 : SubTransSetParent(TransactionId xid, TransactionId parent)
                                 86                 :                : {
  837 akorotkov@postgresql       87                 :           8125 :     int64       pageno = TransactionIdToPage(xid);
 7927 tgl@sss.pgh.pa.us          88                 :           8125 :     int         entryno = TransactionIdToEntry(xid);
                                 89                 :                :     int         slotno;
                                 90                 :                :     LWLock     *lock;
                                 91                 :                :     TransactionId *ptr;
                                 92                 :                : 
 5930 simon@2ndQuadrant.co       93         [ -  + ]:           8125 :     Assert(TransactionIdIsValid(parent));
 3244                            94         [ -  + ]:           8125 :     Assert(TransactionIdFollows(xid, parent));
                                 95                 :                : 
  746 alvherre@alvh.no-ip.       96                 :           8125 :     lock = SimpleLruGetBankLock(SubTransCtl, pageno);
                                 97                 :           8125 :     LWLockAcquire(lock, LW_EXCLUSIVE);
                                 98                 :                : 
    2 heikki.linnakangas@i       99                 :GNC        8125 :     slotno = SimpleLruReadPage(SubTransCtl, pageno, true, &xid);
 7874 tgl@sss.pgh.pa.us         100                 :CBC        8125 :     ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
 7927                           101                 :           8125 :     ptr += entryno;
                                102                 :                : 
                                103                 :                :     /*
                                104                 :                :      * It's possible we'll try to set the parent xid multiple times but we
                                105                 :                :      * shouldn't ever be changing the xid from one valid xid to another valid
                                106                 :                :      * xid, which would corrupt the data structure.
                                107                 :                :      */
 3244 simon@2ndQuadrant.co      108         [ +  + ]:           8125 :     if (*ptr != parent)
                                109                 :                :     {
                                110         [ -  + ]:           7538 :         Assert(*ptr == InvalidTransactionId);
                                111                 :           7538 :         *ptr = parent;
                                112                 :           7538 :         SubTransCtl->shared->page_dirty[slotno] = true;
                                113                 :                :     }
                                114                 :                : 
  746 alvherre@alvh.no-ip.      115                 :           8125 :     LWLockRelease(lock);
 7927 tgl@sss.pgh.pa.us         116                 :           8125 : }
                                117                 :                : 
                                118                 :                : /*
                                119                 :                :  * Interrogate the parent of a transaction in the subtrans log.
                                120                 :                :  */
                                121                 :                : TransactionId
                                122                 :           3092 : SubTransGetParent(TransactionId xid)
                                123                 :                : {
  837 akorotkov@postgresql      124                 :           3092 :     int64       pageno = TransactionIdToPage(xid);
 7927 tgl@sss.pgh.pa.us         125                 :           3092 :     int         entryno = TransactionIdToEntry(xid);
                                126                 :                :     int         slotno;
                                127                 :                :     TransactionId *ptr;
                                128                 :                :     TransactionId parent;
                                129                 :                : 
                                130                 :                :     /* Can't ask about stuff that might not be around anymore */
 7850                           131         [ -  + ]:           3092 :     Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
                                132                 :                : 
                                133                 :                :     /* Bootstrap and frozen XIDs have no parent */
 7927                           134         [ -  + ]:           3092 :     if (!TransactionIdIsNormal(xid))
 7927 tgl@sss.pgh.pa.us         135                 :UBC           0 :         return InvalidTransactionId;
                                136                 :                : 
                                137                 :                :     /* lock is acquired by SimpleLruReadPage_ReadOnly */
                                138                 :                : 
    2 heikki.linnakangas@i      139                 :GNC        3092 :     slotno = SimpleLruReadPage_ReadOnly(SubTransCtl, pageno, &xid);
 7874 tgl@sss.pgh.pa.us         140                 :CBC        3092 :     ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
 7927                           141                 :           3092 :     ptr += entryno;
                                142                 :                : 
                                143                 :           3092 :     parent = *ptr;
                                144                 :                : 
  746 alvherre@alvh.no-ip.      145                 :           3092 :     LWLockRelease(SimpleLruGetBankLock(SubTransCtl, pageno));
                                146                 :                : 
 7927 tgl@sss.pgh.pa.us         147                 :           3092 :     return parent;
                                148                 :                : }
                                149                 :                : 
                                150                 :                : /*
                                151                 :                :  * SubTransGetTopmostTransaction
                                152                 :                :  *
                                153                 :                :  * Returns the topmost transaction of the given transaction id.
                                154                 :                :  *
                                155                 :                :  * Because we cannot look back further than TransactionXmin, it is possible
                                156                 :                :  * that this function will lie and return an intermediate subtransaction ID
                                157                 :                :  * instead of the true topmost parent ID.  This is OK, because in practice
                                158                 :                :  * we only care about detecting whether the topmost parent is still running
                                159                 :                :  * or is part of a current snapshot's list of still-running transactions.
                                160                 :                :  * Therefore, any XID before TransactionXmin is as good as any other.
                                161                 :                :  */
                                162                 :                : TransactionId
                                163                 :           1085 : SubTransGetTopmostTransaction(TransactionId xid)
                                164                 :                : {
                                165                 :           1085 :     TransactionId parentXid = xid,
 7868 bruce@momjian.us          166                 :           1085 :                 previousXid = xid;
                                167                 :                : 
                                168                 :                :     /* Can't ask about stuff that might not be around anymore */
 7850 tgl@sss.pgh.pa.us         169         [ -  + ]:           1085 :     Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
                                170                 :                : 
 7927                           171         [ +  + ]:           4177 :     while (TransactionIdIsValid(parentXid))
                                172                 :                :     {
                                173                 :           3092 :         previousXid = parentXid;
 7850                           174         [ -  + ]:           3092 :         if (TransactionIdPrecedes(parentXid, TransactionXmin))
 7875 tgl@sss.pgh.pa.us         175                 :UBC           0 :             break;
 7927 tgl@sss.pgh.pa.us         176                 :CBC        3092 :         parentXid = SubTransGetParent(parentXid);
                                177                 :                : 
                                178                 :                :         /*
                                179                 :                :          * By convention the parent xid gets allocated first, so should always
                                180                 :                :          * precede the child xid. Anything else points to a corrupted data
                                181                 :                :          * structure that could lead to an infinite loop, so exit.
                                182                 :                :          */
 3244 simon@2ndQuadrant.co      183         [ -  + ]:           3092 :         if (!TransactionIdPrecedes(parentXid, previousXid))
 3244 simon@2ndQuadrant.co      184         [ #  # ]:UBC           0 :             elog(ERROR, "pg_subtrans contains invalid entry: xid %u points to parent xid %u",
                                185                 :                :                  previousXid, parentXid);
                                186                 :                :     }
                                187                 :                : 
 7927 tgl@sss.pgh.pa.us         188         [ -  + ]:CBC        1085 :     Assert(TransactionIdIsValid(previousXid));
                                189                 :                : 
                                190                 :           1085 :     return previousXid;
                                191                 :                : }
                                192                 :                : 
                                193                 :                : /*
                                194                 :                :  * Number of shared SUBTRANS buffers.
                                195                 :                :  *
                                196                 :                :  * If asked to autotune, use 2MB for every 1GB of shared buffers, up to 8MB.
                                197                 :                :  * Otherwise just cap the configured amount to be between 16 and the maximum
                                198                 :                :  * allowed.
                                199                 :                :  */
                                200                 :                : static int
  746 alvherre@alvh.no-ip.      201                 :           4435 : SUBTRANSShmemBuffers(void)
                                202                 :                : {
                                203                 :                :     /* auto-tune based on shared buffers */
                                204         [ +  + ]:           4435 :     if (subtransaction_buffers == 0)
                                205                 :           3266 :         return SimpleLruAutotuneBuffers(512, 1024);
                                206                 :                : 
                                207         [ +  - ]:           1169 :     return Min(Max(16, subtransaction_buffers), SLRU_MAX_ALLOWED_BUFFERS);
                                208                 :                : }
                                209                 :                : 
                                210                 :                : /*
                                211                 :                :  * Initialization of shared memory for SUBTRANS
                                212                 :                :  */
                                213                 :                : Size
 7927 tgl@sss.pgh.pa.us         214                 :           2147 : SUBTRANSShmemSize(void)
                                215                 :                : {
  746 alvherre@alvh.no-ip.      216                 :           2147 :     return SimpleLruShmemSize(SUBTRANSShmemBuffers(), 0);
                                217                 :                : }
                                218                 :                : 
                                219                 :                : void
 7927 tgl@sss.pgh.pa.us         220                 :           1150 : SUBTRANSShmemInit(void)
                                221                 :                : {
                                222                 :                :     /* If auto-tuning is requested, now is the time to do it */
  746 alvherre@alvh.no-ip.      223         [ +  + ]:           1150 :     if (subtransaction_buffers == 0)
                                224                 :                :     {
                                225                 :                :         char        buf[32];
                                226                 :                : 
                                227                 :           1138 :         snprintf(buf, sizeof(buf), "%d", SUBTRANSShmemBuffers());
                                228                 :           1138 :         SetConfigOption("subtransaction_buffers", buf, PGC_POSTMASTER,
                                229                 :                :                         PGC_S_DYNAMIC_DEFAULT);
                                230                 :                : 
                                231                 :                :         /*
                                232                 :                :          * We prefer to report this value's source as PGC_S_DYNAMIC_DEFAULT.
                                233                 :                :          * However, if the DBA explicitly set subtransaction_buffers = 0 in
                                234                 :                :          * the config file, then PGC_S_DYNAMIC_DEFAULT will fail to override
                                235                 :                :          * that and we must force the matter with PGC_S_OVERRIDE.
                                236                 :                :          */
                                237         [ -  + ]:           1138 :         if (subtransaction_buffers == 0)    /* failed to apply it? */
  746 alvherre@alvh.no-ip.      238                 :UBC           0 :             SetConfigOption("subtransaction_buffers", buf, PGC_POSTMASTER,
                                239                 :                :                             PGC_S_OVERRIDE);
                                240                 :                :     }
  746 alvherre@alvh.no-ip.      241         [ -  + ]:CBC        1150 :     Assert(subtransaction_buffers != 0);
                                242                 :                : 
 7927 tgl@sss.pgh.pa.us         243                 :           1150 :     SubTransCtl->PagePrecedes = SubTransPagePrecedes;
    2 heikki.linnakangas@i      244                 :GNC        1150 :     SubTransCtl->errdetail_for_io_error = subtrans_errdetail_for_io_error;
  746 alvherre@alvh.no-ip.      245                 :CBC        1150 :     SimpleLruInit(SubTransCtl, "subtransaction", SUBTRANSShmemBuffers(), 0,
                                246                 :                :                   "pg_subtrans", LWTRANCHE_SUBTRANS_BUFFER,
                                247                 :                :                   LWTRANCHE_SUBTRANS_SLRU, SYNC_HANDLER_NONE, false);
 1884 noah@leadboat.com         248                 :           1150 :     SlruPagePrecedesUnitTests(SubTransCtl, SUBTRANS_XACTS_PER_PAGE);
 7927 tgl@sss.pgh.pa.us         249                 :           1150 : }
                                250                 :                : 
                                251                 :                : /*
                                252                 :                :  * GUC check_hook for subtransaction_buffers
                                253                 :                :  */
                                254                 :                : bool
  746 alvherre@alvh.no-ip.      255                 :           2346 : check_subtrans_buffers(int *newval, void **extra, GucSource source)
                                256                 :                : {
                                257                 :           2346 :     return check_slru_buffers("subtransaction_buffers", newval);
                                258                 :                : }
                                259                 :                : 
                                260                 :                : /*
                                261                 :                :  * This func must be called ONCE on system install.  It creates
                                262                 :                :  * the initial SUBTRANS segment.  (The SUBTRANS directory is assumed to
                                263                 :                :  * have been created by the initdb shell script, and SUBTRANSShmemInit
                                264                 :                :  * must have been called already.)
                                265                 :                :  *
                                266                 :                :  * Note: it's not really necessary to create the initial segment now,
                                267                 :                :  * since slru.c would create it on first write anyway.  But we may as well
                                268                 :                :  * do it to be sure the directory is set up correctly.
                                269                 :                :  */
                                270                 :                : void
 7927 tgl@sss.pgh.pa.us         271                 :             51 : BootStrapSUBTRANS(void)
                                272                 :                : {
                                273                 :                :     /* Zero the initial page and flush it to disk */
  251 alvherre@kurilemu.de      274                 :GNC          51 :     SimpleLruZeroAndWritePage(SubTransCtl, 0);
 7927 tgl@sss.pgh.pa.us         275                 :GIC          51 : }
                                276                 :                : 
                                277                 :                : /*
                                278                 :                :  * This must be called ONCE during postmaster or standalone-backend startup,
                                279                 :                :  * after StartupXLOG has initialized TransamVariables->nextXid.
                                280                 :                :  *
                                281                 :                :  * oldestActiveXID is the oldest XID of any prepared transaction, or nextXid
                                282                 :                :  * if there are none.
                                283                 :                :  */
                                284                 :                : void
 7576 tgl@sss.pgh.pa.us         285                 :CBC         998 : StartupSUBTRANS(TransactionId oldestActiveXID)
                                286                 :                : {
                                287                 :                :     FullTransactionId nextXid;
                                288                 :                :     int64       startPage;
                                289                 :                :     int64       endPage;
  740 alvherre@alvh.no-ip.      290                 :            998 :     LWLock     *prevlock = NULL;
                                291                 :                :     LWLock     *lock;
                                292                 :                : 
                                293                 :                :     /*
                                294                 :                :      * Since we don't expect pg_subtrans to be valid across crashes, we
                                295                 :                :      * initialize the currently-active page(s) to zeroes during startup.
                                296                 :                :      * Whenever we advance into a new page, ExtendSUBTRANS will likewise zero
                                297                 :                :      * the new page without regard to whatever was previously on disk.
                                298                 :                :      */
 7576 tgl@sss.pgh.pa.us         299                 :            998 :     startPage = TransactionIdToPage(oldestActiveXID);
  828 heikki.linnakangas@i      300                 :            998 :     nextXid = TransamVariables->nextXid;
 2042 andres@anarazel.de        301                 :            998 :     endPage = TransactionIdToPage(XidFromFullTransactionId(nextXid));
                                302                 :                : 
                                303                 :                :     for (;;)
                                304                 :                :     {
  746 alvherre@alvh.no-ip.      305                 :           1000 :         lock = SimpleLruGetBankLock(SubTransCtl, startPage);
                                306         [ +  - ]:           1000 :         if (prevlock != lock)
                                307                 :                :         {
  740                           308         [ +  + ]:           1000 :             if (prevlock)
                                309                 :              2 :                 LWLockRelease(prevlock);
  746                           310                 :           1000 :             LWLockAcquire(lock, LW_EXCLUSIVE);
                                311                 :           1000 :             prevlock = lock;
                                312                 :                :         }
                                313                 :                : 
  251 alvherre@kurilemu.de      314                 :GNC        1000 :         (void) SimpleLruZeroPage(SubTransCtl, startPage);
  740 alvherre@alvh.no-ip.      315         [ +  + ]:CBC        1000 :         if (startPage == endPage)
                                316                 :            998 :             break;
                                317                 :                : 
 7576 tgl@sss.pgh.pa.us         318                 :              2 :         startPage++;
                                319                 :                :         /* must account for wraparound */
 3677 simon@2ndQuadrant.co      320         [ -  + ]:              2 :         if (startPage > TransactionIdToPage(MaxTransactionId))
 3566 rhaas@postgresql.org      321                 :UBC           0 :             startPage = 0;
                                322                 :                :     }
                                323                 :                : 
  746 alvherre@alvh.no-ip.      324                 :CBC         998 :     LWLockRelease(lock);
 7927 tgl@sss.pgh.pa.us         325                 :            998 : }
                                326                 :                : 
                                327                 :                : /*
                                328                 :                :  * Perform a checkpoint --- either during shutdown, or on-the-fly
                                329                 :                :  */
                                330                 :                : void
                                331                 :           1802 : CheckPointSUBTRANS(void)
                                332                 :                : {
                                333                 :                :     /*
                                334                 :                :      * Write dirty SUBTRANS pages to disk
                                335                 :                :      *
                                336                 :                :      * This is not actually necessary from a correctness point of view. We do
                                337                 :                :      * it merely to improve the odds that writing of dirty pages is done by
                                338                 :                :      * the checkpoint process and not by backends.
                                339                 :                :      */
                                340                 :                :     TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_START(true);
 1997 tmunro@postgresql.or      341                 :           1802 :     SimpleLruWriteAll(SubTransCtl, true);
                                342                 :                :     TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_DONE(true);
 7927 tgl@sss.pgh.pa.us         343                 :           1802 : }
                                344                 :                : 
                                345                 :                : 
                                346                 :                : /*
                                347                 :                :  * Make sure that SUBTRANS has room for a newly-allocated XID.
                                348                 :                :  *
                                349                 :                :  * NB: this is called while holding XidGenLock.  We want it to be very fast
                                350                 :                :  * most of the time; even when it's not so fast, no actual I/O need happen
                                351                 :                :  * unless we're forced to write out a dirty subtrans page to make room
                                352                 :                :  * in shared memory.
                                353                 :                :  */
                                354                 :                : void
                                355                 :         162913 : ExtendSUBTRANS(TransactionId newestXact)
                                356                 :                : {
                                357                 :                :     int64       pageno;
                                358                 :                :     LWLock     *lock;
                                359                 :                : 
                                360                 :                :     /*
                                361                 :                :      * No work except at first XID of a page.  But beware: just after
                                362                 :                :      * wraparound, the first XID of page zero is FirstNormalTransactionId.
                                363                 :                :      */
                                364   [ +  +  +  + ]:         162913 :     if (TransactionIdToEntry(newestXact) != 0 &&
                                365                 :                :         !TransactionIdEquals(newestXact, FirstNormalTransactionId))
                                366                 :         162811 :         return;
                                367                 :                : 
                                368                 :            102 :     pageno = TransactionIdToPage(newestXact);
                                369                 :                : 
  746 alvherre@alvh.no-ip.      370                 :            102 :     lock = SimpleLruGetBankLock(SubTransCtl, pageno);
                                371                 :            102 :     LWLockAcquire(lock, LW_EXCLUSIVE);
                                372                 :                : 
                                373                 :                :     /* Zero the page */
  251 alvherre@kurilemu.de      374                 :GNC         102 :     SimpleLruZeroPage(SubTransCtl, pageno);
                                375                 :                : 
  746 alvherre@alvh.no-ip.      376                 :CBC         102 :     LWLockRelease(lock);
                                377                 :                : }
                                378                 :                : 
                                379                 :                : 
                                380                 :                : /*
                                381                 :                :  * Remove all SUBTRANS segments before the one holding the passed transaction ID
                                382                 :                :  *
                                383                 :                :  * oldestXact is the oldest TransactionXmin of any running transaction.  This
                                384                 :                :  * is called only during checkpoint.
                                385                 :                :  */
                                386                 :                : void
 7927 tgl@sss.pgh.pa.us         387                 :           1772 : TruncateSUBTRANS(TransactionId oldestXact)
                                388                 :                : {
                                389                 :                :     int64       cutoffPage;
                                390                 :                : 
                                391                 :                :     /*
                                392                 :                :      * The cutoff point is the start of the segment containing oldestXact. We
                                393                 :                :      * pass the *page* containing oldestXact to SimpleLruTruncate.  We step
                                394                 :                :      * back one transaction to avoid passing a cutoff page that hasn't been
                                395                 :                :      * created yet in the rare case that oldestXact would be the first item on
                                396                 :                :      * a page and oldestXact == next XID.  In that case, if we didn't subtract
                                397                 :                :      * one, we'd trigger SimpleLruTruncate's wraparound detection.
                                398                 :                :      */
 3888 heikki.linnakangas@i      399         [ +  + ]:           1931 :     TransactionIdRetreat(oldestXact);
 7927 tgl@sss.pgh.pa.us         400                 :           1772 :     cutoffPage = TransactionIdToPage(oldestXact);
                                401                 :                : 
                                402                 :           1772 :     SimpleLruTruncate(SubTransCtl, cutoffPage);
                                403                 :           1772 : }
                                404                 :                : 
                                405                 :                : 
                                406                 :                : /*
                                407                 :                :  * Decide whether a SUBTRANS page number is "older" for truncation purposes.
                                408                 :                :  * Analogous to CLOGPagePrecedes().
                                409                 :                :  */
                                410                 :                : static bool
  837 akorotkov@postgresql      411                 :          50684 : SubTransPagePrecedes(int64 page1, int64 page2)
                                412                 :                : {
                                413                 :                :     TransactionId xid1;
                                414                 :                :     TransactionId xid2;
                                415                 :                : 
 7927 tgl@sss.pgh.pa.us         416                 :          50684 :     xid1 = ((TransactionId) page1) * SUBTRANS_XACTS_PER_PAGE;
 1884 noah@leadboat.com         417                 :          50684 :     xid1 += FirstNormalTransactionId + 1;
 7927 tgl@sss.pgh.pa.us         418                 :          50684 :     xid2 = ((TransactionId) page2) * SUBTRANS_XACTS_PER_PAGE;
 1884 noah@leadboat.com         419                 :          50684 :     xid2 += FirstNormalTransactionId + 1;
                                420                 :                : 
                                421   [ +  +  +  + ]:          81022 :     return (TransactionIdPrecedes(xid1, xid2) &&
                                422                 :          30338 :             TransactionIdPrecedes(xid1, xid2 + SUBTRANS_XACTS_PER_PAGE - 1));
                                423                 :                : }
                                424                 :                : 
                                425                 :                : static int
    2 heikki.linnakangas@i      426                 :UNC           0 : subtrans_errdetail_for_io_error(const void *opaque_data)
                                427                 :                : {
                                428                 :              0 :     TransactionId xid = *(const TransactionId *) opaque_data;
                                429                 :                : 
                                430                 :              0 :     return errdetail("Could not access subtransaction status of transaction %u.", xid);
                                431                 :                : }
        

Generated by: LCOV version 2.4-beta