LCOV - code coverage report
Current view: top level - src/backend/access/rmgrdesc - xactdesc.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 288 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 12 0
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 0.0 % 84 0

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * xactdesc.c
       4                 :             :  *        rmgr descriptor routines for access/transam/xact.c
       5                 :             :  *
       6                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :             :  *
       9                 :             :  *
      10                 :             :  * IDENTIFICATION
      11                 :             :  *        src/backend/access/rmgrdesc/xactdesc.c
      12                 :             :  *
      13                 :             :  *-------------------------------------------------------------------------
      14                 :             :  */
      15                 :             : #include "postgres.h"
      16                 :             : 
      17                 :             : #include "access/transam.h"
      18                 :             : #include "access/xact.h"
      19                 :             : #include "replication/origin.h"
      20                 :             : #include "storage/sinval.h"
      21                 :             : #include "storage/standbydefs.h"
      22                 :             : #include "utils/timestamp.h"
      23                 :             : 
      24                 :             : /*
      25                 :             :  * Parse the WAL format of an xact commit and abort records into an easier to
      26                 :             :  * understand format.
      27                 :             :  *
      28                 :             :  * These routines are in xactdesc.c because they're accessed in backend (when
      29                 :             :  * replaying WAL) and frontend (pg_waldump) code. This file is the only xact
      30                 :             :  * specific one shared between both. They're complicated enough that
      31                 :             :  * duplication would be bothersome.
      32                 :             :  */
      33                 :             : 
      34                 :             : void
      35                 :           0 : ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed)
      36                 :             : {
      37                 :           0 :         char       *data = ((char *) xlrec) + MinSizeOfXactCommit;
      38                 :             : 
      39                 :           0 :         memset(parsed, 0, sizeof(*parsed));
      40                 :             : 
      41                 :           0 :         parsed->xinfo = 0;                   /* default, if no XLOG_XACT_HAS_INFO is
      42                 :             :                                                                  * present */
      43                 :             : 
      44                 :           0 :         parsed->xact_time = xlrec->xact_time;
      45                 :             : 
      46         [ #  # ]:           0 :         if (info & XLOG_XACT_HAS_INFO)
      47                 :             :         {
      48                 :           0 :                 xl_xact_xinfo *xl_xinfo = (xl_xact_xinfo *) data;
      49                 :             : 
      50                 :           0 :                 parsed->xinfo = xl_xinfo->xinfo;
      51                 :             : 
      52                 :           0 :                 data += sizeof(xl_xact_xinfo);
      53                 :           0 :         }
      54                 :             : 
      55         [ #  # ]:           0 :         if (parsed->xinfo & XACT_XINFO_HAS_DBINFO)
      56                 :             :         {
      57                 :           0 :                 xl_xact_dbinfo *xl_dbinfo = (xl_xact_dbinfo *) data;
      58                 :             : 
      59                 :           0 :                 parsed->dbId = xl_dbinfo->dbId;
      60                 :           0 :                 parsed->tsId = xl_dbinfo->tsId;
      61                 :             : 
      62                 :           0 :                 data += sizeof(xl_xact_dbinfo);
      63                 :           0 :         }
      64                 :             : 
      65         [ #  # ]:           0 :         if (parsed->xinfo & XACT_XINFO_HAS_SUBXACTS)
      66                 :             :         {
      67                 :           0 :                 xl_xact_subxacts *xl_subxacts = (xl_xact_subxacts *) data;
      68                 :             : 
      69                 :           0 :                 parsed->nsubxacts = xl_subxacts->nsubxacts;
      70                 :           0 :                 parsed->subxacts = xl_subxacts->subxacts;
      71                 :             : 
      72                 :           0 :                 data += MinSizeOfXactSubxacts;
      73                 :           0 :                 data += parsed->nsubxacts * sizeof(TransactionId);
      74                 :           0 :         }
      75                 :             : 
      76         [ #  # ]:           0 :         if (parsed->xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
      77                 :             :         {
      78                 :           0 :                 xl_xact_relfilelocators *xl_rellocators = (xl_xact_relfilelocators *) data;
      79                 :             : 
      80                 :           0 :                 parsed->nrels = xl_rellocators->nrels;
      81                 :           0 :                 parsed->xlocators = xl_rellocators->xlocators;
      82                 :             : 
      83                 :           0 :                 data += MinSizeOfXactRelfileLocators;
      84                 :           0 :                 data += xl_rellocators->nrels * sizeof(RelFileLocator);
      85                 :           0 :         }
      86                 :             : 
      87         [ #  # ]:           0 :         if (parsed->xinfo & XACT_XINFO_HAS_DROPPED_STATS)
      88                 :             :         {
      89                 :           0 :                 xl_xact_stats_items *xl_drops = (xl_xact_stats_items *) data;
      90                 :             : 
      91                 :           0 :                 parsed->nstats = xl_drops->nitems;
      92                 :           0 :                 parsed->stats = xl_drops->items;
      93                 :             : 
      94                 :           0 :                 data += MinSizeOfXactStatsItems;
      95                 :           0 :                 data += xl_drops->nitems * sizeof(xl_xact_stats_item);
      96                 :           0 :         }
      97                 :             : 
      98         [ #  # ]:           0 :         if (parsed->xinfo & XACT_XINFO_HAS_INVALS)
      99                 :             :         {
     100                 :           0 :                 xl_xact_invals *xl_invals = (xl_xact_invals *) data;
     101                 :             : 
     102                 :           0 :                 parsed->nmsgs = xl_invals->nmsgs;
     103                 :           0 :                 parsed->msgs = xl_invals->msgs;
     104                 :             : 
     105                 :           0 :                 data += MinSizeOfXactInvals;
     106                 :           0 :                 data += xl_invals->nmsgs * sizeof(SharedInvalidationMessage);
     107                 :           0 :         }
     108                 :             : 
     109         [ #  # ]:           0 :         if (parsed->xinfo & XACT_XINFO_HAS_TWOPHASE)
     110                 :             :         {
     111                 :           0 :                 xl_xact_twophase *xl_twophase = (xl_xact_twophase *) data;
     112                 :             : 
     113                 :           0 :                 parsed->twophase_xid = xl_twophase->xid;
     114                 :             : 
     115                 :           0 :                 data += sizeof(xl_xact_twophase);
     116                 :             : 
     117         [ #  # ]:           0 :                 if (parsed->xinfo & XACT_XINFO_HAS_GID)
     118                 :             :                 {
     119                 :           0 :                         strlcpy(parsed->twophase_gid, data, sizeof(parsed->twophase_gid));
     120                 :           0 :                         data += strlen(data) + 1;
     121                 :           0 :                 }
     122                 :           0 :         }
     123                 :             : 
     124                 :             :         /* Note: no alignment is guaranteed after this point */
     125                 :             : 
     126         [ #  # ]:           0 :         if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
     127                 :             :         {
     128                 :           0 :                 xl_xact_origin xl_origin;
     129                 :             : 
     130                 :             :                 /* no alignment is guaranteed, so copy onto stack */
     131                 :           0 :                 memcpy(&xl_origin, data, sizeof(xl_origin));
     132                 :             : 
     133                 :           0 :                 parsed->origin_lsn = xl_origin.origin_lsn;
     134                 :           0 :                 parsed->origin_timestamp = xl_origin.origin_timestamp;
     135                 :             : 
     136                 :           0 :                 data += sizeof(xl_xact_origin);
     137                 :           0 :         }
     138                 :           0 : }
     139                 :             : 
     140                 :             : void
     141                 :           0 : ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
     142                 :             : {
     143                 :           0 :         char       *data = ((char *) xlrec) + MinSizeOfXactAbort;
     144                 :             : 
     145                 :           0 :         memset(parsed, 0, sizeof(*parsed));
     146                 :             : 
     147                 :           0 :         parsed->xinfo = 0;                   /* default, if no XLOG_XACT_HAS_INFO is
     148                 :             :                                                                  * present */
     149                 :             : 
     150                 :           0 :         parsed->xact_time = xlrec->xact_time;
     151                 :             : 
     152         [ #  # ]:           0 :         if (info & XLOG_XACT_HAS_INFO)
     153                 :             :         {
     154                 :           0 :                 xl_xact_xinfo *xl_xinfo = (xl_xact_xinfo *) data;
     155                 :             : 
     156                 :           0 :                 parsed->xinfo = xl_xinfo->xinfo;
     157                 :             : 
     158                 :           0 :                 data += sizeof(xl_xact_xinfo);
     159                 :           0 :         }
     160                 :             : 
     161         [ #  # ]:           0 :         if (parsed->xinfo & XACT_XINFO_HAS_DBINFO)
     162                 :             :         {
     163                 :           0 :                 xl_xact_dbinfo *xl_dbinfo = (xl_xact_dbinfo *) data;
     164                 :             : 
     165                 :           0 :                 parsed->dbId = xl_dbinfo->dbId;
     166                 :           0 :                 parsed->tsId = xl_dbinfo->tsId;
     167                 :             : 
     168                 :           0 :                 data += sizeof(xl_xact_dbinfo);
     169                 :           0 :         }
     170                 :             : 
     171         [ #  # ]:           0 :         if (parsed->xinfo & XACT_XINFO_HAS_SUBXACTS)
     172                 :             :         {
     173                 :           0 :                 xl_xact_subxacts *xl_subxacts = (xl_xact_subxacts *) data;
     174                 :             : 
     175                 :           0 :                 parsed->nsubxacts = xl_subxacts->nsubxacts;
     176                 :           0 :                 parsed->subxacts = xl_subxacts->subxacts;
     177                 :             : 
     178                 :           0 :                 data += MinSizeOfXactSubxacts;
     179                 :           0 :                 data += parsed->nsubxacts * sizeof(TransactionId);
     180                 :           0 :         }
     181                 :             : 
     182         [ #  # ]:           0 :         if (parsed->xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
     183                 :             :         {
     184                 :           0 :                 xl_xact_relfilelocators *xl_rellocator = (xl_xact_relfilelocators *) data;
     185                 :             : 
     186                 :           0 :                 parsed->nrels = xl_rellocator->nrels;
     187                 :           0 :                 parsed->xlocators = xl_rellocator->xlocators;
     188                 :             : 
     189                 :           0 :                 data += MinSizeOfXactRelfileLocators;
     190                 :           0 :                 data += xl_rellocator->nrels * sizeof(RelFileLocator);
     191                 :           0 :         }
     192                 :             : 
     193         [ #  # ]:           0 :         if (parsed->xinfo & XACT_XINFO_HAS_DROPPED_STATS)
     194                 :             :         {
     195                 :           0 :                 xl_xact_stats_items *xl_drops = (xl_xact_stats_items *) data;
     196                 :             : 
     197                 :           0 :                 parsed->nstats = xl_drops->nitems;
     198                 :           0 :                 parsed->stats = xl_drops->items;
     199                 :             : 
     200                 :           0 :                 data += MinSizeOfXactStatsItems;
     201                 :           0 :                 data += xl_drops->nitems * sizeof(xl_xact_stats_item);
     202                 :           0 :         }
     203                 :             : 
     204         [ #  # ]:           0 :         if (parsed->xinfo & XACT_XINFO_HAS_TWOPHASE)
     205                 :             :         {
     206                 :           0 :                 xl_xact_twophase *xl_twophase = (xl_xact_twophase *) data;
     207                 :             : 
     208                 :           0 :                 parsed->twophase_xid = xl_twophase->xid;
     209                 :             : 
     210                 :           0 :                 data += sizeof(xl_xact_twophase);
     211                 :             : 
     212         [ #  # ]:           0 :                 if (parsed->xinfo & XACT_XINFO_HAS_GID)
     213                 :             :                 {
     214                 :           0 :                         strlcpy(parsed->twophase_gid, data, sizeof(parsed->twophase_gid));
     215                 :           0 :                         data += strlen(data) + 1;
     216                 :           0 :                 }
     217                 :           0 :         }
     218                 :             : 
     219                 :             :         /* Note: no alignment is guaranteed after this point */
     220                 :             : 
     221         [ #  # ]:           0 :         if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
     222                 :             :         {
     223                 :           0 :                 xl_xact_origin xl_origin;
     224                 :             : 
     225                 :             :                 /* no alignment is guaranteed, so copy onto stack */
     226                 :           0 :                 memcpy(&xl_origin, data, sizeof(xl_origin));
     227                 :             : 
     228                 :           0 :                 parsed->origin_lsn = xl_origin.origin_lsn;
     229                 :           0 :                 parsed->origin_timestamp = xl_origin.origin_timestamp;
     230                 :             : 
     231                 :           0 :                 data += sizeof(xl_xact_origin);
     232                 :           0 :         }
     233                 :           0 : }
     234                 :             : 
     235                 :             : /*
     236                 :             :  * ParsePrepareRecord
     237                 :             :  */
     238                 :             : void
     239                 :           0 : ParsePrepareRecord(uint8 info, xl_xact_prepare *xlrec, xl_xact_parsed_prepare *parsed)
     240                 :             : {
     241                 :           0 :         char       *bufptr;
     242                 :             : 
     243                 :           0 :         bufptr = ((char *) xlrec) + MAXALIGN(sizeof(xl_xact_prepare));
     244                 :             : 
     245                 :           0 :         memset(parsed, 0, sizeof(*parsed));
     246                 :             : 
     247                 :           0 :         parsed->xact_time = xlrec->prepared_at;
     248                 :           0 :         parsed->origin_lsn = xlrec->origin_lsn;
     249                 :           0 :         parsed->origin_timestamp = xlrec->origin_timestamp;
     250                 :           0 :         parsed->twophase_xid = xlrec->xid;
     251                 :           0 :         parsed->dbId = xlrec->database;
     252                 :           0 :         parsed->nsubxacts = xlrec->nsubxacts;
     253                 :           0 :         parsed->nrels = xlrec->ncommitrels;
     254                 :           0 :         parsed->nabortrels = xlrec->nabortrels;
     255                 :           0 :         parsed->nstats = xlrec->ncommitstats;
     256                 :           0 :         parsed->nabortstats = xlrec->nabortstats;
     257                 :           0 :         parsed->nmsgs = xlrec->ninvalmsgs;
     258                 :             : 
     259                 :           0 :         strncpy(parsed->twophase_gid, bufptr, xlrec->gidlen);
     260                 :           0 :         bufptr += MAXALIGN(xlrec->gidlen);
     261                 :             : 
     262                 :           0 :         parsed->subxacts = (TransactionId *) bufptr;
     263                 :           0 :         bufptr += MAXALIGN(xlrec->nsubxacts * sizeof(TransactionId));
     264                 :             : 
     265                 :           0 :         parsed->xlocators = (RelFileLocator *) bufptr;
     266                 :           0 :         bufptr += MAXALIGN(xlrec->ncommitrels * sizeof(RelFileLocator));
     267                 :             : 
     268                 :           0 :         parsed->abortlocators = (RelFileLocator *) bufptr;
     269                 :           0 :         bufptr += MAXALIGN(xlrec->nabortrels * sizeof(RelFileLocator));
     270                 :             : 
     271                 :           0 :         parsed->stats = (xl_xact_stats_item *) bufptr;
     272                 :           0 :         bufptr += MAXALIGN(xlrec->ncommitstats * sizeof(xl_xact_stats_item));
     273                 :             : 
     274                 :           0 :         parsed->abortstats = (xl_xact_stats_item *) bufptr;
     275                 :           0 :         bufptr += MAXALIGN(xlrec->nabortstats * sizeof(xl_xact_stats_item));
     276                 :             : 
     277                 :           0 :         parsed->msgs = (SharedInvalidationMessage *) bufptr;
     278                 :           0 :         bufptr += MAXALIGN(xlrec->ninvalmsgs * sizeof(SharedInvalidationMessage));
     279                 :           0 : }
     280                 :             : 
     281                 :             : static void
     282                 :           0 : xact_desc_relations(StringInfo buf, char *label, int nrels,
     283                 :             :                                         RelFileLocator *xlocators)
     284                 :             : {
     285                 :           0 :         int                     i;
     286                 :             : 
     287         [ #  # ]:           0 :         if (nrels > 0)
     288                 :             :         {
     289                 :           0 :                 appendStringInfo(buf, "; %s:", label);
     290         [ #  # ]:           0 :                 for (i = 0; i < nrels; i++)
     291                 :             :                 {
     292                 :           0 :                         appendStringInfo(buf, " %s",
     293                 :           0 :                                                          relpathperm(xlocators[i], MAIN_FORKNUM).str);
     294                 :           0 :                 }
     295                 :           0 :         }
     296                 :           0 : }
     297                 :             : 
     298                 :             : static void
     299                 :           0 : xact_desc_subxacts(StringInfo buf, int nsubxacts, TransactionId *subxacts)
     300                 :             : {
     301                 :           0 :         int                     i;
     302                 :             : 
     303         [ #  # ]:           0 :         if (nsubxacts > 0)
     304                 :             :         {
     305                 :           0 :                 appendStringInfoString(buf, "; subxacts:");
     306         [ #  # ]:           0 :                 for (i = 0; i < nsubxacts; i++)
     307                 :           0 :                         appendStringInfo(buf, " %u", subxacts[i]);
     308                 :           0 :         }
     309                 :           0 : }
     310                 :             : 
     311                 :             : static void
     312                 :           0 : xact_desc_stats(StringInfo buf, const char *label,
     313                 :             :                                 int ndropped, xl_xact_stats_item *dropped_stats)
     314                 :             : {
     315                 :           0 :         int                     i;
     316                 :             : 
     317         [ #  # ]:           0 :         if (ndropped > 0)
     318                 :             :         {
     319                 :           0 :                 appendStringInfo(buf, "; %sdropped stats:", label);
     320         [ #  # ]:           0 :                 for (i = 0; i < ndropped; i++)
     321                 :             :                 {
     322                 :           0 :                         uint64          objid =
     323                 :           0 :                                 ((uint64) dropped_stats[i].objid_hi) << 32 | dropped_stats[i].objid_lo;
     324                 :             : 
     325                 :           0 :                         appendStringInfo(buf, " %d/%u/%" PRIu64,
     326                 :           0 :                                                          dropped_stats[i].kind,
     327                 :           0 :                                                          dropped_stats[i].dboid,
     328                 :           0 :                                                          objid);
     329                 :           0 :                 }
     330                 :           0 :         }
     331                 :           0 : }
     332                 :             : 
     333                 :             : static void
     334                 :           0 : xact_desc_commit(StringInfo buf, uint8 info, xl_xact_commit *xlrec, RepOriginId origin_id)
     335                 :             : {
     336                 :           0 :         xl_xact_parsed_commit parsed;
     337                 :             : 
     338                 :           0 :         ParseCommitRecord(info, xlrec, &parsed);
     339                 :             : 
     340                 :             :         /* If this is a prepared xact, show the xid of the original xact */
     341         [ #  # ]:           0 :         if (TransactionIdIsValid(parsed.twophase_xid))
     342                 :           0 :                 appendStringInfo(buf, "%u: ", parsed.twophase_xid);
     343                 :             : 
     344                 :           0 :         appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
     345                 :             : 
     346                 :           0 :         xact_desc_relations(buf, "rels", parsed.nrels, parsed.xlocators);
     347                 :           0 :         xact_desc_subxacts(buf, parsed.nsubxacts, parsed.subxacts);
     348                 :           0 :         xact_desc_stats(buf, "", parsed.nstats, parsed.stats);
     349                 :             : 
     350                 :           0 :         standby_desc_invalidations(buf, parsed.nmsgs, parsed.msgs, parsed.dbId,
     351                 :           0 :                                                            parsed.tsId,
     352                 :           0 :                                                            XactCompletionRelcacheInitFileInval(parsed.xinfo));
     353                 :             : 
     354         [ #  # ]:           0 :         if (XactCompletionApplyFeedback(parsed.xinfo))
     355                 :           0 :                 appendStringInfoString(buf, "; apply_feedback");
     356                 :             : 
     357         [ #  # ]:           0 :         if (XactCompletionForceSyncCommit(parsed.xinfo))
     358                 :           0 :                 appendStringInfoString(buf, "; sync");
     359                 :             : 
     360         [ #  # ]:           0 :         if (parsed.xinfo & XACT_XINFO_HAS_ORIGIN)
     361                 :             :         {
     362                 :           0 :                 appendStringInfo(buf, "; origin: node %u, lsn %X/%08X, at %s",
     363                 :           0 :                                                  origin_id,
     364                 :           0 :                                                  LSN_FORMAT_ARGS(parsed.origin_lsn),
     365                 :           0 :                                                  timestamptz_to_str(parsed.origin_timestamp));
     366                 :           0 :         }
     367                 :           0 : }
     368                 :             : 
     369                 :             : static void
     370                 :           0 : xact_desc_abort(StringInfo buf, uint8 info, xl_xact_abort *xlrec, RepOriginId origin_id)
     371                 :             : {
     372                 :           0 :         xl_xact_parsed_abort parsed;
     373                 :             : 
     374                 :           0 :         ParseAbortRecord(info, xlrec, &parsed);
     375                 :             : 
     376                 :             :         /* If this is a prepared xact, show the xid of the original xact */
     377         [ #  # ]:           0 :         if (TransactionIdIsValid(parsed.twophase_xid))
     378                 :           0 :                 appendStringInfo(buf, "%u: ", parsed.twophase_xid);
     379                 :             : 
     380                 :           0 :         appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
     381                 :             : 
     382                 :           0 :         xact_desc_relations(buf, "rels", parsed.nrels, parsed.xlocators);
     383                 :           0 :         xact_desc_subxacts(buf, parsed.nsubxacts, parsed.subxacts);
     384                 :             : 
     385         [ #  # ]:           0 :         if (parsed.xinfo & XACT_XINFO_HAS_ORIGIN)
     386                 :             :         {
     387                 :           0 :                 appendStringInfo(buf, "; origin: node %u, lsn %X/%08X, at %s",
     388                 :           0 :                                                  origin_id,
     389                 :           0 :                                                  LSN_FORMAT_ARGS(parsed.origin_lsn),
     390                 :           0 :                                                  timestamptz_to_str(parsed.origin_timestamp));
     391                 :           0 :         }
     392                 :             : 
     393                 :           0 :         xact_desc_stats(buf, "", parsed.nstats, parsed.stats);
     394                 :           0 : }
     395                 :             : 
     396                 :             : static void
     397                 :           0 : xact_desc_prepare(StringInfo buf, uint8 info, xl_xact_prepare *xlrec, RepOriginId origin_id)
     398                 :             : {
     399                 :           0 :         xl_xact_parsed_prepare parsed;
     400                 :             : 
     401                 :           0 :         ParsePrepareRecord(info, xlrec, &parsed);
     402                 :             : 
     403                 :           0 :         appendStringInfo(buf, "gid %s: ", parsed.twophase_gid);
     404                 :           0 :         appendStringInfoString(buf, timestamptz_to_str(parsed.xact_time));
     405                 :             : 
     406                 :           0 :         xact_desc_relations(buf, "rels(commit)", parsed.nrels, parsed.xlocators);
     407                 :           0 :         xact_desc_relations(buf, "rels(abort)", parsed.nabortrels,
     408                 :           0 :                                                 parsed.abortlocators);
     409                 :           0 :         xact_desc_stats(buf, "commit ", parsed.nstats, parsed.stats);
     410                 :           0 :         xact_desc_stats(buf, "abort ", parsed.nabortstats, parsed.abortstats);
     411                 :           0 :         xact_desc_subxacts(buf, parsed.nsubxacts, parsed.subxacts);
     412                 :             : 
     413                 :           0 :         standby_desc_invalidations(buf, parsed.nmsgs, parsed.msgs, parsed.dbId,
     414                 :           0 :                                                            parsed.tsId, xlrec->initfileinval);
     415                 :             : 
     416                 :             :         /*
     417                 :             :          * Check if the replication origin has been set in this record in the same
     418                 :             :          * way as PrepareRedoAdd().
     419                 :             :          */
     420         [ #  # ]:           0 :         if (origin_id != InvalidRepOriginId)
     421                 :           0 :                 appendStringInfo(buf, "; origin: node %u, lsn %X/%08X, at %s",
     422                 :           0 :                                                  origin_id,
     423                 :           0 :                                                  LSN_FORMAT_ARGS(parsed.origin_lsn),
     424                 :           0 :                                                  timestamptz_to_str(parsed.origin_timestamp));
     425                 :           0 : }
     426                 :             : 
     427                 :             : static void
     428                 :           0 : xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
     429                 :             : {
     430                 :           0 :         int                     i;
     431                 :             : 
     432                 :           0 :         appendStringInfoString(buf, "subxacts:");
     433                 :             : 
     434         [ #  # ]:           0 :         for (i = 0; i < xlrec->nsubxacts; i++)
     435                 :           0 :                 appendStringInfo(buf, " %u", xlrec->xsub[i]);
     436                 :           0 : }
     437                 :             : 
     438                 :             : void
     439                 :           0 : xact_desc(StringInfo buf, XLogReaderState *record)
     440                 :             : {
     441                 :           0 :         char       *rec = XLogRecGetData(record);
     442                 :           0 :         uint8           info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
     443                 :             : 
     444   [ #  #  #  # ]:           0 :         if (info == XLOG_XACT_COMMIT || info == XLOG_XACT_COMMIT_PREPARED)
     445                 :             :         {
     446                 :           0 :                 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
     447                 :             : 
     448                 :           0 :                 xact_desc_commit(buf, XLogRecGetInfo(record), xlrec,
     449                 :           0 :                                                  XLogRecGetOrigin(record));
     450                 :           0 :         }
     451   [ #  #  #  # ]:           0 :         else if (info == XLOG_XACT_ABORT || info == XLOG_XACT_ABORT_PREPARED)
     452                 :             :         {
     453                 :           0 :                 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
     454                 :             : 
     455                 :           0 :                 xact_desc_abort(buf, XLogRecGetInfo(record), xlrec,
     456                 :           0 :                                                 XLogRecGetOrigin(record));
     457                 :           0 :         }
     458         [ #  # ]:           0 :         else if (info == XLOG_XACT_PREPARE)
     459                 :             :         {
     460                 :           0 :                 xl_xact_prepare *xlrec = (xl_xact_prepare *) rec;
     461                 :             : 
     462                 :           0 :                 xact_desc_prepare(buf, XLogRecGetInfo(record), xlrec,
     463                 :           0 :                                                   XLogRecGetOrigin(record));
     464                 :           0 :         }
     465         [ #  # ]:           0 :         else if (info == XLOG_XACT_ASSIGNMENT)
     466                 :             :         {
     467                 :           0 :                 xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
     468                 :             : 
     469                 :             :                 /*
     470                 :             :                  * Note that we ignore the WAL record's xid, since we're more
     471                 :             :                  * interested in the top-level xid that issued the record and which
     472                 :             :                  * xids are being reported here.
     473                 :             :                  */
     474                 :           0 :                 appendStringInfo(buf, "xtop %u: ", xlrec->xtop);
     475                 :           0 :                 xact_desc_assignment(buf, xlrec);
     476                 :           0 :         }
     477         [ #  # ]:           0 :         else if (info == XLOG_XACT_INVALIDATIONS)
     478                 :             :         {
     479                 :           0 :                 xl_xact_invals *xlrec = (xl_xact_invals *) rec;
     480                 :             : 
     481                 :           0 :                 standby_desc_invalidations(buf, xlrec->nmsgs, xlrec->msgs, InvalidOid,
     482                 :             :                                                                    InvalidOid, false);
     483                 :           0 :         }
     484                 :           0 : }
     485                 :             : 
     486                 :             : const char *
     487                 :           0 : xact_identify(uint8 info)
     488                 :             : {
     489                 :           0 :         const char *id = NULL;
     490                 :             : 
     491   [ #  #  #  #  :           0 :         switch (info & XLOG_XACT_OPMASK)
             #  #  #  # ]
     492                 :             :         {
     493                 :             :                 case XLOG_XACT_COMMIT:
     494                 :           0 :                         id = "COMMIT";
     495                 :           0 :                         break;
     496                 :             :                 case XLOG_XACT_PREPARE:
     497                 :           0 :                         id = "PREPARE";
     498                 :           0 :                         break;
     499                 :             :                 case XLOG_XACT_ABORT:
     500                 :           0 :                         id = "ABORT";
     501                 :           0 :                         break;
     502                 :             :                 case XLOG_XACT_COMMIT_PREPARED:
     503                 :           0 :                         id = "COMMIT_PREPARED";
     504                 :           0 :                         break;
     505                 :             :                 case XLOG_XACT_ABORT_PREPARED:
     506                 :           0 :                         id = "ABORT_PREPARED";
     507                 :           0 :                         break;
     508                 :             :                 case XLOG_XACT_ASSIGNMENT:
     509                 :           0 :                         id = "ASSIGNMENT";
     510                 :           0 :                         break;
     511                 :             :                 case XLOG_XACT_INVALIDATIONS:
     512                 :           0 :                         id = "INVALIDATION";
     513                 :           0 :                         break;
     514                 :             :         }
     515                 :             : 
     516                 :           0 :         return id;
     517                 :           0 : }
        

Generated by: LCOV version 2.3.2-1