PostgreSQL Source Code  git master
walsummaryfuncs.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * walsummaryfuncs.c
4  * SQL-callable functions for accessing WAL summary data.
5  *
6  * Portions Copyright (c) 2010-2024, PostgreSQL Global Development Group
7  *
8  * src/backend/backup/walsummaryfuncs.c
9  *
10  *-------------------------------------------------------------------------
11  */
12 
13 #include "postgres.h"
14 
15 #include "backup/walsummary.h"
16 #include "common/blkreftable.h"
17 #include "funcapi.h"
18 #include "miscadmin.h"
20 #include "utils/fmgrprotos.h"
21 #include "utils/pg_lsn.h"
22 
23 #define NUM_WS_ATTS 3
24 #define NUM_SUMMARY_ATTS 6
25 #define NUM_STATE_ATTS 4
26 #define MAX_BLOCKS_PER_CALL 256
27 
28 /*
29  * List the WAL summary files available in pg_wal/summaries.
30  */
31 Datum
33 {
34  ReturnSetInfo *rsi;
35  List *wslist;
36  ListCell *lc;
38  bool nulls[NUM_WS_ATTS];
39 
40  InitMaterializedSRF(fcinfo, 0);
41  rsi = (ReturnSetInfo *) fcinfo->resultinfo;
42 
43  memset(nulls, 0, sizeof(nulls));
44 
46  foreach(lc, wslist)
47  {
48  WalSummaryFile *ws = (WalSummaryFile *) lfirst(lc);
49  HeapTuple tuple;
50 
52 
53  values[0] = Int64GetDatum((int64) ws->tli);
54  values[1] = LSNGetDatum(ws->start_lsn);
55  values[2] = LSNGetDatum(ws->end_lsn);
56 
57  tuple = heap_form_tuple(rsi->setDesc, values, nulls);
58  tuplestore_puttuple(rsi->setResult, tuple);
59  }
60 
61  return (Datum) 0;
62 }
63 
64 /*
65  * List the contents of a WAL summary file identified by TLI, start LSN,
66  * and end LSN.
67  */
68 Datum
70 {
71  ReturnSetInfo *rsi;
73  bool nulls[NUM_SUMMARY_ATTS];
74  WalSummaryFile ws;
75  WalSummaryIO io;
76  BlockRefTableReader *reader;
77  int64 raw_tli;
78  RelFileLocator rlocator;
79  ForkNumber forknum;
80  BlockNumber limit_block;
81 
82  InitMaterializedSRF(fcinfo, 0);
83  rsi = (ReturnSetInfo *) fcinfo->resultinfo;
84  memset(nulls, 0, sizeof(nulls));
85 
86  /*
87  * Since the timeline could at least in theory be more than 2^31, and
88  * since we don't have unsigned types at the SQL level, it is passed as a
89  * 64-bit integer. Test whether it's out of range.
90  */
91  raw_tli = PG_GETARG_INT64(0);
92  if (raw_tli < 1 || raw_tli > PG_INT32_MAX)
93  ereport(ERROR,
94  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
95  errmsg("invalid timeline %lld", (long long) raw_tli));
96 
97  /* Prepare to read the specified WAL summary file. */
98  ws.tli = (TimeLineID) raw_tli;
99  ws.start_lsn = PG_GETARG_LSN(1);
100  ws.end_lsn = PG_GETARG_LSN(2);
101  io.filepos = 0;
102  io.file = OpenWalSummaryFile(&ws, false);
104  FilePathName(io.file),
105  ReportWalSummaryError, NULL);
106 
107  /* Loop over relation forks. */
108  while (BlockRefTableReaderNextRelation(reader, &rlocator, &forknum,
109  &limit_block))
110  {
112  HeapTuple tuple;
113 
115 
116  values[0] = ObjectIdGetDatum(rlocator.relNumber);
117  values[1] = ObjectIdGetDatum(rlocator.spcOid);
118  values[2] = ObjectIdGetDatum(rlocator.dbOid);
119  values[3] = Int16GetDatum((int16) forknum);
120 
121  /*
122  * If the limit block is not InvalidBlockNumber, emit an extra row
123  * with that block number and limit_block = true.
124  *
125  * There is no point in doing this when the limit_block is
126  * InvalidBlockNumber, because no block with that number or any higher
127  * number can ever exist.
128  */
129  if (BlockNumberIsValid(limit_block))
130  {
131  values[4] = Int64GetDatum((int64) limit_block);
132  values[5] = BoolGetDatum(true);
133 
134  tuple = heap_form_tuple(rsi->setDesc, values, nulls);
135  tuplestore_puttuple(rsi->setResult, tuple);
136  }
137 
138  /* Loop over blocks within the current relation fork. */
139  while (1)
140  {
141  unsigned nblocks;
142  unsigned i;
143 
145 
146  nblocks = BlockRefTableReaderGetBlocks(reader, blocks,
148  if (nblocks == 0)
149  break;
150 
151  /*
152  * For each block that we specifically know to have been modified,
153  * emit a row with that block number and limit_block = false.
154  */
155  values[5] = BoolGetDatum(false);
156  for (i = 0; i < nblocks; ++i)
157  {
158  values[4] = Int64GetDatum((int64) blocks[i]);
159 
160  tuple = heap_form_tuple(rsi->setDesc, values, nulls);
161  tuplestore_puttuple(rsi->setResult, tuple);
162  }
163  }
164  }
165 
166  /* Cleanup */
168  FileClose(io.file);
169 
170  return (Datum) 0;
171 }
172 
173 /*
174  * Returns information about the state of the WAL summarizer process.
175  */
176 Datum
178 {
180  bool nulls[NUM_STATE_ATTS];
181  TimeLineID summarized_tli;
182  XLogRecPtr summarized_lsn;
183  XLogRecPtr pending_lsn;
184  int summarizer_pid;
185  TupleDesc tupdesc;
186  HeapTuple htup;
187 
188  GetWalSummarizerState(&summarized_tli, &summarized_lsn, &pending_lsn,
189  &summarizer_pid);
190 
191  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
192  elog(ERROR, "return type must be a row type");
193 
194  memset(nulls, 0, sizeof(nulls));
195 
196  values[0] = Int64GetDatum((int64) summarized_tli);
197  values[1] = LSNGetDatum(summarized_lsn);
198  values[2] = LSNGetDatum(pending_lsn);
199 
200  if (summarizer_pid < 0)
201  nulls[3] = true;
202  else
203  values[3] = Int32GetDatum(summarizer_pid);
204 
205  htup = heap_form_tuple(tupdesc, values, nulls);
206 
208 }
BlockRefTableReader * CreateBlockRefTableReader(io_callback_fn read_callback, void *read_callback_arg, char *error_filename, report_error_fn error_callback, void *error_callback_arg)
Definition: blkreftable.c:577
bool BlockRefTableReaderNextRelation(BlockRefTableReader *reader, RelFileLocator *rlocator, ForkNumber *forknum, BlockNumber *limit_block)
Definition: blkreftable.c:613
unsigned BlockRefTableReaderGetBlocks(BlockRefTableReader *reader, BlockNumber *blocks, int nblocks)
Definition: blkreftable.c:689
void DestroyBlockRefTableReader(BlockRefTableReader *reader)
Definition: blkreftable.c:773
uint32 BlockNumber
Definition: block.h:31
static bool BlockNumberIsValid(BlockNumber blockNumber)
Definition: block.h:71
static Datum values[MAXATTR]
Definition: bootstrap.c:150
#define PG_INT32_MAX
Definition: c.h:580
signed short int16
Definition: c.h:495
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
void FileClose(File file)
Definition: fd.c:1978
char * FilePathName(File file)
Definition: fd.c:2484
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1807
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Definition: funcapi.c:76
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:276
@ TYPEFUNC_COMPOSITE
Definition: funcapi.h:149
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition: funcapi.h:230
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1116
int i
Definition: isn.c:73
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
#define lfirst(lc)
Definition: pg_list.h:172
#define PG_GETARG_LSN(n)
Definition: pg_lsn.h:33
static Datum LSNGetDatum(XLogRecPtr X)
Definition: pg_lsn.h:28
uintptr_t Datum
Definition: postgres.h:64
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:172
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
ForkNumber
Definition: relpath.h:56
Definition: pg_list.h:54
RelFileNumber relNumber
TupleDesc setDesc
Definition: execnodes.h:343
Tuplestorestate * setResult
Definition: execnodes.h:342
XLogRecPtr end_lsn
Definition: walsummary.h:30
TimeLineID tli
Definition: walsummary.h:31
XLogRecPtr start_lsn
Definition: walsummary.h:29
off_t filepos
Definition: walsummary.h:24
void tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
Definition: tuplestore.c:764
void GetWalSummarizerState(TimeLineID *summarized_tli, XLogRecPtr *summarized_lsn, XLogRecPtr *pending_lsn, int *summarizer_pid)
File OpenWalSummaryFile(WalSummaryFile *ws, bool missing_ok)
Definition: walsummary.c:205
List * GetWalSummaries(TimeLineID tli, XLogRecPtr start_lsn, XLogRecPtr end_lsn)
Definition: walsummary.c:43
int ReadWalSummary(void *wal_summary_io, void *data, int length)
Definition: walsummary.c:273
void ReportWalSummaryError(void *callback_arg, char *fmt,...)
Definition: walsummary.c:322
Datum pg_get_wal_summarizer_state(PG_FUNCTION_ARGS)
#define NUM_SUMMARY_ATTS
#define NUM_STATE_ATTS
Datum pg_available_wal_summaries(PG_FUNCTION_ARGS)
#define NUM_WS_ATTS
#define MAX_BLOCKS_PER_CALL
Datum pg_wal_summary_contents(PG_FUNCTION_ARGS)
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
uint32 TimeLineID
Definition: xlogdefs.h:59