1 /*-------------------------------------------------------------------------
5 * Routines to expose the contents of the control data file via
6 * a set of SQL functions.
8 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
12 * src/backend/utils/misc/pg_controldata.c
13 *-------------------------------------------------------------------------
18 #include "access/htup_details.h"
19 #include "access/transam.h"
20 #include "access/xlog_internal.h"
21 #include "access/xlog.h"
22 #include "catalog/pg_control.h"
23 #include "catalog/pg_type.h"
24 #include "common/controldata_utils.h"
26 #include "miscadmin.h"
27 #include "utils/builtins.h"
28 #include "utils/pg_lsn.h"
29 #include "utils/timestamp.h"
32 pg_control_system(PG_FUNCTION_ARGS)
38 ControlFileData *ControlFile;
42 * Construct a tuple descriptor for the result row. This must match this
43 * function's pg_proc entry!
45 tupdesc = CreateTemplateTupleDesc(4);
46 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "pg_control_version",
48 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catalog_version_no",
50 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "system_identifier",
52 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "pg_control_last_modified",
53 TIMESTAMPTZOID, -1, 0);
54 tupdesc = BlessTupleDesc(tupdesc);
56 /* read the control file */
57 ControlFile = get_controlfile(DataDir, &crc_ok);
60 (errmsg("calculated CRC checksum does not match value stored in file")));
62 values[0] = Int32GetDatum(ControlFile->pg_control_version);
65 values[1] = Int32GetDatum(ControlFile->catalog_version_no);
68 values[2] = Int64GetDatum(ControlFile->system_identifier);
71 values[3] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->time));
74 htup = heap_form_tuple(tupdesc, values, nulls);
76 PG_RETURN_DATUM(HeapTupleGetDatum(htup));
80 pg_control_checkpoint(PG_FUNCTION_ARGS)
86 ControlFileData *ControlFile;
88 char xlogfilename[MAXFNAMELEN];
92 * Construct a tuple descriptor for the result row. This must match this
93 * function's pg_proc entry!
95 tupdesc = CreateTemplateTupleDesc(18);
96 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "checkpoint_lsn",
98 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "redo_lsn",
100 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "redo_wal_file",
102 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "timeline_id",
104 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "prev_timeline_id",
106 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "full_page_writes",
108 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "next_xid",
110 TupleDescInitEntry(tupdesc, (AttrNumber) 8, "next_oid",
112 TupleDescInitEntry(tupdesc, (AttrNumber) 9, "next_multixact_id",
114 TupleDescInitEntry(tupdesc, (AttrNumber) 10, "next_multi_offset",
116 TupleDescInitEntry(tupdesc, (AttrNumber) 11, "oldest_xid",
118 TupleDescInitEntry(tupdesc, (AttrNumber) 12, "oldest_xid_dbid",
120 TupleDescInitEntry(tupdesc, (AttrNumber) 13, "oldest_active_xid",
122 TupleDescInitEntry(tupdesc, (AttrNumber) 14, "oldest_multi_xid",
124 TupleDescInitEntry(tupdesc, (AttrNumber) 15, "oldest_multi_dbid",
126 TupleDescInitEntry(tupdesc, (AttrNumber) 16, "oldest_commit_ts_xid",
128 TupleDescInitEntry(tupdesc, (AttrNumber) 17, "newest_commit_ts_xid",
130 TupleDescInitEntry(tupdesc, (AttrNumber) 18, "checkpoint_time",
131 TIMESTAMPTZOID, -1, 0);
132 tupdesc = BlessTupleDesc(tupdesc);
134 /* Read the control file. */
135 ControlFile = get_controlfile(DataDir, &crc_ok);
138 (errmsg("calculated CRC checksum does not match value stored in file")));
141 * Calculate name of the WAL file containing the latest checkpoint's REDO
144 XLByteToSeg(ControlFile->checkPointCopy.redo, segno, wal_segment_size);
145 XLogFileName(xlogfilename, ControlFile->checkPointCopy.ThisTimeLineID,
146 segno, wal_segment_size);
148 /* Populate the values and null arrays */
149 values[0] = LSNGetDatum(ControlFile->checkPoint);
152 values[1] = LSNGetDatum(ControlFile->checkPointCopy.redo);
155 values[2] = CStringGetTextDatum(xlogfilename);
158 values[3] = Int32GetDatum(ControlFile->checkPointCopy.ThisTimeLineID);
161 values[4] = Int32GetDatum(ControlFile->checkPointCopy.PrevTimeLineID);
164 values[5] = BoolGetDatum(ControlFile->checkPointCopy.fullPageWrites);
167 values[6] = CStringGetTextDatum(psprintf("%u:%u",
168 EpochFromFullTransactionId(ControlFile->checkPointCopy.nextFullXid),
169 XidFromFullTransactionId(ControlFile->checkPointCopy.nextFullXid)));
172 values[7] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid);
175 values[8] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMulti);
178 values[9] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMultiOffset);
181 values[10] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestXid);
184 values[11] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestXidDB);
187 values[12] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestActiveXid);
190 values[13] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestMulti);
193 values[14] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestMultiDB);
196 values[15] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestCommitTsXid);
199 values[16] = TransactionIdGetDatum(ControlFile->checkPointCopy.newestCommitTsXid);
202 values[17] = TimestampTzGetDatum(
203 time_t_to_timestamptz(ControlFile->checkPointCopy.time));
206 htup = heap_form_tuple(tupdesc, values, nulls);
208 PG_RETURN_DATUM(HeapTupleGetDatum(htup));
212 pg_control_recovery(PG_FUNCTION_ARGS)
218 ControlFileData *ControlFile;
222 * Construct a tuple descriptor for the result row. This must match this
223 * function's pg_proc entry!
225 tupdesc = CreateTemplateTupleDesc(5);
226 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "min_recovery_end_lsn",
228 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "min_recovery_end_timeline",
230 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "backup_start_lsn",
232 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "backup_end_lsn",
234 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "end_of_backup_record_required",
236 tupdesc = BlessTupleDesc(tupdesc);
238 /* read the control file */
239 ControlFile = get_controlfile(DataDir, &crc_ok);
242 (errmsg("calculated CRC checksum does not match value stored in file")));
244 values[0] = LSNGetDatum(ControlFile->minRecoveryPoint);
247 values[1] = Int32GetDatum(ControlFile->minRecoveryPointTLI);
250 values[2] = LSNGetDatum(ControlFile->backupStartPoint);
253 values[3] = LSNGetDatum(ControlFile->backupEndPoint);
256 values[4] = BoolGetDatum(ControlFile->backupEndRequired);
259 htup = heap_form_tuple(tupdesc, values, nulls);
261 PG_RETURN_DATUM(HeapTupleGetDatum(htup));
265 pg_control_init(PG_FUNCTION_ARGS)
271 ControlFileData *ControlFile;
275 * Construct a tuple descriptor for the result row. This must match this
276 * function's pg_proc entry!
278 tupdesc = CreateTemplateTupleDesc(12);
279 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "max_data_alignment",
281 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database_block_size",
283 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "blocks_per_segment",
285 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_block_size",
287 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "bytes_per_wal_segment",
289 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "max_identifier_length",
291 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "max_index_columns",
293 TupleDescInitEntry(tupdesc, (AttrNumber) 8, "max_toast_chunk_size",
295 TupleDescInitEntry(tupdesc, (AttrNumber) 9, "large_object_chunk_size",
297 TupleDescInitEntry(tupdesc, (AttrNumber) 10, "float4_pass_by_value",
299 TupleDescInitEntry(tupdesc, (AttrNumber) 11, "float8_pass_by_value",
301 TupleDescInitEntry(tupdesc, (AttrNumber) 12, "data_page_checksum_version",
303 tupdesc = BlessTupleDesc(tupdesc);
305 /* read the control file */
306 ControlFile = get_controlfile(DataDir, &crc_ok);
309 (errmsg("calculated CRC checksum does not match value stored in file")));
311 values[0] = Int32GetDatum(ControlFile->maxAlign);
314 values[1] = Int32GetDatum(ControlFile->blcksz);
317 values[2] = Int32GetDatum(ControlFile->relseg_size);
320 values[3] = Int32GetDatum(ControlFile->xlog_blcksz);
323 values[4] = Int32GetDatum(ControlFile->xlog_seg_size);
326 values[5] = Int32GetDatum(ControlFile->nameDataLen);
329 values[6] = Int32GetDatum(ControlFile->indexMaxKeys);
332 values[7] = Int32GetDatum(ControlFile->toast_max_chunk_size);
335 values[8] = Int32GetDatum(ControlFile->loblksize);
338 values[9] = BoolGetDatum(ControlFile->float4ByVal);
341 values[10] = BoolGetDatum(ControlFile->float8ByVal);
344 values[11] = Int32GetDatum(ControlFile->data_checksum_version);
347 htup = heap_form_tuple(tupdesc, values, nulls);
349 PG_RETURN_DATUM(HeapTupleGetDatum(htup));