LCOV - differential code coverage report
Current view: top level - src/backend/access/transam - subtrans.c (source / functions) Coverage Total Hit UNC UBC GBC GNC CBC DCB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 95.6 % 114 109 1 4 3 40 66 19
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 15 15 12 3 2
Baseline: 16@8cea358b128 Branches: 68.5 % 54 37 4 13 1 12 24
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed [..60] days: 97.1 % 34 33 1 33
(120,180] days: 100.0 % 7 7 7
(240..) days: 94.5 % 73 69 4 3 66
Function coverage date bins:
[..60] days: 100.0 % 2 2 2
(120,180] days: 100.0 % 3 3 3
(240..) days: 100.0 % 10 10 7 3
Branch coverage date bins:
[..60] days: 75.0 % 16 12 4 12
(240..) days: 65.8 % 38 25 13 1 24

 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-2024, 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
  137 akorotkov@postgresql       61                 :GNC     6919350 : TransactionIdToPage(TransactionId xid)
                                 62                 :                : {
                                 63                 :        6919350 :     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 int  ZeroSUBTRANSPage(int64 pageno);
                                 78                 :                : static bool SubTransPagePrecedes(int64 page1, int64 page2);
                                 79                 :                : 
                                 80                 :                : 
                                 81                 :                : /*
                                 82                 :                :  * Record the parent of a subtransaction in the subtrans log.
                                 83                 :                :  */
                                 84                 :                : void
 2544 simon@2ndQuadrant.co       85                 :CBC        7013 : SubTransSetParent(TransactionId xid, TransactionId parent)
                                 86                 :                : {
  137 akorotkov@postgresql       87                 :GNC        7013 :     int64       pageno = TransactionIdToPage(xid);
 7227 tgl@sss.pgh.pa.us          88                 :CBC        7013 :     int         entryno = TransactionIdToEntry(xid);
                                 89                 :                :     int         slotno;
                                 90                 :                :     LWLock     *lock;
                                 91                 :                :     TransactionId *ptr;
                                 92                 :                : 
 5230 simon@2ndQuadrant.co       93         [ -  + ]:           7013 :     Assert(TransactionIdIsValid(parent));
 2544                            94         [ -  + ]:           7013 :     Assert(TransactionIdFollows(xid, parent));
                                 95                 :                : 
   46 alvherre@alvh.no-ip.       96                 :GNC        7013 :     lock = SimpleLruGetBankLock(SubTransCtl, pageno);
                                 97                 :           7013 :     LWLockAcquire(lock, LW_EXCLUSIVE);
                                 98                 :                : 
 6101 tgl@sss.pgh.pa.us          99                 :CBC        7013 :     slotno = SimpleLruReadPage(SubTransCtl, pageno, true, xid);
 7174                           100                 :           7013 :     ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
 7227                           101                 :           7013 :     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                 :                :      */
 2544 simon@2ndQuadrant.co      108         [ +  + ]:           7013 :     if (*ptr != parent)
                                109                 :                :     {
                                110         [ -  + ]:           6757 :         Assert(*ptr == InvalidTransactionId);
                                111                 :           6757 :         *ptr = parent;
                                112                 :           6757 :         SubTransCtl->shared->page_dirty[slotno] = true;
                                113                 :                :     }
                                114                 :                : 
   46 alvherre@alvh.no-ip.      115                 :GNC        7013 :     LWLockRelease(lock);
 7227 tgl@sss.pgh.pa.us         116                 :CBC        7013 : }
                                117                 :                : 
                                118                 :                : /*
                                119                 :                :  * Interrogate the parent of a transaction in the subtrans log.
                                120                 :                :  */
                                121                 :                : TransactionId
                                122                 :           3089 : SubTransGetParent(TransactionId xid)
                                123                 :                : {
  137 akorotkov@postgresql      124                 :GNC        3089 :     int64       pageno = TransactionIdToPage(xid);
 7227 tgl@sss.pgh.pa.us         125                 :CBC        3089 :     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 */
 7150                           131         [ -  + ]:           3089 :     Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
                                132                 :                : 
                                133                 :                :     /* Bootstrap and frozen XIDs have no parent */
 7227                           134         [ -  + ]:           3089 :     if (!TransactionIdIsNormal(xid))
 7227 tgl@sss.pgh.pa.us         135                 :UBC           0 :         return InvalidTransactionId;
                                136                 :                : 
                                137                 :                :     /* lock is acquired by SimpleLruReadPage_ReadOnly */
                                138                 :                : 
 6704 tgl@sss.pgh.pa.us         139                 :CBC        3089 :     slotno = SimpleLruReadPage_ReadOnly(SubTransCtl, pageno, xid);
 7174                           140                 :           3089 :     ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
 7227                           141                 :           3089 :     ptr += entryno;
                                142                 :                : 
                                143                 :           3089 :     parent = *ptr;
                                144                 :                : 
   46 alvherre@alvh.no-ip.      145                 :GNC        3089 :     LWLockRelease(SimpleLruGetBankLock(SubTransCtl, pageno));
                                146                 :                : 
 7227 tgl@sss.pgh.pa.us         147                 :CBC        3089 :     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                 :           1081 : SubTransGetTopmostTransaction(TransactionId xid)
                                164                 :                : {
                                165                 :           1081 :     TransactionId parentXid = xid,
 7168 bruce@momjian.us          166                 :           1081 :                 previousXid = xid;
                                167                 :                : 
                                168                 :                :     /* Can't ask about stuff that might not be around anymore */
 7150 tgl@sss.pgh.pa.us         169         [ -  + ]:           1081 :     Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
                                170                 :                : 
 7227                           171         [ +  + ]:           4170 :     while (TransactionIdIsValid(parentXid))
                                172                 :                :     {
                                173                 :           3089 :         previousXid = parentXid;
 7150                           174         [ -  + ]:           3089 :         if (TransactionIdPrecedes(parentXid, TransactionXmin))
 7175 tgl@sss.pgh.pa.us         175                 :UBC           0 :             break;
 7227 tgl@sss.pgh.pa.us         176                 :CBC        3089 :         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                 :                :          */
 2544 simon@2ndQuadrant.co      183         [ -  + ]:           3089 :         if (!TransactionIdPrecedes(parentXid, previousXid))
 2544 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                 :                : 
 7227 tgl@sss.pgh.pa.us         188         [ -  + ]:CBC        1081 :     Assert(TransactionIdIsValid(previousXid));
                                189                 :                : 
                                190                 :           1081 :     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
   46 alvherre@alvh.no-ip.      201                 :GNC        3464 : SUBTRANSShmemBuffers(void)
                                202                 :                : {
                                203                 :                :     /* auto-tune based on shared buffers */
                                204         [ +  + ]:           3464 :     if (subtransaction_buffers == 0)
                                205                 :           2549 :         return SimpleLruAutotuneBuffers(512, 1024);
                                206                 :                : 
                                207         [ +  - ]:            915 :     return Min(Max(16, subtransaction_buffers), SLRU_MAX_ALLOWED_BUFFERS);
                                208                 :                : }
                                209                 :                : 
                                210                 :                : /*
                                211                 :                :  * Initialization of shared memory for SUBTRANS
                                212                 :                :  */
                                213                 :                : Size
 7227 tgl@sss.pgh.pa.us         214                 :CBC        1679 : SUBTRANSShmemSize(void)
                                215                 :                : {
   46 alvherre@alvh.no-ip.      216                 :GNC        1679 :     return SimpleLruShmemSize(SUBTRANSShmemBuffers(), 0);
                                217                 :                : }
                                218                 :                : 
                                219                 :                : void
 7227 tgl@sss.pgh.pa.us         220                 :CBC         898 : SUBTRANSShmemInit(void)
                                221                 :                : {
                                222                 :                :     /* If auto-tuning is requested, now is the time to do it */
   46 alvherre@alvh.no-ip.      223         [ +  + ]:GNC         898 :     if (subtransaction_buffers == 0)
                                224                 :                :     {
                                225                 :                :         char        buf[32];
                                226                 :                : 
                                227                 :            887 :         snprintf(buf, sizeof(buf), "%d", SUBTRANSShmemBuffers());
                                228                 :            887 :         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         [ -  + ]:            887 :         if (subtransaction_buffers == 0)    /* failed to apply it? */
   46 alvherre@alvh.no-ip.      238                 :UNC           0 :             SetConfigOption("subtransaction_buffers", buf, PGC_POSTMASTER,
                                239                 :                :                             PGC_S_OVERRIDE);
                                240                 :                :     }
   46 alvherre@alvh.no-ip.      241         [ -  + ]:GNC         898 :     Assert(subtransaction_buffers != 0);
                                242                 :                : 
 7227 tgl@sss.pgh.pa.us         243                 :CBC         898 :     SubTransCtl->PagePrecedes = SubTransPagePrecedes;
   46 alvherre@alvh.no-ip.      244                 :GNC         898 :     SimpleLruInit(SubTransCtl, "subtransaction", SUBTRANSShmemBuffers(), 0,
                                245                 :                :                   "pg_subtrans", LWTRANCHE_SUBTRANS_BUFFER,
                                246                 :                :                   LWTRANCHE_SUBTRANS_SLRU, SYNC_HANDLER_NONE, false);
 1184 noah@leadboat.com         247                 :CBC         898 :     SlruPagePrecedesUnitTests(SubTransCtl, SUBTRANS_XACTS_PER_PAGE);
 7227 tgl@sss.pgh.pa.us         248                 :            898 : }
                                249                 :                : 
                                250                 :                : /*
                                251                 :                :  * GUC check_hook for subtransaction_buffers
                                252                 :                :  */
                                253                 :                : bool
   46 alvherre@alvh.no-ip.      254                 :GNC        1832 : check_subtrans_buffers(int *newval, void **extra, GucSource source)
                                255                 :                : {
                                256                 :           1832 :     return check_slru_buffers("subtransaction_buffers", newval);
                                257                 :                : }
                                258                 :                : 
                                259                 :                : /*
                                260                 :                :  * This func must be called ONCE on system install.  It creates
                                261                 :                :  * the initial SUBTRANS segment.  (The SUBTRANS directory is assumed to
                                262                 :                :  * have been created by the initdb shell script, and SUBTRANSShmemInit
                                263                 :                :  * must have been called already.)
                                264                 :                :  *
                                265                 :                :  * Note: it's not really necessary to create the initial segment now,
                                266                 :                :  * since slru.c would create it on first write anyway.  But we may as well
                                267                 :                :  * do it to be sure the directory is set up correctly.
                                268                 :                :  */
                                269                 :                : void
 7227 tgl@sss.pgh.pa.us         270                 :CBC          39 : BootStrapSUBTRANS(void)
                                271                 :                : {
                                272                 :                :     int         slotno;
   46 alvherre@alvh.no-ip.      273                 :GNC          39 :     LWLock     *lock = SimpleLruGetBankLock(SubTransCtl, 0);
                                274                 :                : 
                                275                 :             39 :     LWLockAcquire(lock, LW_EXCLUSIVE);
                                276                 :                : 
                                277                 :                :     /* Create and zero the first page of the subtrans log */
 7174 tgl@sss.pgh.pa.us         278                 :CBC          39 :     slotno = ZeroSUBTRANSPage(0);
                                279                 :                : 
                                280                 :                :     /* Make sure it's written out */
 4854 alvherre@alvh.no-ip.      281                 :             39 :     SimpleLruWritePage(SubTransCtl, slotno);
 6735 tgl@sss.pgh.pa.us         282         [ -  + ]:             39 :     Assert(!SubTransCtl->shared->page_dirty[slotno]);
                                283                 :                : 
   46 alvherre@alvh.no-ip.      284                 :GNC          39 :     LWLockRelease(lock);
 7227 tgl@sss.pgh.pa.us         285                 :CBC          39 : }
                                286                 :                : 
                                287                 :                : /*
                                288                 :                :  * Initialize (or reinitialize) a page of SUBTRANS to zeroes.
                                289                 :                :  *
                                290                 :                :  * The page is not actually written, just set up in shared memory.
                                291                 :                :  * The slot number of the new page is returned.
                                292                 :                :  *
                                293                 :                :  * Control lock must be held at entry, and will be held at exit.
                                294                 :                :  */
                                295                 :                : static int
  137 akorotkov@postgresql      296                 :GNC     6907427 : ZeroSUBTRANSPage(int64 pageno)
                                297                 :                : {
 7174 tgl@sss.pgh.pa.us         298                 :CBC     6907427 :     return SimpleLruZeroPage(SubTransCtl, pageno);
                                299                 :                : }
                                300                 :                : 
                                301                 :                : /*
                                302                 :                :  * This must be called ONCE during postmaster or standalone-backend startup,
                                303                 :                :  * after StartupXLOG has initialized TransamVariables->nextXid.
                                304                 :                :  *
                                305                 :                :  * oldestActiveXID is the oldest XID of any prepared transaction, or nextXid
                                306                 :                :  * if there are none.
                                307                 :                :  */
                                308                 :                : void
 6876                           309                 :            821 : StartupSUBTRANS(TransactionId oldestActiveXID)
                                310                 :                : {
                                311                 :                :     FullTransactionId nextXid;
                                312                 :                :     int64       startPage;
                                313                 :                :     int64       endPage;
   40 alvherre@alvh.no-ip.      314                 :GNC         821 :     LWLock     *prevlock = NULL;
                                315                 :                :     LWLock     *lock;
                                316                 :                : 
                                317                 :                :     /*
                                318                 :                :      * Since we don't expect pg_subtrans to be valid across crashes, we
                                319                 :                :      * initialize the currently-active page(s) to zeroes during startup.
                                320                 :                :      * Whenever we advance into a new page, ExtendSUBTRANS will likewise zero
                                321                 :                :      * the new page without regard to whatever was previously on disk.
                                322                 :                :      */
 6876 tgl@sss.pgh.pa.us         323                 :CBC         821 :     startPage = TransactionIdToPage(oldestActiveXID);
  128 heikki.linnakangas@i      324                 :GNC         821 :     nextXid = TransamVariables->nextXid;
 1342 andres@anarazel.de        325                 :CBC         821 :     endPage = TransactionIdToPage(XidFromFullTransactionId(nextXid));
                                326                 :                : 
                                327                 :                :     for (;;)
                                328                 :                :     {
   46 alvherre@alvh.no-ip.      329                 :GNC         823 :         lock = SimpleLruGetBankLock(SubTransCtl, startPage);
                                330         [ +  - ]:            823 :         if (prevlock != lock)
                                331                 :                :         {
   40                           332         [ +  + ]:            823 :             if (prevlock)
                                333                 :              2 :                 LWLockRelease(prevlock);
   46                           334                 :            823 :             LWLockAcquire(lock, LW_EXCLUSIVE);
                                335                 :            823 :             prevlock = lock;
                                336                 :                :         }
                                337                 :                : 
 6876 tgl@sss.pgh.pa.us         338                 :GBC         823 :         (void) ZeroSUBTRANSPage(startPage);
   40 alvherre@alvh.no-ip.      339         [ +  + ]:GNC         823 :         if (startPage == endPage)
                                340                 :            821 :             break;
                                341                 :                : 
 6876 tgl@sss.pgh.pa.us         342                 :GBC           2 :         startPage++;
                                343                 :                :         /* must account for wraparound */
 2977 simon@2ndQuadrant.co      344         [ -  + ]:              2 :         if (startPage > TransactionIdToPage(MaxTransactionId))
 2866 rhaas@postgresql.org      345                 :UBC           0 :             startPage = 0;
                                346                 :                :     }
                                347                 :                : 
   46 alvherre@alvh.no-ip.      348                 :GNC         821 :     LWLockRelease(lock);
 7227 tgl@sss.pgh.pa.us         349                 :CBC         821 : }
                                350                 :                : 
                                351                 :                : /*
                                352                 :                :  * Perform a checkpoint --- either during shutdown, or on-the-fly
                                353                 :                :  */
                                354                 :                : void
                                355                 :           1153 : CheckPointSUBTRANS(void)
                                356                 :                : {
                                357                 :                :     /*
                                358                 :                :      * Write dirty SUBTRANS pages to disk
                                359                 :                :      *
                                360                 :                :      * This is not actually necessary from a correctness point of view. We do
                                361                 :                :      * it merely to improve the odds that writing of dirty pages is done by
                                362                 :                :      * the checkpoint process and not by backends.
                                363                 :                :      */
                                364                 :                :     TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_START(true);
 1297 tmunro@postgresql.or      365                 :           1153 :     SimpleLruWriteAll(SubTransCtl, true);
                                366                 :                :     TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_DONE(true);
 7227 tgl@sss.pgh.pa.us         367                 :           1153 : }
                                368                 :                : 
                                369                 :                : 
                                370                 :                : /*
                                371                 :                :  * Make sure that SUBTRANS has room for a newly-allocated XID.
                                372                 :                :  *
                                373                 :                :  * NB: this is called while holding XidGenLock.  We want it to be very fast
                                374                 :                :  * most of the time; even when it's not so fast, no actual I/O need happen
                                375                 :                :  * unless we're forced to write out a dirty subtrans page to make room
                                376                 :                :  * in shared memory.
                                377                 :                :  */
                                378                 :                : void
                                379                 :       24504285 : ExtendSUBTRANS(TransactionId newestXact)
                                380                 :                : {
                                381                 :                :     int64       pageno;
                                382                 :                :     LWLock     *lock;
                                383                 :                : 
                                384                 :                :     /*
                                385                 :                :      * No work except at first XID of a page.  But beware: just after
                                386                 :                :      * wraparound, the first XID of page zero is FirstNormalTransactionId.
                                387                 :                :      */
                                388   [ +  +  +  + ]:       24504285 :     if (TransactionIdToEntry(newestXact) != 0 &&
                                389                 :                :         !TransactionIdEquals(newestXact, FirstNormalTransactionId))
                                390                 :       17597720 :         return;
                                391                 :                : 
                                392                 :        6906565 :     pageno = TransactionIdToPage(newestXact);
                                393                 :                : 
   46 alvherre@alvh.no-ip.      394                 :GNC     6906565 :     lock = SimpleLruGetBankLock(SubTransCtl, pageno);
                                395                 :        6906565 :     LWLockAcquire(lock, LW_EXCLUSIVE);
                                396                 :                : 
                                397                 :                :     /* Zero the page */
 7174 tgl@sss.pgh.pa.us         398                 :CBC     6906565 :     ZeroSUBTRANSPage(pageno);
                                399                 :                : 
   46 alvherre@alvh.no-ip.      400                 :GNC     6906565 :     LWLockRelease(lock);
                                401                 :                : }
                                402                 :                : 
                                403                 :                : 
                                404                 :                : /*
                                405                 :                :  * Remove all SUBTRANS segments before the one holding the passed transaction ID
                                406                 :                :  *
                                407                 :                :  * oldestXact is the oldest TransactionXmin of any running transaction.  This
                                408                 :                :  * is called only during checkpoint.
                                409                 :                :  */
                                410                 :                : void
 7227 tgl@sss.pgh.pa.us         411                 :CBC        1039 : TruncateSUBTRANS(TransactionId oldestXact)
                                412                 :                : {
                                413                 :                :     int64       cutoffPage;
                                414                 :                : 
                                415                 :                :     /*
                                416                 :                :      * The cutoff point is the start of the segment containing oldestXact. We
                                417                 :                :      * pass the *page* containing oldestXact to SimpleLruTruncate.  We step
                                418                 :                :      * back one transaction to avoid passing a cutoff page that hasn't been
                                419                 :                :      * created yet in the rare case that oldestXact would be the first item on
                                420                 :                :      * a page and oldestXact == next XID.  In that case, if we didn't subtract
                                421                 :                :      * one, we'd trigger SimpleLruTruncate's wraparound detection.
                                422                 :                :      */
 3188 heikki.linnakangas@i      423         [ +  + ]:           1162 :     TransactionIdRetreat(oldestXact);
 7227 tgl@sss.pgh.pa.us         424                 :           1039 :     cutoffPage = TransactionIdToPage(oldestXact);
                                425                 :                : 
                                426                 :           1039 :     SimpleLruTruncate(SubTransCtl, cutoffPage);
                                427                 :           1039 : }
                                428                 :                : 
                                429                 :                : 
                                430                 :                : /*
                                431                 :                :  * Decide whether a SUBTRANS page number is "older" for truncation purposes.
                                432                 :                :  * Analogous to CLOGPagePrecedes().
                                433                 :                :  */
                                434                 :                : static bool
  137 akorotkov@postgresql      435                 :GNC      263126 : SubTransPagePrecedes(int64 page1, int64 page2)
                                436                 :                : {
                                437                 :                :     TransactionId xid1;
                                438                 :                :     TransactionId xid2;
                                439                 :                : 
 7227 tgl@sss.pgh.pa.us         440                 :CBC      263126 :     xid1 = ((TransactionId) page1) * SUBTRANS_XACTS_PER_PAGE;
 1184 noah@leadboat.com         441                 :         263126 :     xid1 += FirstNormalTransactionId + 1;
 7227 tgl@sss.pgh.pa.us         442                 :         263126 :     xid2 = ((TransactionId) page2) * SUBTRANS_XACTS_PER_PAGE;
 1184 noah@leadboat.com         443                 :         263126 :     xid2 += FirstNormalTransactionId + 1;
                                444                 :                : 
                                445   [ +  +  +  + ]:         478682 :     return (TransactionIdPrecedes(xid1, xid2) &&
                                446                 :         215556 :             TransactionIdPrecedes(xid1, xid2 + SUBTRANS_XACTS_PER_PAGE - 1));
                                447                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622