Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * xlogdesc.c
4 : * rmgr descriptor routines for access/transam/xlog.c
5 : *
6 : * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : *
10 : * IDENTIFICATION
11 : * src/backend/access/rmgrdesc/xlogdesc.c
12 : *
13 : *-------------------------------------------------------------------------
14 : */
15 : #include "postgres.h"
16 :
17 : #include "access/xlog.h"
18 : #include "access/xlog_internal.h"
19 : #include "catalog/pg_control.h"
20 : #include "utils/guc.h"
21 : #include "utils/timestamp.h"
22 :
23 : /*
24 : * GUC support
25 : */
26 : const struct config_enum_entry wal_level_options[] = {
27 : {"minimal", WAL_LEVEL_MINIMAL, false},
28 : {"replica", WAL_LEVEL_REPLICA, false},
29 : {"archive", WAL_LEVEL_REPLICA, true}, /* deprecated */
30 : {"hot_standby", WAL_LEVEL_REPLICA, true}, /* deprecated */
31 : {"logical", WAL_LEVEL_LOGICAL, false},
32 : {NULL, 0, false}
33 : };
34 :
35 : void
36 0 : xlog_desc(StringInfo buf, XLogReaderState *record)
37 : {
38 0 : char *rec = XLogRecGetData(record);
39 0 : uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
40 :
41 0 : if (info == XLOG_CHECKPOINT_SHUTDOWN ||
42 : info == XLOG_CHECKPOINT_ONLINE)
43 0 : {
44 0 : CheckPoint *checkpoint = (CheckPoint *) rec;
45 :
46 0 : appendStringInfo(buf, "redo %X/%X; "
47 : "tli %u; prev tli %u; fpw %s; xid %u:%u; oid %u; multi %u; offset %u; "
48 : "oldest xid %u in DB %u; oldest multi %u in DB %u; "
49 : "oldest/newest commit timestamp xid: %u/%u; "
50 : "oldest running xid %u; %s",
51 0 : (uint32) (checkpoint->redo >> 32), (uint32) checkpoint->redo,
52 : checkpoint->ThisTimeLineID,
53 : checkpoint->PrevTimeLineID,
54 0 : checkpoint->fullPageWrites ? "true" : "false",
55 : checkpoint->nextXidEpoch, checkpoint->nextXid,
56 : checkpoint->nextOid,
57 : checkpoint->nextMulti,
58 : checkpoint->nextMultiOffset,
59 : checkpoint->oldestXid,
60 : checkpoint->oldestXidDB,
61 : checkpoint->oldestMulti,
62 : checkpoint->oldestMultiDB,
63 : checkpoint->oldestCommitTsXid,
64 : checkpoint->newestCommitTsXid,
65 : checkpoint->oldestActiveXid,
66 : (info == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online");
67 : }
68 0 : else if (info == XLOG_NEXTOID)
69 : {
70 : Oid nextOid;
71 :
72 0 : memcpy(&nextOid, rec, sizeof(Oid));
73 0 : appendStringInfo(buf, "%u", nextOid);
74 : }
75 0 : else if (info == XLOG_RESTORE_POINT)
76 : {
77 0 : xl_restore_point *xlrec = (xl_restore_point *) rec;
78 :
79 0 : appendStringInfoString(buf, xlrec->rp_name);
80 : }
81 0 : else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT)
82 : {
83 : /* no further information to print */
84 : }
85 0 : else if (info == XLOG_BACKUP_END)
86 : {
87 : XLogRecPtr startpoint;
88 :
89 0 : memcpy(&startpoint, rec, sizeof(XLogRecPtr));
90 0 : appendStringInfo(buf, "%X/%X",
91 0 : (uint32) (startpoint >> 32), (uint32) startpoint);
92 : }
93 0 : else if (info == XLOG_PARAMETER_CHANGE)
94 : {
95 : xl_parameter_change xlrec;
96 : const char *wal_level_str;
97 : const struct config_enum_entry *entry;
98 :
99 0 : memcpy(&xlrec, rec, sizeof(xl_parameter_change));
100 :
101 : /* Find a string representation for wal_level */
102 0 : wal_level_str = "?";
103 0 : for (entry = wal_level_options; entry->name; entry++)
104 : {
105 0 : if (entry->val == xlrec.wal_level)
106 : {
107 0 : wal_level_str = entry->name;
108 0 : break;
109 : }
110 : }
111 :
112 0 : appendStringInfo(buf, "max_connections=%d max_worker_processes=%d "
113 : "max_prepared_xacts=%d max_locks_per_xact=%d "
114 : "wal_level=%s wal_log_hints=%s "
115 : "track_commit_timestamp=%s",
116 : xlrec.MaxConnections,
117 : xlrec.max_worker_processes,
118 : xlrec.max_prepared_xacts,
119 : xlrec.max_locks_per_xact,
120 : wal_level_str,
121 0 : xlrec.wal_log_hints ? "on" : "off",
122 0 : xlrec.track_commit_timestamp ? "on" : "off");
123 : }
124 0 : else if (info == XLOG_FPW_CHANGE)
125 : {
126 : bool fpw;
127 :
128 0 : memcpy(&fpw, rec, sizeof(bool));
129 0 : appendStringInfoString(buf, fpw ? "true" : "false");
130 : }
131 0 : else if (info == XLOG_END_OF_RECOVERY)
132 : {
133 : xl_end_of_recovery xlrec;
134 :
135 0 : memcpy(&xlrec, rec, sizeof(xl_end_of_recovery));
136 0 : appendStringInfo(buf, "tli %u; prev tli %u; time %s",
137 : xlrec.ThisTimeLineID, xlrec.PrevTimeLineID,
138 : timestamptz_to_str(xlrec.end_time));
139 : }
140 0 : }
141 :
142 : const char *
143 0 : xlog_identify(uint8 info)
144 : {
145 0 : const char *id = NULL;
146 :
147 0 : switch (info & ~XLR_INFO_MASK)
148 : {
149 : case XLOG_CHECKPOINT_SHUTDOWN:
150 0 : id = "CHECKPOINT_SHUTDOWN";
151 0 : break;
152 : case XLOG_CHECKPOINT_ONLINE:
153 0 : id = "CHECKPOINT_ONLINE";
154 0 : break;
155 : case XLOG_NOOP:
156 0 : id = "NOOP";
157 0 : break;
158 : case XLOG_NEXTOID:
159 0 : id = "NEXTOID";
160 0 : break;
161 : case XLOG_SWITCH:
162 0 : id = "SWITCH";
163 0 : break;
164 : case XLOG_BACKUP_END:
165 0 : id = "BACKUP_END";
166 0 : break;
167 : case XLOG_PARAMETER_CHANGE:
168 0 : id = "PARAMETER_CHANGE";
169 0 : break;
170 : case XLOG_RESTORE_POINT:
171 0 : id = "RESTORE_POINT";
172 0 : break;
173 : case XLOG_FPW_CHANGE:
174 0 : id = "FPW_CHANGE";
175 0 : break;
176 : case XLOG_END_OF_RECOVERY:
177 0 : id = "END_OF_RECOVERY";
178 0 : break;
179 : case XLOG_FPI:
180 0 : id = "FPI";
181 0 : break;
182 : case XLOG_FPI_FOR_HINT:
183 0 : id = "FPI_FOR_HINT";
184 0 : break;
185 : }
186 :
187 0 : return id;
188 : }
|