Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  pg_logicalinspect.c

  Sprache: C
 

/*-------------------------------------------------------------------------
 *
 * pg_logicalinspect.c
 *    Functions to inspect contents of PostgreSQL logical snapshots
 *
 * Copyright (c) 2024-2025, PostgreSQL Global Development Group
 *
 * IDENTIFICATION
 *    contrib/pg_logicalinspect/pg_logicalinspect.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "funcapi.h"
#include "replication/snapbuild_internal.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/pg_lsn.h"

PG_MODULE_MAGIC_EXT(
     .name = "pg_logicalinspect",
     .version = PG_VERSION
);

PG_FUNCTION_INFO_V1(pg_get_logical_snapshot_meta);
PG_FUNCTION_INFO_V1(pg_get_logical_snapshot_info);

/* Return the description of SnapBuildState */
static const char *
get_snapbuild_state_desc(SnapBuildState state)
{
 const char *stateDesc = "unknown state";

 switch (state)
 {
  case SNAPBUILD_START:
   stateDesc = "start";
   break;
  case SNAPBUILD_BUILDING_SNAPSHOT:
   stateDesc = "building";
   break;
  case SNAPBUILD_FULL_SNAPSHOT:
   stateDesc = "full";
   break;
  case SNAPBUILD_CONSISTENT:
   stateDesc = "consistent";
   break;
 }

 return stateDesc;
}

/*
 * Extract the LSN from the given serialized snapshot file name.
 */

static XLogRecPtr
parse_snapshot_filename(const char *filename)
{
 uint32  hi;
 uint32  lo;
 XLogRecPtr lsn;
 char  tmpfname[MAXPGPATH];

 /*
  * Extract the values to build the LSN.
  *
  * Note: Including ".snap" doesn't mean that sscanf() also does the format
  * check including the suffix. The subsequent check validates if the given
  * filename has the expected suffix.
 */

 if (sscanf(filename, "%X-%X.snap", &hi, &lo) != 2)
  goto parse_error;

 /*
  * Bring back the extracted LSN to the snapshot file format and compare it
  * to the given filename. This check strictly checks if the given filename
  * follows the format of the snapshot filename.
 */

 sprintf(tmpfname, "%X-%X.snap", hi, lo);
 if (strcmp(tmpfname, filename) != 0)
  goto parse_error;

 lsn = ((uint64) hi) << 32 | lo;

 return lsn;

parse_error:
 ereport(ERROR,
   errmsg("invalid snapshot file name \"%s\"", filename));

 return InvalidXLogRecPtr; /* keep compiler quiet */
}

/*
 * Retrieve the logical snapshot file metadata.
 */

Datum
pg_get_logical_snapshot_meta(PG_FUNCTION_ARGS)
{
#define PG_GET_LOGICAL_SNAPSHOT_META_COLS 3
 SnapBuildOnDisk ondisk;
 HeapTuple tuple;
 Datum  values[PG_GET_LOGICAL_SNAPSHOT_META_COLS] = {0};
 bool  nulls[PG_GET_LOGICAL_SNAPSHOT_META_COLS] = {0};
 TupleDesc tupdesc;
 XLogRecPtr lsn;
 int   i = 0;
 text    *filename_t = PG_GETARG_TEXT_PP(0);

 /* Build a tuple descriptor for our result type */
 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
  elog(ERROR, "return type must be a row type");

 lsn = parse_snapshot_filename(text_to_cstring(filename_t));

 /* Validate and restore the snapshot to 'ondisk' */
 SnapBuildRestoreSnapshot(&ondisk, lsn, CurrentMemoryContext, false);

 values[i++] = UInt32GetDatum(ondisk.magic);
 values[i++] = Int64GetDatum((int64) ondisk.checksum);
 values[i++] = UInt32GetDatum(ondisk.version);

 Assert(i == PG_GET_LOGICAL_SNAPSHOT_META_COLS);

 tuple = heap_form_tuple(tupdesc, values, nulls);

 PG_RETURN_DATUM(HeapTupleGetDatum(tuple));

#undef PG_GET_LOGICAL_SNAPSHOT_META_COLS
}

Datum
pg_get_logical_snapshot_info(PG_FUNCTION_ARGS)
{
#define PG_GET_LOGICAL_SNAPSHOT_INFO_COLS 14
 SnapBuildOnDisk ondisk;
 HeapTuple tuple;
 Datum  values[PG_GET_LOGICAL_SNAPSHOT_INFO_COLS] = {0};
 bool  nulls[PG_GET_LOGICAL_SNAPSHOT_INFO_COLS] = {0};
 TupleDesc tupdesc;
 XLogRecPtr lsn;
 int   i = 0;
 text    *filename_t = PG_GETARG_TEXT_PP(0);

 /* Build a tuple descriptor for our result type */
 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
  elog(ERROR, "return type must be a row type");

 lsn = parse_snapshot_filename(text_to_cstring(filename_t));

 /* Validate and restore the snapshot to 'ondisk' */
 SnapBuildRestoreSnapshot(&ondisk, lsn, CurrentMemoryContext, false);

 values[i++] = CStringGetTextDatum(get_snapbuild_state_desc(ondisk.builder.state));
 values[i++] = TransactionIdGetDatum(ondisk.builder.xmin);
 values[i++] = TransactionIdGetDatum(ondisk.builder.xmax);
 values[i++] = LSNGetDatum(ondisk.builder.start_decoding_at);
 values[i++] = LSNGetDatum(ondisk.builder.two_phase_at);
 values[i++] = TransactionIdGetDatum(ondisk.builder.initial_xmin_horizon);
 values[i++] = BoolGetDatum(ondisk.builder.building_full_snapshot);
 values[i++] = BoolGetDatum(ondisk.builder.in_slot_creation);
 values[i++] = LSNGetDatum(ondisk.builder.last_serialized_snapshot);
 values[i++] = TransactionIdGetDatum(ondisk.builder.next_phase_at);

 values[i++] = UInt32GetDatum(ondisk.builder.committed.xcnt);
 if (ondisk.builder.committed.xcnt > 0)
 {
  Datum    *arrayelems;

  arrayelems = (Datum *) palloc(ondisk.builder.committed.xcnt * sizeof(Datum));

  for (int j = 0; j < ondisk.builder.committed.xcnt; j++)
   arrayelems[j] = TransactionIdGetDatum(ondisk.builder.committed.xip[j]);

  values[i++] = PointerGetDatum(construct_array_builtin(arrayelems,
                 ondisk.builder.committed.xcnt,
                 XIDOID));
 }
 else
  nulls[i++] = true;

 values[i++] = UInt32GetDatum(ondisk.builder.catchange.xcnt);
 if (ondisk.builder.catchange.xcnt > 0)
 {
  Datum    *arrayelems;

  arrayelems = (Datum *) palloc(ondisk.builder.catchange.xcnt * sizeof(Datum));

  for (int j = 0; j < ondisk.builder.catchange.xcnt; j++)
   arrayelems[j] = TransactionIdGetDatum(ondisk.builder.catchange.xip[j]);

  values[i++] = PointerGetDatum(construct_array_builtin(arrayelems,
                 ondisk.builder.catchange.xcnt,
                 XIDOID));
 }
 else
  nulls[i++] = true;

 Assert(i == PG_GET_LOGICAL_SNAPSHOT_INFO_COLS);

 tuple = heap_form_tuple(tupdesc, values, nulls);

 PG_RETURN_DATUM(HeapTupleGetDatum(tuple));

#undef PG_GET_LOGICAL_SNAPSHOT_INFO_COLS
}

Messung V0.5 in Prozent
C=94 H=87 G=90

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=738142