1 /*-------------------------------------------------------------------------
5 * Routines to expose the contents of the control data file via
6 * a set of SQL functions.
8 * Portions Copyright (c) 1996-2024, 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.h"
21 #include "access/xlog_internal.h"
22 #include "catalog/pg_control.h"
23 #include "common/controldata_utils.h"
25 #include "miscadmin.h"
26 #include "storage/lwlock.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
;
41 if (get_call_result_type(fcinfo
, NULL
, &tupdesc
) != TYPEFUNC_COMPOSITE
)
42 elog(ERROR
, "return type must be a row type");
44 /* read the control file */
45 LWLockAcquire(ControlFileLock
, LW_SHARED
);
46 ControlFile
= get_controlfile(DataDir
, &crc_ok
);
47 LWLockRelease(ControlFileLock
);
50 (errmsg("calculated CRC checksum does not match value stored in file")));
52 values
[0] = Int32GetDatum(ControlFile
->pg_control_version
);
55 values
[1] = Int32GetDatum(ControlFile
->catalog_version_no
);
58 values
[2] = Int64GetDatum(ControlFile
->system_identifier
);
61 values
[3] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile
->time
));
64 htup
= heap_form_tuple(tupdesc
, values
, nulls
);
66 PG_RETURN_DATUM(HeapTupleGetDatum(htup
));
70 pg_control_checkpoint(PG_FUNCTION_ARGS
)
76 ControlFileData
*ControlFile
;
78 char xlogfilename
[MAXFNAMELEN
];
81 if (get_call_result_type(fcinfo
, NULL
, &tupdesc
) != TYPEFUNC_COMPOSITE
)
82 elog(ERROR
, "return type must be a row type");
84 /* Read the control file. */
85 LWLockAcquire(ControlFileLock
, LW_SHARED
);
86 ControlFile
= get_controlfile(DataDir
, &crc_ok
);
87 LWLockRelease(ControlFileLock
);
90 (errmsg("calculated CRC checksum does not match value stored in file")));
93 * Calculate name of the WAL file containing the latest checkpoint's REDO
96 XLByteToSeg(ControlFile
->checkPointCopy
.redo
, segno
, wal_segment_size
);
97 XLogFileName(xlogfilename
, ControlFile
->checkPointCopy
.ThisTimeLineID
,
98 segno
, wal_segment_size
);
100 /* Populate the values and null arrays */
101 values
[0] = LSNGetDatum(ControlFile
->checkPoint
);
104 values
[1] = LSNGetDatum(ControlFile
->checkPointCopy
.redo
);
107 values
[2] = CStringGetTextDatum(xlogfilename
);
110 values
[3] = Int32GetDatum(ControlFile
->checkPointCopy
.ThisTimeLineID
);
113 values
[4] = Int32GetDatum(ControlFile
->checkPointCopy
.PrevTimeLineID
);
116 values
[5] = BoolGetDatum(ControlFile
->checkPointCopy
.fullPageWrites
);
119 values
[6] = CStringGetTextDatum(psprintf("%u:%u",
120 EpochFromFullTransactionId(ControlFile
->checkPointCopy
.nextXid
),
121 XidFromFullTransactionId(ControlFile
->checkPointCopy
.nextXid
)));
124 values
[7] = ObjectIdGetDatum(ControlFile
->checkPointCopy
.nextOid
);
127 values
[8] = TransactionIdGetDatum(ControlFile
->checkPointCopy
.nextMulti
);
130 values
[9] = TransactionIdGetDatum(ControlFile
->checkPointCopy
.nextMultiOffset
);
133 values
[10] = TransactionIdGetDatum(ControlFile
->checkPointCopy
.oldestXid
);
136 values
[11] = ObjectIdGetDatum(ControlFile
->checkPointCopy
.oldestXidDB
);
139 values
[12] = TransactionIdGetDatum(ControlFile
->checkPointCopy
.oldestActiveXid
);
142 values
[13] = TransactionIdGetDatum(ControlFile
->checkPointCopy
.oldestMulti
);
145 values
[14] = ObjectIdGetDatum(ControlFile
->checkPointCopy
.oldestMultiDB
);
148 values
[15] = TransactionIdGetDatum(ControlFile
->checkPointCopy
.oldestCommitTsXid
);
151 values
[16] = TransactionIdGetDatum(ControlFile
->checkPointCopy
.newestCommitTsXid
);
154 values
[17] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile
->checkPointCopy
.time
));
157 htup
= heap_form_tuple(tupdesc
, values
, nulls
);
159 PG_RETURN_DATUM(HeapTupleGetDatum(htup
));
163 pg_control_recovery(PG_FUNCTION_ARGS
)
169 ControlFileData
*ControlFile
;
172 if (get_call_result_type(fcinfo
, NULL
, &tupdesc
) != TYPEFUNC_COMPOSITE
)
173 elog(ERROR
, "return type must be a row type");
175 /* read the control file */
176 LWLockAcquire(ControlFileLock
, LW_SHARED
);
177 ControlFile
= get_controlfile(DataDir
, &crc_ok
);
178 LWLockRelease(ControlFileLock
);
181 (errmsg("calculated CRC checksum does not match value stored in file")));
183 values
[0] = LSNGetDatum(ControlFile
->minRecoveryPoint
);
186 values
[1] = Int32GetDatum(ControlFile
->minRecoveryPointTLI
);
189 values
[2] = LSNGetDatum(ControlFile
->backupStartPoint
);
192 values
[3] = LSNGetDatum(ControlFile
->backupEndPoint
);
195 values
[4] = BoolGetDatum(ControlFile
->backupEndRequired
);
198 htup
= heap_form_tuple(tupdesc
, values
, nulls
);
200 PG_RETURN_DATUM(HeapTupleGetDatum(htup
));
204 pg_control_init(PG_FUNCTION_ARGS
)
210 ControlFileData
*ControlFile
;
213 if (get_call_result_type(fcinfo
, NULL
, &tupdesc
) != TYPEFUNC_COMPOSITE
)
214 elog(ERROR
, "return type must be a row type");
216 /* read the control file */
217 LWLockAcquire(ControlFileLock
, LW_SHARED
);
218 ControlFile
= get_controlfile(DataDir
, &crc_ok
);
219 LWLockRelease(ControlFileLock
);
222 (errmsg("calculated CRC checksum does not match value stored in file")));
224 values
[0] = Int32GetDatum(ControlFile
->maxAlign
);
227 values
[1] = Int32GetDatum(ControlFile
->blcksz
);
230 values
[2] = Int32GetDatum(ControlFile
->relseg_size
);
233 values
[3] = Int32GetDatum(ControlFile
->xlog_blcksz
);
236 values
[4] = Int32GetDatum(ControlFile
->xlog_seg_size
);
239 values
[5] = Int32GetDatum(ControlFile
->nameDataLen
);
242 values
[6] = Int32GetDatum(ControlFile
->indexMaxKeys
);
245 values
[7] = Int32GetDatum(ControlFile
->toast_max_chunk_size
);
248 values
[8] = Int32GetDatum(ControlFile
->loblksize
);
251 values
[9] = BoolGetDatum(ControlFile
->float8ByVal
);
254 values
[10] = Int32GetDatum(ControlFile
->data_checksum_version
);
257 htup
= heap_form_tuple(tupdesc
, values
, nulls
);
259 PG_RETURN_DATUM(HeapTupleGetDatum(htup
));