1 /*
2  * controldata.h
3  * Copyright (c) 2ndQuadrant, 2010-2020
4  *
5  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
6  * Portions Copyright (c) 1994, Regents of the University of California
7  */
8 
9 #ifndef _CONTROLDATA_H_
10 #define _CONTROLDATA_H_
11 
12 #include "postgres_fe.h"
13 #include "catalog/pg_control.h"
14 
15 
16 #define MAX_VERSION_STRING 24
17 /*
18  * A simplified representation of pg_control containing only those fields
19  * required by repmgr.
20  */
21 typedef struct
22 {
23 	bool		control_file_processed;
24 	uint64		system_identifier;
25 	DBState		state;
26 	XLogRecPtr	checkPoint;
27 	uint32		data_checksum_version;
28 	TimeLineID	timeline;
29 	TimeLineID	minRecoveryPointTLI;
30 	XLogRecPtr	minRecoveryPoint;
31 } ControlFileInfo;
32 
33 
34 typedef struct CheckPoint94
35 {
36 	XLogRecPtr	redo;			/* next RecPtr available when we began to
37 								 * create CheckPoint (i.e. REDO start point) */
38 	TimeLineID	ThisTimeLineID; /* current TLI */
39 	TimeLineID	PrevTimeLineID; /* previous TLI, if this record begins a new
40 								 * timeline (equals ThisTimeLineID otherwise) */
41 	bool		fullPageWrites; /* current full_page_writes */
42 	uint32		nextXidEpoch;	/* higher-order bits of nextXid */
43 	TransactionId nextXid;		/* next free XID */
44 	Oid			nextOid;		/* next free OID */
45 	MultiXactId nextMulti;		/* next free MultiXactId */
46 	MultiXactOffset nextMultiOffset;	/* next free MultiXact offset */
47 	TransactionId oldestXid;	/* cluster-wide minimum datfrozenxid */
48 	Oid			oldestXidDB;	/* database with minimum datfrozenxid */
49 	MultiXactId oldestMulti;	/* cluster-wide minimum datminmxid */
50 	Oid			oldestMultiDB;	/* database with minimum datminmxid */
51 	pg_time_t	time;			/* time stamp of checkpoint */
52 
53 	TransactionId oldestActiveXid;
54 } CheckPoint94;
55 
56 
57 /* Same for 9.5, 9.6, 10, 11 */
58 typedef struct CheckPoint95
59 {
60 	XLogRecPtr	redo;			/* next RecPtr available when we began to
61 								 * create CheckPoint (i.e. REDO start point) */
62 	TimeLineID	ThisTimeLineID; /* current TLI */
63 	TimeLineID	PrevTimeLineID; /* previous TLI, if this record begins a new
64 								 * timeline (equals ThisTimeLineID otherwise) */
65 	bool		fullPageWrites; /* current full_page_writes */
66 	uint32		nextXidEpoch;	/* higher-order bits of nextXid */
67 	TransactionId nextXid;		/* next free XID */
68 	Oid			nextOid;		/* next free OID */
69 	MultiXactId nextMulti;		/* next free MultiXactId */
70 	MultiXactOffset nextMultiOffset;	/* next free MultiXact offset */
71 	TransactionId oldestXid;	/* cluster-wide minimum datfrozenxid */
72 	Oid			oldestXidDB;	/* database with minimum datfrozenxid */
73 	MultiXactId oldestMulti;	/* cluster-wide minimum datminmxid */
74 	Oid			oldestMultiDB;	/* database with minimum datminmxid */
75 	pg_time_t	time;			/* time stamp of checkpoint */
76 	TransactionId oldestCommitTsXid;	/* oldest Xid with valid commit
77 										 * timestamp */
78 	TransactionId newestCommitTsXid;	/* newest Xid with valid commit
79 										 * timestamp */
80 
81 	TransactionId oldestActiveXid;
82 } CheckPoint95;
83 
84 
85 #if PG_ACTUAL_VERSION_NUM >= 120000
86 /*
87  * Following fields removed in PostgreSQL 12;
88  *
89  *   uint32 nextXidEpoch;
90  *   TransactionId nextXid;
91  *
92  * and replaced by:
93  *
94  *   FullTransactionId nextFullXid;
95  */
96 
97 typedef struct CheckPoint12
98 {
99 	XLogRecPtr	redo;			/* next RecPtr available when we began to
100 								 * create CheckPoint (i.e. REDO start point) */
101 	TimeLineID	ThisTimeLineID; /* current TLI */
102 	TimeLineID	PrevTimeLineID; /* previous TLI, if this record begins a new
103 								 * timeline (equals ThisTimeLineID otherwise) */
104 	bool		fullPageWrites; /* current full_page_writes */
105 	FullTransactionId nextFullXid;	/* next free full transaction ID */
106 	Oid			nextOid;		/* next free OID */
107 	MultiXactId nextMulti;		/* next free MultiXactId */
108 	MultiXactOffset nextMultiOffset;	/* next free MultiXact offset */
109 	TransactionId oldestXid;	/* cluster-wide minimum datfrozenxid */
110 	Oid			oldestXidDB;	/* database with minimum datfrozenxid */
111 	MultiXactId oldestMulti;	/* cluster-wide minimum datminmxid */
112 	Oid			oldestMultiDB;	/* database with minimum datminmxid */
113 	pg_time_t	time;			/* time stamp of checkpoint */
114 	TransactionId oldestCommitTsXid;	/* oldest Xid with valid commit
115 										 * timestamp */
116 	TransactionId newestCommitTsXid;	/* newest Xid with valid commit
117 										 * timestamp */
118 
119 	/*
120 	 * Oldest XID still running. This is only needed to initialize hot standby
121 	 * mode from an online checkpoint, so we only bother calculating this for
122 	 * online checkpoints and only when wal_level is replica. Otherwise it's
123 	 * set to InvalidTransactionId.
124 	 */
125 	TransactionId oldestActiveXid;
126 } CheckPoint12;
127 #endif
128 
129 
130 typedef struct ControlFileData94
131 {
132 	uint64		system_identifier;
133 
134 	uint32		pg_control_version;		/* PG_CONTROL_VERSION */
135 	uint32		catalog_version_no;		/* see catversion.h */
136 
137 	DBState		state;			/* see enum above */
138 	pg_time_t	time;			/* time stamp of last pg_control update */
139 	XLogRecPtr	checkPoint;		/* last check point record ptr */
140 	XLogRecPtr	prevCheckPoint; /* previous check point record ptr */
141 
142 	CheckPoint94	checkPointCopy; /* copy of last check point record */
143 
144 	XLogRecPtr	unloggedLSN;	/* current fake LSN value, for unlogged rels */
145 
146 	XLogRecPtr	minRecoveryPoint;
147 	TimeLineID	minRecoveryPointTLI;
148 	XLogRecPtr	backupStartPoint;
149 	XLogRecPtr	backupEndPoint;
150 	bool		backupEndRequired;
151 
152 	int			wal_level;
153 	bool		wal_log_hints;
154 	int			MaxConnections;
155 	int			max_worker_processes;
156 	int			max_prepared_xacts;
157 	int			max_locks_per_xact;
158 
159 	uint32		maxAlign;		/* alignment requirement for tuples */
160 	double		floatFormat;	/* constant 1234567.0 */
161 
162 	uint32		blcksz;			/* data block size for this DB */
163 	uint32		relseg_size;	/* blocks per segment of large relation */
164 
165 	uint32		xlog_blcksz;	/* block size within WAL files */
166 	uint32		xlog_seg_size;	/* size of each WAL segment */
167 
168 	uint32		nameDataLen;	/* catalog name field width */
169 	uint32		indexMaxKeys;	/* max number of columns in an index */
170 
171 	uint32		toast_max_chunk_size;	/* chunk size in TOAST tables */
172 	uint32		loblksize;		/* chunk size in pg_largeobject */
173 
174 	bool		enableIntTimes; /* int64 storage enabled? */
175 
176 	bool		float4ByVal;	/* float4 pass-by-value? */
177 	bool		float8ByVal;	/* float8, int8, etc pass-by-value? */
178 
179 	/* Are data pages protected by checksums? Zero if no checksum version */
180 	uint32		data_checksum_version;
181 
182 } ControlFileData94;
183 
184 
185 
186 /*
187  * Following field added since 9.4:
188  *
189  *	bool		track_commit_timestamp;
190  *
191  * Unchanged in 9.6
192  *
193  * In 10, following field appended *after* "data_checksum_version":
194  *
195  *	char		mock_authentication_nonce[MOCK_AUTH_NONCE_LEN];
196  *
197  * (but we don't care about that)
198  */
199 
200 typedef struct ControlFileData95
201 {
202 	uint64		system_identifier;
203 
204 	uint32		pg_control_version;		/* PG_CONTROL_VERSION */
205 	uint32		catalog_version_no;		/* see catversion.h */
206 
207 	DBState		state;			/* see enum above */
208 	pg_time_t	time;			/* time stamp of last pg_control update */
209 	XLogRecPtr	checkPoint;		/* last check point record ptr */
210 	XLogRecPtr	prevCheckPoint; /* previous check point record ptr */
211 
212 	CheckPoint95	checkPointCopy; /* copy of last check point record */
213 
214 	XLogRecPtr	unloggedLSN;	/* current fake LSN value, for unlogged rels */
215 
216 	XLogRecPtr	minRecoveryPoint;
217 	TimeLineID	minRecoveryPointTLI;
218 	XLogRecPtr	backupStartPoint;
219 	XLogRecPtr	backupEndPoint;
220 	bool		backupEndRequired;
221 
222 	int			wal_level;
223 	bool		wal_log_hints;
224 	int			MaxConnections;
225 	int			max_worker_processes;
226 	int			max_prepared_xacts;
227 	int			max_locks_per_xact;
228 	bool		track_commit_timestamp;
229 
230 	uint32		maxAlign;		/* alignment requirement for tuples */
231 	double		floatFormat;	/* constant 1234567.0 */
232 
233 	uint32		blcksz;			/* data block size for this DB */
234 	uint32		relseg_size;	/* blocks per segment of large relation */
235 
236 	uint32		xlog_blcksz;	/* block size within WAL files */
237 	uint32		xlog_seg_size;	/* size of each WAL segment */
238 
239 	uint32		nameDataLen;	/* catalog name field width */
240 	uint32		indexMaxKeys;	/* max number of columns in an index */
241 
242 	uint32		toast_max_chunk_size;	/* chunk size in TOAST tables */
243 	uint32		loblksize;		/* chunk size in pg_largeobject */
244 
245 	bool		enableIntTimes; /* int64 storage enabled? */
246 
247 	bool		float4ByVal;	/* float4 pass-by-value? */
248 	bool		float8ByVal;	/* float8, int8, etc pass-by-value? */
249 
250 	uint32		data_checksum_version;
251 
252 } ControlFileData95;
253 
254 /*
255  * Following field removed in 11:
256  *
257  *  XLogRecPtr	prevCheckPoint;
258  *
259  * In 10, following field appended *after* "data_checksum_version":
260  *
261  * 	char		mock_authentication_nonce[MOCK_AUTH_NONCE_LEN];
262  *
263  * (but we don't care about that)
264  */
265 
266 typedef struct ControlFileData11
267 {
268 	uint64		system_identifier;
269 
270 	uint32		pg_control_version;		/* PG_CONTROL_VERSION */
271 	uint32		catalog_version_no;		/* see catversion.h */
272 
273 	DBState		state;			/* see enum above */
274 	pg_time_t	time;			/* time stamp of last pg_control update */
275 	XLogRecPtr	checkPoint;		/* last check point record ptr */
276 
277 	CheckPoint95	checkPointCopy; /* copy of last check point record */
278 
279 	XLogRecPtr	unloggedLSN;	/* current fake LSN value, for unlogged rels */
280 
281 	XLogRecPtr	minRecoveryPoint;
282 	TimeLineID	minRecoveryPointTLI;
283 	XLogRecPtr	backupStartPoint;
284 	XLogRecPtr	backupEndPoint;
285 	bool		backupEndRequired;
286 
287 	int			wal_level;
288 	bool		wal_log_hints;
289 	int			MaxConnections;
290 	int			max_worker_processes;
291 	int			max_prepared_xacts;
292 	int			max_locks_per_xact;
293 	bool		track_commit_timestamp;
294 
295 	uint32		maxAlign;		/* alignment requirement for tuples */
296 	double		floatFormat;	/* constant 1234567.0 */
297 
298 	uint32		blcksz;			/* data block size for this DB */
299 	uint32		relseg_size;	/* blocks per segment of large relation */
300 
301 	uint32		xlog_blcksz;	/* block size within WAL files */
302 	uint32		xlog_seg_size;	/* size of each WAL segment */
303 
304 	uint32		nameDataLen;	/* catalog name field width */
305 	uint32		indexMaxKeys;	/* max number of columns in an index */
306 
307 	uint32		toast_max_chunk_size;	/* chunk size in TOAST tables */
308 	uint32		loblksize;		/* chunk size in pg_largeobject */
309 
310 	bool		enableIntTimes; /* int64 storage enabled? */
311 
312 	bool		float4ByVal;	/* float4 pass-by-value? */
313 	bool		float8ByVal;	/* float8, int8, etc pass-by-value? */
314 
315 	uint32		data_checksum_version;
316 
317 } ControlFileData11;
318 
319 
320 #if PG_ACTUAL_VERSION_NUM >= 120000
321 /*
322  * Following field added in Pg12:
323  *
324  *   int max_wal_senders;
325  */
326 
327 typedef struct ControlFileData12
328 {
329 	uint64		system_identifier;
330 
331 	uint32		pg_control_version; /* PG_CONTROL_VERSION */
332 	uint32		catalog_version_no; /* see catversion.h */
333 
334 	DBState		state;			/* see enum above */
335 	pg_time_t	time;			/* time stamp of last pg_control update */
336 	XLogRecPtr	checkPoint;		/* last check point record ptr */
337 
338 	CheckPoint12	checkPointCopy; /* copy of last check point record */
339 
340 	XLogRecPtr	unloggedLSN;	/* current fake LSN value, for unlogged rels */
341 
342 	XLogRecPtr	minRecoveryPoint;
343 	TimeLineID	minRecoveryPointTLI;
344 	XLogRecPtr	backupStartPoint;
345 	XLogRecPtr	backupEndPoint;
346 	bool		backupEndRequired;
347 
348 	int			wal_level;
349 	bool		wal_log_hints;
350 	int			MaxConnections;
351 	int			max_worker_processes;
352 	int			max_wal_senders;
353 	int			max_prepared_xacts;
354 	int			max_locks_per_xact;
355 	bool		track_commit_timestamp;
356 
357 	uint32		maxAlign;		/* alignment requirement for tuples */
358 	double		floatFormat;	/* constant 1234567.0 */
359 
360 	uint32		blcksz;			/* data block size for this DB */
361 	uint32		relseg_size;	/* blocks per segment of large relation */
362 
363 	uint32		xlog_blcksz;	/* block size within WAL files */
364 	uint32		xlog_seg_size;	/* size of each WAL segment */
365 
366 	uint32		nameDataLen;	/* catalog name field width */
367 	uint32		indexMaxKeys;	/* max number of columns in an index */
368 
369 	uint32		toast_max_chunk_size;	/* chunk size in TOAST tables */
370 	uint32		loblksize;		/* chunk size in pg_largeobject */
371 
372 	bool		float4ByVal;	/* float4 pass-by-value? */
373 	bool		float8ByVal;	/* float8, int8, etc pass-by-value? */
374 
375 	uint32		data_checksum_version;
376 } ControlFileData12;
377 #endif
378 
379 extern int get_pg_version(const char *data_directory, char *version_string);
380 extern bool get_db_state(const char *data_directory, DBState *state);
381 extern const char *describe_db_state(DBState state);
382 extern int	get_data_checksum_version(const char *data_directory);
383 extern uint64 get_system_identifier(const char *data_directory);
384 extern XLogRecPtr get_latest_checkpoint_location(const char *data_directory);
385 extern TimeLineID get_timeline(const char *data_directory);
386 extern TimeLineID get_min_recovery_end_timeline(const char *data_directory);
387 extern XLogRecPtr get_min_recovery_location(const char *data_directory);
388 
389 #endif							/* _CONTROLDATA_H_ */
390