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
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 :
41 GNC 3 : if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
42 UNC 0 : elog(ERROR, "return type must be a row type");
43 :
44 ECB : /* read the control file */
45 CBC 3 : ControlFile = get_controlfile(DataDir, &crc_ok);
46 GIC 3 : if (!crc_ok)
47 LBC 0 : ereport(ERROR,
48 ECB : (errmsg("calculated CRC checksum does not match value stored in file")));
49 :
50 CBC 3 : values[0] = Int32GetDatum(ControlFile->pg_control_version);
51 GIC 3 : nulls[0] = false;
52 ECB :
53 GIC 3 : values[1] = Int32GetDatum(ControlFile->catalog_version_no);
54 3 : nulls[1] = false;
55 :
56 CBC 3 : values[2] = Int64GetDatum(ControlFile->system_identifier);
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 :
67 ECB : Datum
68 GBC 3 : pg_control_checkpoint(PG_FUNCTION_ARGS)
69 : {
70 : Datum values[18];
71 ECB : bool nulls[18];
72 : TupleDesc tupdesc;
73 EUB : HeapTuple htup;
74 : ControlFileData *ControlFile;
75 : XLogSegNo segno;
76 : char xlogfilename[MAXFNAMELEN];
77 : bool crc_ok;
78 :
79 GNC 3 : if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
80 UNC 0 : elog(ERROR, "return type must be a row type");
81 ECB :
82 : /* Read the control file. */
83 CBC 3 : ControlFile = get_controlfile(DataDir, &crc_ok);
84 3 : if (!crc_ok)
85 UIC 0 : ereport(ERROR,
86 ECB : (errmsg("calculated CRC checksum does not match value stored in file")));
87 :
88 : /*
89 : * Calculate name of the WAL file containing the latest checkpoint's REDO
90 : * start point.
91 : */
92 CBC 3 : XLByteToSeg(ControlFile->checkPointCopy.redo, segno, wal_segment_size);
93 3 : XLogFileName(xlogfilename, ControlFile->checkPointCopy.ThisTimeLineID,
94 : segno, wal_segment_size);
95 ECB :
96 : /* Populate the values and null arrays */
97 GIC 3 : values[0] = LSNGetDatum(ControlFile->checkPoint);
98 CBC 3 : nulls[0] = false;
99 ECB :
100 GIC 3 : values[1] = LSNGetDatum(ControlFile->checkPointCopy.redo);
101 CBC 3 : nulls[1] = false;
102 :
103 3 : values[2] = CStringGetTextDatum(xlogfilename);
104 GIC 3 : nulls[2] = false;
105 :
106 3 : values[3] = Int32GetDatum(ControlFile->checkPointCopy.ThisTimeLineID);
107 CBC 3 : nulls[3] = false;
108 :
109 GIC 3 : values[4] = Int32GetDatum(ControlFile->checkPointCopy.PrevTimeLineID);
110 3 : nulls[4] = false;
111 :
112 3 : values[5] = BoolGetDatum(ControlFile->checkPointCopy.fullPageWrites);
113 3 : nulls[5] = false;
114 :
115 3 : values[6] = CStringGetTextDatum(psprintf("%u:%u",
116 ECB : EpochFromFullTransactionId(ControlFile->checkPointCopy.nextXid),
117 EUB : XidFromFullTransactionId(ControlFile->checkPointCopy.nextXid)));
118 GIC 3 : nulls[6] = false;
119 :
120 CBC 3 : values[7] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid);
121 3 : nulls[7] = false;
122 EUB :
123 GIC 3 : values[8] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMulti);
124 3 : nulls[8] = false;
125 ECB :
126 CBC 3 : values[9] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMultiOffset);
127 GIC 3 : nulls[9] = false;
128 ECB :
129 CBC 3 : values[10] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestXid);
130 GIC 3 : nulls[10] = false;
131 ECB :
132 CBC 3 : values[11] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestXidDB);
133 GIC 3 : nulls[11] = false;
134 ECB :
135 CBC 3 : values[12] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestActiveXid);
136 GIC 3 : nulls[12] = false;
137 ECB :
138 CBC 3 : values[13] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestMulti);
139 GIC 3 : nulls[13] = false;
140 ECB :
141 GIC 3 : values[14] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestMultiDB);
142 CBC 3 : nulls[14] = false;
143 :
144 GIC 3 : values[15] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestCommitTsXid);
145 3 : nulls[15] = false;
146 ECB :
147 GIC 3 : values[16] = TransactionIdGetDatum(ControlFile->checkPointCopy.newestCommitTsXid);
148 3 : nulls[16] = false;
149 :
150 3 : values[17] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time));
151 3 : nulls[17] = false;
152 :
153 3 : htup = heap_form_tuple(tupdesc, values, nulls);
154 :
155 CBC 3 : PG_RETURN_DATUM(HeapTupleGetDatum(htup));
156 EUB : }
157 :
158 : Datum
159 CBC 3 : pg_control_recovery(PG_FUNCTION_ARGS)
160 ECB : {
161 EUB : Datum values[5];
162 : bool nulls[5];
163 : TupleDesc tupdesc;
164 ECB : HeapTuple htup;
165 : ControlFileData *ControlFile;
166 : bool crc_ok;
167 :
168 GNC 3 : if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
169 UNC 0 : elog(ERROR, "return type must be a row type");
170 :
171 ECB : /* read the control file */
172 CBC 3 : ControlFile = get_controlfile(DataDir, &crc_ok);
173 GIC 3 : if (!crc_ok)
174 LBC 0 : ereport(ERROR,
175 ECB : (errmsg("calculated CRC checksum does not match value stored in file")));
176 :
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);
184 GIC 3 : nulls[2] = false;
185 ECB :
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 :
207 GNC 3 : if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
208 UNC 0 : elog(ERROR, "return type must be a row type");
209 :
210 : /* read the control file */
211 GIC 3 : ControlFile = get_controlfile(DataDir, &crc_ok);
212 3 : if (!crc_ok)
213 UIC 0 : ereport(ERROR,
214 : (errmsg("calculated CRC checksum does not match value stored in file")));
215 :
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 :
243 3 : values[9] = BoolGetDatum(ControlFile->float8ByVal);
244 3 : nulls[9] = false;
245 :
246 3 : values[10] = Int32GetDatum(ControlFile->data_checksum_version);
247 3 : nulls[10] = false;
248 :
249 3 : htup = heap_form_tuple(tupdesc, values, nulls);
250 :
251 3 : PG_RETURN_DATUM(HeapTupleGetDatum(htup));
252 : }
|