Age Owner TLA Line data Source code
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-2023, 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"
24 : #include "common/controldata_utils.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
2591 mail 32 CBC 3 : pg_control_system(PG_FUNCTION_ARGS)
33 : {
34 : Datum values[4];
35 : bool nulls[4];
36 : TupleDesc tupdesc;
37 : HeapTuple htup;
38 : ControlFileData *ControlFile;
39 : bool crc_ok;
40 :
109 michael 41 GNC 3 : if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
109 michael 42 UNC 0 : elog(ERROR, "return type must be a row type");
43 :
2591 mail 44 ECB : /* read the control file */
1469 peter 45 CBC 3 : ControlFile = get_controlfile(DataDir, &crc_ok);
2384 peter_e 46 GIC 3 : if (!crc_ok)
2448 peter_e 47 LBC 0 : ereport(ERROR,
2448 peter_e 48 ECB : (errmsg("calculated CRC checksum does not match value stored in file")));
49 :
2591 mail 50 CBC 3 : values[0] = Int32GetDatum(ControlFile->pg_control_version);
2591 mail 51 GIC 3 : nulls[0] = false;
2591 mail 52 ECB :
2591 mail 53 GIC 3 : values[1] = Int32GetDatum(ControlFile->catalog_version_no);
54 3 : nulls[1] = false;
55 :
2591 mail 56 CBC 3 : values[2] = Int64GetDatum(ControlFile->system_identifier);
2591 mail 57 GIC 3 : nulls[2] = false;
58 :
59 3 : values[3] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->time));
60 3 : nulls[3] = false;
61 :
62 3 : htup = heap_form_tuple(tupdesc, values, nulls);
63 :
64 3 : PG_RETURN_DATUM(HeapTupleGetDatum(htup));
65 : }
66 :
2591 mail 67 ECB : Datum
2591 mail 68 GBC 3 : pg_control_checkpoint(PG_FUNCTION_ARGS)
69 : {
70 : Datum values[18];
193 rhaas 71 ECB : bool nulls[18];
2495 72 : TupleDesc tupdesc;
2495 rhaas 73 EUB : HeapTuple htup;
74 : ControlFileData *ControlFile;
75 : XLogSegNo segno;
76 : char xlogfilename[MAXFNAMELEN];
77 : bool crc_ok;
78 :
109 michael 79 GNC 3 : if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
109 michael 80 UNC 0 : elog(ERROR, "return type must be a row type");
2591 mail 81 ECB :
82 : /* Read the control file. */
1469 peter 83 CBC 3 : ControlFile = get_controlfile(DataDir, &crc_ok);
2384 peter_e 84 3 : if (!crc_ok)
2448 peter_e 85 UIC 0 : ereport(ERROR,
2448 peter_e 86 ECB : (errmsg("calculated CRC checksum does not match value stored in file")));
2591 mail 87 :
88 : /*
89 : * Calculate name of the WAL file containing the latest checkpoint's REDO
90 : * start point.
91 : */
2028 andres 92 CBC 3 : XLByteToSeg(ControlFile->checkPointCopy.redo, segno, wal_segment_size);
93 3 : XLogFileName(xlogfilename, ControlFile->checkPointCopy.ThisTimeLineID,
94 : segno, wal_segment_size);
2591 mail 95 ECB :
96 : /* Populate the values and null arrays */
2591 mail 97 GIC 3 : values[0] = LSNGetDatum(ControlFile->checkPoint);
2591 mail 98 CBC 3 : nulls[0] = false;
2591 mail 99 ECB :
1979 simon 100 GIC 3 : values[1] = LSNGetDatum(ControlFile->checkPointCopy.redo);
2591 mail 101 CBC 3 : nulls[1] = false;
102 :
1979 simon 103 3 : values[2] = CStringGetTextDatum(xlogfilename);
2591 mail 104 GIC 3 : nulls[2] = false;
105 :
1979 simon 106 3 : values[3] = Int32GetDatum(ControlFile->checkPointCopy.ThisTimeLineID);
2591 mail 107 CBC 3 : nulls[3] = false;
108 :
1979 simon 109 GIC 3 : values[4] = Int32GetDatum(ControlFile->checkPointCopy.PrevTimeLineID);
2591 mail 110 3 : nulls[4] = false;
111 :
1979 simon 112 3 : values[5] = BoolGetDatum(ControlFile->checkPointCopy.fullPageWrites);
2591 mail 113 3 : nulls[5] = false;
114 :
1979 simon 115 3 : values[6] = CStringGetTextDatum(psprintf("%u:%u",
971 andres 116 ECB : EpochFromFullTransactionId(ControlFile->checkPointCopy.nextXid),
971 andres 117 EUB : XidFromFullTransactionId(ControlFile->checkPointCopy.nextXid)));
1979 simon 118 GIC 3 : nulls[6] = false;
119 :
1979 simon 120 CBC 3 : values[7] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid);
2591 mail 121 3 : nulls[7] = false;
2591 mail 122 EUB :
1979 simon 123 GIC 3 : values[8] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMulti);
2591 mail 124 3 : nulls[8] = false;
2591 mail 125 ECB :
1979 simon 126 CBC 3 : values[9] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMultiOffset);
2591 mail 127 GIC 3 : nulls[9] = false;
2591 mail 128 ECB :
1979 simon 129 CBC 3 : values[10] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestXid);
2591 mail 130 GIC 3 : nulls[10] = false;
2591 mail 131 ECB :
1979 simon 132 CBC 3 : values[11] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestXidDB);
2591 mail 133 GIC 3 : nulls[11] = false;
2591 mail 134 ECB :
1979 simon 135 CBC 3 : values[12] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestActiveXid);
2591 mail 136 GIC 3 : nulls[12] = false;
2591 mail 137 ECB :
1979 simon 138 CBC 3 : values[13] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestMulti);
2591 mail 139 GIC 3 : nulls[13] = false;
2591 mail 140 ECB :
1979 simon 141 GIC 3 : values[14] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestMultiDB);
2591 mail 142 CBC 3 : nulls[14] = false;
143 :
1979 simon 144 GIC 3 : values[15] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestCommitTsXid);
2591 mail 145 3 : nulls[15] = false;
2591 mail 146 ECB :
1979 simon 147 GIC 3 : values[16] = TransactionIdGetDatum(ControlFile->checkPointCopy.newestCommitTsXid);
2591 mail 148 3 : nulls[16] = false;
149 :
1165 alvherre 150 3 : values[17] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time));
1979 simon 151 3 : nulls[17] = false;
152 :
2591 mail 153 3 : htup = heap_form_tuple(tupdesc, values, nulls);
154 :
2591 mail 155 CBC 3 : PG_RETURN_DATUM(HeapTupleGetDatum(htup));
2591 mail 156 EUB : }
157 :
158 : Datum
2591 mail 159 CBC 3 : pg_control_recovery(PG_FUNCTION_ARGS)
2591 mail 160 ECB : {
2495 rhaas 161 EUB : Datum values[5];
162 : bool nulls[5];
163 : TupleDesc tupdesc;
2495 rhaas 164 ECB : HeapTuple htup;
165 : ControlFileData *ControlFile;
166 : bool crc_ok;
2591 mail 167 :
109 michael 168 GNC 3 : if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
109 michael 169 UNC 0 : elog(ERROR, "return type must be a row type");
170 :
2591 mail 171 ECB : /* read the control file */
1469 peter 172 CBC 3 : ControlFile = get_controlfile(DataDir, &crc_ok);
2384 peter_e 173 GIC 3 : if (!crc_ok)
2448 peter_e 174 LBC 0 : ereport(ERROR,
2448 peter_e 175 ECB : (errmsg("calculated CRC checksum does not match value stored in file")));
176 :
2591 mail 177 CBC 3 : values[0] = LSNGetDatum(ControlFile->minRecoveryPoint);
178 3 : nulls[0] = false;
179 :
180 3 : values[1] = Int32GetDatum(ControlFile->minRecoveryPointTLI);
181 3 : nulls[1] = false;
182 :
183 3 : values[2] = LSNGetDatum(ControlFile->backupStartPoint);
2591 mail 184 GIC 3 : nulls[2] = false;
2591 mail 185 ECB :
2591 mail 186 GIC 3 : values[3] = LSNGetDatum(ControlFile->backupEndPoint);
187 3 : nulls[3] = false;
188 :
189 3 : values[4] = BoolGetDatum(ControlFile->backupEndRequired);
190 3 : nulls[4] = false;
191 :
192 3 : htup = heap_form_tuple(tupdesc, values, nulls);
193 :
194 3 : PG_RETURN_DATUM(HeapTupleGetDatum(htup));
195 : }
196 :
197 : Datum
198 3 : pg_control_init(PG_FUNCTION_ARGS)
199 : {
200 : Datum values[11];
201 : bool nulls[11];
202 : TupleDesc tupdesc;
203 : HeapTuple htup;
204 : ControlFileData *ControlFile;
205 : bool crc_ok;
206 :
109 michael 207 GNC 3 : if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
109 michael 208 UNC 0 : elog(ERROR, "return type must be a row type");
209 :
210 : /* read the control file */
1469 peter 211 GIC 3 : ControlFile = get_controlfile(DataDir, &crc_ok);
2384 peter_e 212 3 : if (!crc_ok)
2448 peter_e 213 UIC 0 : ereport(ERROR,
214 : (errmsg("calculated CRC checksum does not match value stored in file")));
215 :
2591 mail 216 GIC 3 : values[0] = Int32GetDatum(ControlFile->maxAlign);
217 3 : nulls[0] = false;
218 :
219 3 : values[1] = Int32GetDatum(ControlFile->blcksz);
220 3 : nulls[1] = false;
221 :
222 3 : values[2] = Int32GetDatum(ControlFile->relseg_size);
223 3 : nulls[2] = false;
224 :
225 3 : values[3] = Int32GetDatum(ControlFile->xlog_blcksz);
226 3 : nulls[3] = false;
227 :
228 3 : values[4] = Int32GetDatum(ControlFile->xlog_seg_size);
229 3 : nulls[4] = false;
230 :
231 3 : values[5] = Int32GetDatum(ControlFile->nameDataLen);
232 3 : nulls[5] = false;
233 :
234 3 : values[6] = Int32GetDatum(ControlFile->indexMaxKeys);
235 3 : nulls[6] = false;
236 :
237 3 : values[7] = Int32GetDatum(ControlFile->toast_max_chunk_size);
238 3 : nulls[7] = false;
239 :
240 3 : values[8] = Int32GetDatum(ControlFile->loblksize);
241 3 : nulls[8] = false;
242 :
1235 peter 243 3 : values[9] = BoolGetDatum(ControlFile->float8ByVal);
2591 mail 244 3 : nulls[9] = false;
245 :
1235 peter 246 3 : values[10] = Int32GetDatum(ControlFile->data_checksum_version);
2591 mail 247 3 : nulls[10] = false;
248 :
249 3 : htup = heap_form_tuple(tupdesc, values, nulls);
250 :
251 3 : PG_RETURN_DATUM(HeapTupleGetDatum(htup));
252 : }
|