LCOV - differential code coverage report
Current view: top level - src/backend/access/transam - subtrans.c (source / functions) Coverage Total Hit UBC GIC GNC CBC DCB
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 95.3 % 107 102 5 1 3 98 11
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 14 14 3 11 1
Baseline: lcov-20250906-005545-baseline Branches: 69.2 % 52 36 16 36
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 100.0 % 3 3 3
(360..) days: 95.2 % 104 99 5 1 98
Function coverage date bins:
(360..) days: 100.0 % 14 14 3 11
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-2025, 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
  647 akorotkov@postgresql       61                 :CBC       12177 : TransactionIdToPage(TransactionId xid)
                                 62                 :                : {
                                 63                 :          12177 :     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                 :                : 
                                 79                 :                : 
                                 80                 :                : /*
                                 81                 :                :  * Record the parent of a subtransaction in the subtrans log.
                                 82                 :                :  */
                                 83                 :                : void
 3054 simon@2ndQuadrant.co       84                 :           5574 : SubTransSetParent(TransactionId xid, TransactionId parent)
                                 85                 :                : {
  647 akorotkov@postgresql       86                 :           5574 :     int64       pageno = TransactionIdToPage(xid);
 7737 tgl@sss.pgh.pa.us          87                 :           5574 :     int         entryno = TransactionIdToEntry(xid);
                                 88                 :                :     int         slotno;
                                 89                 :                :     LWLock     *lock;
                                 90                 :                :     TransactionId *ptr;
                                 91                 :                : 
 5740 simon@2ndQuadrant.co       92         [ -  + ]:           5574 :     Assert(TransactionIdIsValid(parent));
 3054                            93         [ -  + ]:           5574 :     Assert(TransactionIdFollows(xid, parent));
                                 94                 :                : 
  556 alvherre@alvh.no-ip.       95                 :           5574 :     lock = SimpleLruGetBankLock(SubTransCtl, pageno);
                                 96                 :           5574 :     LWLockAcquire(lock, LW_EXCLUSIVE);
                                 97                 :                : 
 6611 tgl@sss.pgh.pa.us          98                 :           5574 :     slotno = SimpleLruReadPage(SubTransCtl, pageno, true, xid);
 7684                            99                 :           5574 :     ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
 7737                           100                 :           5574 :     ptr += entryno;
                                101                 :                : 
                                102                 :                :     /*
                                103                 :                :      * It's possible we'll try to set the parent xid multiple times but we
                                104                 :                :      * shouldn't ever be changing the xid from one valid xid to another valid
                                105                 :                :      * xid, which would corrupt the data structure.
                                106                 :                :      */
 3054 simon@2ndQuadrant.co      107         [ +  + ]:           5574 :     if (*ptr != parent)
                                108                 :                :     {
                                109         [ -  + ]:           4988 :         Assert(*ptr == InvalidTransactionId);
                                110                 :           4988 :         *ptr = parent;
                                111                 :           4988 :         SubTransCtl->shared->page_dirty[slotno] = true;
                                112                 :                :     }
                                113                 :                : 
  556 alvherre@alvh.no-ip.      114                 :           5574 :     LWLockRelease(lock);
 7737 tgl@sss.pgh.pa.us         115                 :           5574 : }
                                116                 :                : 
                                117                 :                : /*
                                118                 :                :  * Interrogate the parent of a transaction in the subtrans log.
                                119                 :                :  */
                                120                 :                : TransactionId
                                121                 :           3087 : SubTransGetParent(TransactionId xid)
                                122                 :                : {
  647 akorotkov@postgresql      123                 :           3087 :     int64       pageno = TransactionIdToPage(xid);
 7737 tgl@sss.pgh.pa.us         124                 :           3087 :     int         entryno = TransactionIdToEntry(xid);
                                125                 :                :     int         slotno;
                                126                 :                :     TransactionId *ptr;
                                127                 :                :     TransactionId parent;
                                128                 :                : 
                                129                 :                :     /* Can't ask about stuff that might not be around anymore */
 7660                           130         [ -  + ]:           3087 :     Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
                                131                 :                : 
                                132                 :                :     /* Bootstrap and frozen XIDs have no parent */
 7737                           133         [ -  + ]:           3087 :     if (!TransactionIdIsNormal(xid))
 7737 tgl@sss.pgh.pa.us         134                 :UBC           0 :         return InvalidTransactionId;
                                135                 :                : 
                                136                 :                :     /* lock is acquired by SimpleLruReadPage_ReadOnly */
                                137                 :                : 
 7214 tgl@sss.pgh.pa.us         138                 :CBC        3087 :     slotno = SimpleLruReadPage_ReadOnly(SubTransCtl, pageno, xid);
 7684                           139                 :           3087 :     ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
 7737                           140                 :           3087 :     ptr += entryno;
                                141                 :                : 
                                142                 :           3087 :     parent = *ptr;
                                143                 :                : 
  556 alvherre@alvh.no-ip.      144                 :           3087 :     LWLockRelease(SimpleLruGetBankLock(SubTransCtl, pageno));
                                145                 :                : 
 7737 tgl@sss.pgh.pa.us         146                 :           3087 :     return parent;
                                147                 :                : }
                                148                 :                : 
                                149                 :                : /*
                                150                 :                :  * SubTransGetTopmostTransaction
                                151                 :                :  *
                                152                 :                :  * Returns the topmost transaction of the given transaction id.
                                153                 :                :  *
                                154                 :                :  * Because we cannot look back further than TransactionXmin, it is possible
                                155                 :                :  * that this function will lie and return an intermediate subtransaction ID
                                156                 :                :  * instead of the true topmost parent ID.  This is OK, because in practice
                                157                 :                :  * we only care about detecting whether the topmost parent is still running
                                158                 :                :  * or is part of a current snapshot's list of still-running transactions.
                                159                 :                :  * Therefore, any XID before TransactionXmin is as good as any other.
                                160                 :                :  */
                                161                 :                : TransactionId
                                162                 :           1081 : SubTransGetTopmostTransaction(TransactionId xid)
                                163                 :                : {
                                164                 :           1081 :     TransactionId parentXid = xid,
 7678 bruce@momjian.us          165                 :           1081 :                 previousXid = xid;
                                166                 :                : 
                                167                 :                :     /* Can't ask about stuff that might not be around anymore */
 7660 tgl@sss.pgh.pa.us         168         [ -  + ]:           1081 :     Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
                                169                 :                : 
 7737                           170         [ +  + ]:           4168 :     while (TransactionIdIsValid(parentXid))
                                171                 :                :     {
                                172                 :           3087 :         previousXid = parentXid;
 7660                           173         [ -  + ]:           3087 :         if (TransactionIdPrecedes(parentXid, TransactionXmin))
 7685 tgl@sss.pgh.pa.us         174                 :UBC           0 :             break;
 7737 tgl@sss.pgh.pa.us         175                 :CBC        3087 :         parentXid = SubTransGetParent(parentXid);
                                176                 :                : 
                                177                 :                :         /*
                                178                 :                :          * By convention the parent xid gets allocated first, so should always
                                179                 :                :          * precede the child xid. Anything else points to a corrupted data
                                180                 :                :          * structure that could lead to an infinite loop, so exit.
                                181                 :                :          */
 3054 simon@2ndQuadrant.co      182         [ -  + ]:           3087 :         if (!TransactionIdPrecedes(parentXid, previousXid))
 3054 simon@2ndQuadrant.co      183         [ #  # ]:UBC           0 :             elog(ERROR, "pg_subtrans contains invalid entry: xid %u points to parent xid %u",
                                184                 :                :                  previousXid, parentXid);
                                185                 :                :     }
                                186                 :                : 
 7737 tgl@sss.pgh.pa.us         187         [ -  + ]:CBC        1081 :     Assert(TransactionIdIsValid(previousXid));
                                188                 :                : 
                                189                 :           1081 :     return previousXid;
                                190                 :                : }
                                191                 :                : 
                                192                 :                : /*
                                193                 :                :  * Number of shared SUBTRANS buffers.
                                194                 :                :  *
                                195                 :                :  * If asked to autotune, use 2MB for every 1GB of shared buffers, up to 8MB.
                                196                 :                :  * Otherwise just cap the configured amount to be between 16 and the maximum
                                197                 :                :  * allowed.
                                198                 :                :  */
                                199                 :                : static int
  556 alvherre@alvh.no-ip.      200                 :           3956 : SUBTRANSShmemBuffers(void)
                                201                 :                : {
                                202                 :                :     /* auto-tune based on shared buffers */
                                203         [ +  + ]:           3956 :     if (subtransaction_buffers == 0)
                                204                 :           2909 :         return SimpleLruAutotuneBuffers(512, 1024);
                                205                 :                : 
                                206         [ +  - ]:           1047 :     return Min(Max(16, subtransaction_buffers), SLRU_MAX_ALLOWED_BUFFERS);
                                207                 :                : }
                                208                 :                : 
                                209                 :                : /*
                                210                 :                :  * Initialization of shared memory for SUBTRANS
                                211                 :                :  */
                                212                 :                : Size
 7737 tgl@sss.pgh.pa.us         213                 :           1909 : SUBTRANSShmemSize(void)
                                214                 :                : {
  556 alvherre@alvh.no-ip.      215                 :           1909 :     return SimpleLruShmemSize(SUBTRANSShmemBuffers(), 0);
                                216                 :                : }
                                217                 :                : 
                                218                 :                : void
 7737 tgl@sss.pgh.pa.us         219                 :           1029 : SUBTRANSShmemInit(void)
                                220                 :                : {
                                221                 :                :     /* If auto-tuning is requested, now is the time to do it */
  556 alvherre@alvh.no-ip.      222         [ +  + ]:           1029 :     if (subtransaction_buffers == 0)
                                223                 :                :     {
                                224                 :                :         char        buf[32];
                                225                 :                : 
                                226                 :           1018 :         snprintf(buf, sizeof(buf), "%d", SUBTRANSShmemBuffers());
                                227                 :           1018 :         SetConfigOption("subtransaction_buffers", buf, PGC_POSTMASTER,
                                228                 :                :                         PGC_S_DYNAMIC_DEFAULT);
                                229                 :                : 
                                230                 :                :         /*
                                231                 :                :          * We prefer to report this value's source as PGC_S_DYNAMIC_DEFAULT.
                                232                 :                :          * However, if the DBA explicitly set subtransaction_buffers = 0 in
                                233                 :                :          * the config file, then PGC_S_DYNAMIC_DEFAULT will fail to override
                                234                 :                :          * that and we must force the matter with PGC_S_OVERRIDE.
                                235                 :                :          */
                                236         [ -  + ]:           1018 :         if (subtransaction_buffers == 0)    /* failed to apply it? */
  556 alvherre@alvh.no-ip.      237                 :UBC           0 :             SetConfigOption("subtransaction_buffers", buf, PGC_POSTMASTER,
                                238                 :                :                             PGC_S_OVERRIDE);
                                239                 :                :     }
  556 alvherre@alvh.no-ip.      240         [ -  + ]:CBC        1029 :     Assert(subtransaction_buffers != 0);
                                241                 :                : 
 7737 tgl@sss.pgh.pa.us         242                 :           1029 :     SubTransCtl->PagePrecedes = SubTransPagePrecedes;
  556 alvherre@alvh.no-ip.      243                 :           1029 :     SimpleLruInit(SubTransCtl, "subtransaction", SUBTRANSShmemBuffers(), 0,
                                244                 :                :                   "pg_subtrans", LWTRANCHE_SUBTRANS_BUFFER,
                                245                 :                :                   LWTRANCHE_SUBTRANS_SLRU, SYNC_HANDLER_NONE, false);
 1694 noah@leadboat.com         246                 :           1029 :     SlruPagePrecedesUnitTests(SubTransCtl, SUBTRANS_XACTS_PER_PAGE);
 7737 tgl@sss.pgh.pa.us         247                 :           1029 : }
                                248                 :                : 
                                249                 :                : /*
                                250                 :                :  * GUC check_hook for subtransaction_buffers
                                251                 :                :  */
                                252                 :                : bool
  556 alvherre@alvh.no-ip.      253                 :           2110 : check_subtrans_buffers(int *newval, void **extra, GucSource source)
                                254                 :                : {
                                255                 :           2110 :     return check_slru_buffers("subtransaction_buffers", newval);
                                256                 :                : }
                                257                 :                : 
                                258                 :                : /*
                                259                 :                :  * This func must be called ONCE on system install.  It creates
                                260                 :                :  * the initial SUBTRANS segment.  (The SUBTRANS directory is assumed to
                                261                 :                :  * have been created by the initdb shell script, and SUBTRANSShmemInit
                                262                 :                :  * must have been called already.)
                                263                 :                :  *
                                264                 :                :  * Note: it's not really necessary to create the initial segment now,
                                265                 :                :  * since slru.c would create it on first write anyway.  But we may as well
                                266                 :                :  * do it to be sure the directory is set up correctly.
                                267                 :                :  */
                                268                 :                : void
 7737 tgl@sss.pgh.pa.us         269                 :             50 : BootStrapSUBTRANS(void)
                                270                 :                : {
                                271                 :                :     /* Zero the initial page and flush it to disk */
   61 alvherre@kurilemu.de      272                 :GNC          50 :     SimpleLruZeroAndWritePage(SubTransCtl, 0);
 7737 tgl@sss.pgh.pa.us         273                 :GIC          50 : }
                                274                 :                : 
                                275                 :                : /*
                                276                 :                :  * This must be called ONCE during postmaster or standalone-backend startup,
                                277                 :                :  * after StartupXLOG has initialized TransamVariables->nextXid.
                                278                 :                :  *
                                279                 :                :  * oldestActiveXID is the oldest XID of any prepared transaction, or nextXid
                                280                 :                :  * if there are none.
                                281                 :                :  */
                                282                 :                : void
 7386 tgl@sss.pgh.pa.us         283                 :CBC         885 : StartupSUBTRANS(TransactionId oldestActiveXID)
                                284                 :                : {
                                285                 :                :     FullTransactionId nextXid;
                                286                 :                :     int64       startPage;
                                287                 :                :     int64       endPage;
  550 alvherre@alvh.no-ip.      288                 :            885 :     LWLock     *prevlock = NULL;
                                289                 :                :     LWLock     *lock;
                                290                 :                : 
                                291                 :                :     /*
                                292                 :                :      * Since we don't expect pg_subtrans to be valid across crashes, we
                                293                 :                :      * initialize the currently-active page(s) to zeroes during startup.
                                294                 :                :      * Whenever we advance into a new page, ExtendSUBTRANS will likewise zero
                                295                 :                :      * the new page without regard to whatever was previously on disk.
                                296                 :                :      */
 7386 tgl@sss.pgh.pa.us         297                 :            885 :     startPage = TransactionIdToPage(oldestActiveXID);
  638 heikki.linnakangas@i      298                 :            885 :     nextXid = TransamVariables->nextXid;
 1852 andres@anarazel.de        299                 :            885 :     endPage = TransactionIdToPage(XidFromFullTransactionId(nextXid));
                                300                 :                : 
                                301                 :                :     for (;;)
                                302                 :                :     {
  556 alvherre@alvh.no-ip.      303                 :            887 :         lock = SimpleLruGetBankLock(SubTransCtl, startPage);
                                304         [ +  - ]:            887 :         if (prevlock != lock)
                                305                 :                :         {
  550                           306         [ +  + ]:            887 :             if (prevlock)
                                307                 :              2 :                 LWLockRelease(prevlock);
  556                           308                 :            887 :             LWLockAcquire(lock, LW_EXCLUSIVE);
                                309                 :            887 :             prevlock = lock;
                                310                 :                :         }
                                311                 :                : 
   61 alvherre@kurilemu.de      312                 :GNC         887 :         (void) SimpleLruZeroPage(SubTransCtl, startPage);
  550 alvherre@alvh.no-ip.      313         [ +  + ]:CBC         887 :         if (startPage == endPage)
                                314                 :            885 :             break;
                                315                 :                : 
 7386 tgl@sss.pgh.pa.us         316                 :              2 :         startPage++;
                                317                 :                :         /* must account for wraparound */
 3487 simon@2ndQuadrant.co      318         [ -  + ]:              2 :         if (startPage > TransactionIdToPage(MaxTransactionId))
 3376 rhaas@postgresql.org      319                 :UBC           0 :             startPage = 0;
                                320                 :                :     }
                                321                 :                : 
  556 alvherre@alvh.no-ip.      322                 :CBC         885 :     LWLockRelease(lock);
 7737 tgl@sss.pgh.pa.us         323                 :            885 : }
                                324                 :                : 
                                325                 :                : /*
                                326                 :                :  * Perform a checkpoint --- either during shutdown, or on-the-fly
                                327                 :                :  */
                                328                 :                : void
                                329                 :           1677 : CheckPointSUBTRANS(void)
                                330                 :                : {
                                331                 :                :     /*
                                332                 :                :      * Write dirty SUBTRANS pages to disk
                                333                 :                :      *
                                334                 :                :      * This is not actually necessary from a correctness point of view. We do
                                335                 :                :      * it merely to improve the odds that writing of dirty pages is done by
                                336                 :                :      * the checkpoint process and not by backends.
                                337                 :                :      */
                                338                 :                :     TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_START(true);
 1807 tmunro@postgresql.or      339                 :           1677 :     SimpleLruWriteAll(SubTransCtl, true);
                                340                 :                :     TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_DONE(true);
 7737 tgl@sss.pgh.pa.us         341                 :           1677 : }
                                342                 :                : 
                                343                 :                : 
                                344                 :                : /*
                                345                 :                :  * Make sure that SUBTRANS has room for a newly-allocated XID.
                                346                 :                :  *
                                347                 :                :  * NB: this is called while holding XidGenLock.  We want it to be very fast
                                348                 :                :  * most of the time; even when it's not so fast, no actual I/O need happen
                                349                 :                :  * unless we're forced to write out a dirty subtrans page to make room
                                350                 :                :  * in shared memory.
                                351                 :                :  */
                                352                 :                : void
                                353                 :         154095 : ExtendSUBTRANS(TransactionId newestXact)
                                354                 :                : {
                                355                 :                :     int64       pageno;
                                356                 :                :     LWLock     *lock;
                                357                 :                : 
                                358                 :                :     /*
                                359                 :                :      * No work except at first XID of a page.  But beware: just after
                                360                 :                :      * wraparound, the first XID of page zero is FirstNormalTransactionId.
                                361                 :                :      */
                                362   [ +  +  +  + ]:         154095 :     if (TransactionIdToEntry(newestXact) != 0 &&
                                363                 :                :         !TransactionIdEquals(newestXact, FirstNormalTransactionId))
                                364                 :         154000 :         return;
                                365                 :                : 
                                366                 :             95 :     pageno = TransactionIdToPage(newestXact);
                                367                 :                : 
  556 alvherre@alvh.no-ip.      368                 :             95 :     lock = SimpleLruGetBankLock(SubTransCtl, pageno);
                                369                 :             95 :     LWLockAcquire(lock, LW_EXCLUSIVE);
                                370                 :                : 
                                371                 :                :     /* Zero the page */
   61 alvherre@kurilemu.de      372                 :GNC          95 :     SimpleLruZeroPage(SubTransCtl, pageno);
                                373                 :                : 
  556 alvherre@alvh.no-ip.      374                 :CBC          95 :     LWLockRelease(lock);
                                375                 :                : }
                                376                 :                : 
                                377                 :                : 
                                378                 :                : /*
                                379                 :                :  * Remove all SUBTRANS segments before the one holding the passed transaction ID
                                380                 :                :  *
                                381                 :                :  * oldestXact is the oldest TransactionXmin of any running transaction.  This
                                382                 :                :  * is called only during checkpoint.
                                383                 :                :  */
                                384                 :                : void
 7737 tgl@sss.pgh.pa.us         385                 :           1649 : TruncateSUBTRANS(TransactionId oldestXact)
                                386                 :                : {
                                387                 :                :     int64       cutoffPage;
                                388                 :                : 
                                389                 :                :     /*
                                390                 :                :      * The cutoff point is the start of the segment containing oldestXact. We
                                391                 :                :      * pass the *page* containing oldestXact to SimpleLruTruncate.  We step
                                392                 :                :      * back one transaction to avoid passing a cutoff page that hasn't been
                                393                 :                :      * created yet in the rare case that oldestXact would be the first item on
                                394                 :                :      * a page and oldestXact == next XID.  In that case, if we didn't subtract
                                395                 :                :      * one, we'd trigger SimpleLruTruncate's wraparound detection.
                                396                 :                :      */
 3698 heikki.linnakangas@i      397         [ +  + ]:           1805 :     TransactionIdRetreat(oldestXact);
 7737 tgl@sss.pgh.pa.us         398                 :           1649 :     cutoffPage = TransactionIdToPage(oldestXact);
                                399                 :                : 
                                400                 :           1649 :     SimpleLruTruncate(SubTransCtl, cutoffPage);
                                401                 :           1649 : }
                                402                 :                : 
                                403                 :                : 
                                404                 :                : /*
                                405                 :                :  * Decide whether a SUBTRANS page number is "older" for truncation purposes.
                                406                 :                :  * Analogous to CLOGPagePrecedes().
                                407                 :                :  */
                                408                 :                : static bool
  647 akorotkov@postgresql      409                 :          45517 : SubTransPagePrecedes(int64 page1, int64 page2)
                                410                 :                : {
                                411                 :                :     TransactionId xid1;
                                412                 :                :     TransactionId xid2;
                                413                 :                : 
 7737 tgl@sss.pgh.pa.us         414                 :          45517 :     xid1 = ((TransactionId) page1) * SUBTRANS_XACTS_PER_PAGE;
 1694 noah@leadboat.com         415                 :          45517 :     xid1 += FirstNormalTransactionId + 1;
 7737 tgl@sss.pgh.pa.us         416                 :          45517 :     xid2 = ((TransactionId) page2) * SUBTRANS_XACTS_PER_PAGE;
 1694 noah@leadboat.com         417                 :          45517 :     xid2 += FirstNormalTransactionId + 1;
                                418                 :                : 
                                419   [ +  +  +  + ]:          72686 :     return (TransactionIdPrecedes(xid1, xid2) &&
                                420                 :          27169 :             TransactionIdPrecedes(xid1, xid2 + SUBTRANS_XACTS_PER_PAGE - 1));
                                421                 :                : }
        

Generated by: LCOV version 2.4-beta