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