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