PostgreSQL Source Code  git master
pg_controldata.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_controldata.c
4  *
5  * Routines to expose the contents of the control data file via
6  * a set of SQL functions.
7  *
8  * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
9  * Portions Copyright (c) 1994, Regents of the University of California
10  *
11  * IDENTIFICATION
12  * src/backend/utils/misc/pg_controldata.c
13  *-------------------------------------------------------------------------
14  */
15 
16 #include "postgres.h"
17 
18 #include "access/htup_details.h"
19 #include "access/transam.h"
20 #include "access/xlog.h"
21 #include "access/xlog_internal.h"
22 #include "catalog/pg_control.h"
23 #include "catalog/pg_type.h"
25 #include "funcapi.h"
26 #include "miscadmin.h"
27 #include "utils/builtins.h"
28 #include "utils/pg_lsn.h"
29 #include "utils/timestamp.h"
30 
31 Datum
33 {
34  Datum values[4];
35  bool nulls[4];
36  TupleDesc tupdesc;
37  HeapTuple htup;
39  bool crc_ok;
40 
41  /*
42  * Construct a tuple descriptor for the result row. This must match this
43  * function's pg_proc entry!
44  */
45  tupdesc = CreateTemplateTupleDesc(4);
46  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "pg_control_version",
47  INT4OID, -1, 0);
48  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catalog_version_no",
49  INT4OID, -1, 0);
50  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "system_identifier",
51  INT8OID, -1, 0);
52  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "pg_control_last_modified",
53  TIMESTAMPTZOID, -1, 0);
54  tupdesc = BlessTupleDesc(tupdesc);
55 
56  /* read the control file */
57  ControlFile = get_controlfile(DataDir, &crc_ok);
58  if (!crc_ok)
59  ereport(ERROR,
60  (errmsg("calculated CRC checksum does not match value stored in file")));
61 
62  values[0] = Int32GetDatum(ControlFile->pg_control_version);
63  nulls[0] = false;
64 
65  values[1] = Int32GetDatum(ControlFile->catalog_version_no);
66  nulls[1] = false;
67 
68  values[2] = Int64GetDatum(ControlFile->system_identifier);
69  nulls[2] = false;
70 
71  values[3] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->time));
72  nulls[3] = false;
73 
74  htup = heap_form_tuple(tupdesc, values, nulls);
75 
77 }
78 
79 Datum
81 {
82  Datum values[19];
83  bool nulls[19];
84  TupleDesc tupdesc;
85  HeapTuple htup;
87  XLogSegNo segno;
88  char xlogfilename[MAXFNAMELEN];
89  bool crc_ok;
90 
91  /*
92  * Construct a tuple descriptor for the result row. This must match this
93  * function's pg_proc entry!
94  */
95  tupdesc = CreateTemplateTupleDesc(18);
96  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "checkpoint_lsn",
97  LSNOID, -1, 0);
98  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "redo_lsn",
99  LSNOID, -1, 0);
100  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "redo_wal_file",
101  TEXTOID, -1, 0);
102  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "timeline_id",
103  INT4OID, -1, 0);
104  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "prev_timeline_id",
105  INT4OID, -1, 0);
106  TupleDescInitEntry(tupdesc, (AttrNumber) 6, "full_page_writes",
107  BOOLOID, -1, 0);
108  TupleDescInitEntry(tupdesc, (AttrNumber) 7, "next_xid",
109  TEXTOID, -1, 0);
110  TupleDescInitEntry(tupdesc, (AttrNumber) 8, "next_oid",
111  OIDOID, -1, 0);
112  TupleDescInitEntry(tupdesc, (AttrNumber) 9, "next_multixact_id",
113  XIDOID, -1, 0);
114  TupleDescInitEntry(tupdesc, (AttrNumber) 10, "next_multi_offset",
115  XIDOID, -1, 0);
116  TupleDescInitEntry(tupdesc, (AttrNumber) 11, "oldest_xid",
117  XIDOID, -1, 0);
118  TupleDescInitEntry(tupdesc, (AttrNumber) 12, "oldest_xid_dbid",
119  OIDOID, -1, 0);
120  TupleDescInitEntry(tupdesc, (AttrNumber) 13, "oldest_active_xid",
121  XIDOID, -1, 0);
122  TupleDescInitEntry(tupdesc, (AttrNumber) 14, "oldest_multi_xid",
123  XIDOID, -1, 0);
124  TupleDescInitEntry(tupdesc, (AttrNumber) 15, "oldest_multi_dbid",
125  OIDOID, -1, 0);
126  TupleDescInitEntry(tupdesc, (AttrNumber) 16, "oldest_commit_ts_xid",
127  XIDOID, -1, 0);
128  TupleDescInitEntry(tupdesc, (AttrNumber) 17, "newest_commit_ts_xid",
129  XIDOID, -1, 0);
130  TupleDescInitEntry(tupdesc, (AttrNumber) 18, "checkpoint_time",
131  TIMESTAMPTZOID, -1, 0);
132  tupdesc = BlessTupleDesc(tupdesc);
133 
134  /* Read the control file. */
135  ControlFile = get_controlfile(DataDir, &crc_ok);
136  if (!crc_ok)
137  ereport(ERROR,
138  (errmsg("calculated CRC checksum does not match value stored in file")));
139 
140  /*
141  * Calculate name of the WAL file containing the latest checkpoint's REDO
142  * start point.
143  */
144  XLByteToSeg(ControlFile->checkPointCopy.redo, segno, wal_segment_size);
145  XLogFileName(xlogfilename, ControlFile->checkPointCopy.ThisTimeLineID,
146  segno, wal_segment_size);
147 
148  /* Populate the values and null arrays */
149  values[0] = LSNGetDatum(ControlFile->checkPoint);
150  nulls[0] = false;
151 
152  values[1] = LSNGetDatum(ControlFile->checkPointCopy.redo);
153  nulls[1] = false;
154 
155  values[2] = CStringGetTextDatum(xlogfilename);
156  nulls[2] = false;
157 
158  values[3] = Int32GetDatum(ControlFile->checkPointCopy.ThisTimeLineID);
159  nulls[3] = false;
160 
161  values[4] = Int32GetDatum(ControlFile->checkPointCopy.PrevTimeLineID);
162  nulls[4] = false;
163 
164  values[5] = BoolGetDatum(ControlFile->checkPointCopy.fullPageWrites);
165  nulls[5] = false;
166 
167  values[6] = CStringGetTextDatum(psprintf("%u:%u",
170  nulls[6] = false;
171 
172  values[7] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid);
173  nulls[7] = false;
174 
175  values[8] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMulti);
176  nulls[8] = false;
177 
178  values[9] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMultiOffset);
179  nulls[9] = false;
180 
181  values[10] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestXid);
182  nulls[10] = false;
183 
184  values[11] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestXidDB);
185  nulls[11] = false;
186 
187  values[12] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestActiveXid);
188  nulls[12] = false;
189 
190  values[13] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestMulti);
191  nulls[13] = false;
192 
193  values[14] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestMultiDB);
194  nulls[14] = false;
195 
196  values[15] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestCommitTsXid);
197  nulls[15] = false;
198 
199  values[16] = TransactionIdGetDatum(ControlFile->checkPointCopy.newestCommitTsXid);
200  nulls[16] = false;
201 
202  values[17] = TimestampTzGetDatum(
204  nulls[17] = false;
205 
206  htup = heap_form_tuple(tupdesc, values, nulls);
207 
209 }
210 
211 Datum
213 {
214  Datum values[5];
215  bool nulls[5];
216  TupleDesc tupdesc;
217  HeapTuple htup;
219  bool crc_ok;
220 
221  /*
222  * Construct a tuple descriptor for the result row. This must match this
223  * function's pg_proc entry!
224  */
225  tupdesc = CreateTemplateTupleDesc(5);
226  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "min_recovery_end_lsn",
227  LSNOID, -1, 0);
228  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "min_recovery_end_timeline",
229  INT4OID, -1, 0);
230  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "backup_start_lsn",
231  LSNOID, -1, 0);
232  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "backup_end_lsn",
233  LSNOID, -1, 0);
234  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "end_of_backup_record_required",
235  BOOLOID, -1, 0);
236  tupdesc = BlessTupleDesc(tupdesc);
237 
238  /* read the control file */
239  ControlFile = get_controlfile(DataDir, &crc_ok);
240  if (!crc_ok)
241  ereport(ERROR,
242  (errmsg("calculated CRC checksum does not match value stored in file")));
243 
244  values[0] = LSNGetDatum(ControlFile->minRecoveryPoint);
245  nulls[0] = false;
246 
247  values[1] = Int32GetDatum(ControlFile->minRecoveryPointTLI);
248  nulls[1] = false;
249 
250  values[2] = LSNGetDatum(ControlFile->backupStartPoint);
251  nulls[2] = false;
252 
253  values[3] = LSNGetDatum(ControlFile->backupEndPoint);
254  nulls[3] = false;
255 
256  values[4] = BoolGetDatum(ControlFile->backupEndRequired);
257  nulls[4] = false;
258 
259  htup = heap_form_tuple(tupdesc, values, nulls);
260 
262 }
263 
264 Datum
266 {
267  Datum values[11];
268  bool nulls[11];
269  TupleDesc tupdesc;
270  HeapTuple htup;
272  bool crc_ok;
273 
274  /*
275  * Construct a tuple descriptor for the result row. This must match this
276  * function's pg_proc entry!
277  */
278  tupdesc = CreateTemplateTupleDesc(11);
279  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "max_data_alignment",
280  INT4OID, -1, 0);
281  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database_block_size",
282  INT4OID, -1, 0);
283  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "blocks_per_segment",
284  INT4OID, -1, 0);
285  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_block_size",
286  INT4OID, -1, 0);
287  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "bytes_per_wal_segment",
288  INT4OID, -1, 0);
289  TupleDescInitEntry(tupdesc, (AttrNumber) 6, "max_identifier_length",
290  INT4OID, -1, 0);
291  TupleDescInitEntry(tupdesc, (AttrNumber) 7, "max_index_columns",
292  INT4OID, -1, 0);
293  TupleDescInitEntry(tupdesc, (AttrNumber) 8, "max_toast_chunk_size",
294  INT4OID, -1, 0);
295  TupleDescInitEntry(tupdesc, (AttrNumber) 9, "large_object_chunk_size",
296  INT4OID, -1, 0);
297  TupleDescInitEntry(tupdesc, (AttrNumber) 10, "float8_pass_by_value",
298  BOOLOID, -1, 0);
299  TupleDescInitEntry(tupdesc, (AttrNumber) 11, "data_page_checksum_version",
300  INT4OID, -1, 0);
301  tupdesc = BlessTupleDesc(tupdesc);
302 
303  /* read the control file */
304  ControlFile = get_controlfile(DataDir, &crc_ok);
305  if (!crc_ok)
306  ereport(ERROR,
307  (errmsg("calculated CRC checksum does not match value stored in file")));
308 
309  values[0] = Int32GetDatum(ControlFile->maxAlign);
310  nulls[0] = false;
311 
312  values[1] = Int32GetDatum(ControlFile->blcksz);
313  nulls[1] = false;
314 
315  values[2] = Int32GetDatum(ControlFile->relseg_size);
316  nulls[2] = false;
317 
318  values[3] = Int32GetDatum(ControlFile->xlog_blcksz);
319  nulls[3] = false;
320 
321  values[4] = Int32GetDatum(ControlFile->xlog_seg_size);
322  nulls[4] = false;
323 
324  values[5] = Int32GetDatum(ControlFile->nameDataLen);
325  nulls[5] = false;
326 
327  values[6] = Int32GetDatum(ControlFile->indexMaxKeys);
328  nulls[6] = false;
329 
330  values[7] = Int32GetDatum(ControlFile->toast_max_chunk_size);
331  nulls[7] = false;
332 
333  values[8] = Int32GetDatum(ControlFile->loblksize);
334  nulls[8] = false;
335 
336  values[9] = BoolGetDatum(ControlFile->float8ByVal);
337  nulls[9] = false;
338 
339  values[10] = Int32GetDatum(ControlFile->data_checksum_version);
340  nulls[10] = false;
341 
342  htup = heap_form_tuple(tupdesc, values, nulls);
343 
345 }
Datum pg_control_recovery(PG_FUNCTION_ARGS)
int wal_segment_size
Definition: xlog.c:112
pg_time_t time
Definition: pg_control.h:128
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
TransactionId oldestActiveXid
Definition: pg_control.h:63
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
uint32 nameDataLen
Definition: pg_control.h:211
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
#define LSNGetDatum(X)
Definition: pg_lsn.h:22
uint32 pg_control_version
Definition: pg_control.h:121
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
CheckPoint checkPointCopy
Definition: pg_control.h:131
uint32 xlog_blcksz
Definition: pg_control.h:208
TransactionId oldestXid
Definition: pg_control.h:47
pg_time_t time
Definition: pg_control.h:51
#define XidFromFullTransactionId(x)
Definition: transam.h:48
bool backupEndRequired
Definition: pg_control.h:170
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
uint32 xlog_seg_size
Definition: pg_control.h:209
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
uint64 system_identifier
Definition: pg_control.h:106
Datum pg_control_checkpoint(PG_FUNCTION_ARGS)
#define TimestampTzGetDatum(X)
Definition: timestamp.h:32
Datum pg_control_init(PG_FUNCTION_ARGS)
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2052
uint32 data_checksum_version
Definition: pg_control.h:220
uint64 XLogSegNo
Definition: xlogdefs.h:41
uint32 loblksize
Definition: pg_control.h:215
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1699
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:603
#define ereport(elevel, rest)
Definition: elog.h:141
uint32 indexMaxKeys
Definition: pg_control.h:212
#define MAXFNAMELEN
TransactionId newestCommitTsXid
Definition: pg_control.h:54
#define TransactionIdGetDatum(X)
Definition: postgres.h:521
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
Oid oldestMultiDB
Definition: pg_control.h:50
TimestampTz time_t_to_timestamptz(pg_time_t tm)
Definition: timestamp.c:1703
uint32 toast_max_chunk_size
Definition: pg_control.h:214
#define EpochFromFullTransactionId(x)
Definition: transam.h:47
static ControlFileData * ControlFile
Definition: xlog.c:721
#define BoolGetDatum(X)
Definition: postgres.h:402
Oid nextOid
Definition: pg_control.h:44
XLogRecPtr backupEndPoint
Definition: pg_control.h:169
bool fullPageWrites
Definition: pg_control.h:42
Datum pg_control_system(PG_FUNCTION_ARGS)
FullTransactionId nextFullXid
Definition: pg_control.h:43
Oid oldestXidDB
Definition: pg_control.h:48
ControlFileData * get_controlfile(const char *DataDir, bool *crc_ok_p)
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
MultiXactId nextMulti
Definition: pg_control.h:45
uint32 catalog_version_no
Definition: pg_control.h:122
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:220
static Datum values[MAXATTR]
Definition: bootstrap.c:167
#define Int32GetDatum(X)
Definition: postgres.h:479
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define CStringGetTextDatum(s)
Definition: builtins.h:83
char * DataDir
Definition: globals.c:62
#define PG_FUNCTION_ARGS
Definition: fmgr.h:188
int16 AttrNumber
Definition: attnum.h:21
XLogRecPtr backupStartPoint
Definition: pg_control.h:168
uint32 relseg_size
Definition: pg_control.h:206
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)