MySQL 8.1.0
Source Code Documentation
cursor_by_error_log.h
Go to the documentation of this file.
1/* Copyright (c) 2020, 2023, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#ifndef CURSOR_BY_ERROR_LOG_H
25#define CURSOR_BY_ERROR_LOG_H
26
27/**
28 @file storage/perfschema/cursor_by_error_log.h
29 Cursor CURSOR_BY_ERROR_LOG (declarations);
30 PFS_ringbuffer_index, PFS_index_error_log.
31*/
32
37
38/**
39 Index in the error-log ring-buffer.
40
41 Has a numeric index, a pointer to an event in the buffer,
42 and the timestamp for that event.
43 This lets us easily check whether this index is still
44 valid: its timestamp must be greater than or equal to
45 that of the ring-buffer's oldest entry (the tail or
46 "read-position"). If our timestamp is older than that
47 value, it points to an event that has since expired.
48*/
50 private:
51 /**
52 Numeric row index. valid range [0;num_events[. -1 == EOF
53 */
55 /**
56 Pointer to an event in the ring-buffer.
57 Before dereferencing this pointer, use
58 @see log_sink_pfs_event_valid()
59 to make sure it has not become stale.
60 */
62 /**
63 Time-stamp we copied from the event we
64 point to when setting this index.
65 The ring-buffer keeps track of what the
66 oldest item in it is. If our timestamp
67 is older than that item's timestamp,
68 the event we're pointing too has been
69 purged from the ring-buffer, and our
70 pointer is stale. 0 for undefined.
71 */
73
74 public:
75 /**
76 Reset index.
77 */
78 void reset() {
79 m_index = 0;
80 m_event = nullptr;
81 m_timestamp = 0;
82 }
83
84 /**
85 Constructor.
86 */
88
89 /**
90 Set this index to a given position.
91 This copies ``other`` without validating it.
92
93 @param other set our index from the given one
94 */
95 void set_at(const PFS_ringbuffer_index *other) {
96 m_index = other->m_index;
97 m_event = other->m_event;
98 m_timestamp = other->m_timestamp;
99 }
100
101 /**
102 Set our index to the element after the given one
103 (if that is valid; otherwise, we cannot determine a next element).
104
105 Caller should hold read-lock on ring-buffer.
106
107 @param other set our index to the position after the given one
108 */
109 void set_after(const PFS_ringbuffer_index *other) {
110 assert(other != nullptr);
111
112 // special case: ``other`` was reset or is otherwise at index start
113 if ((other->m_index == 0) &&
114 ((m_event = log_sink_pfs_event_first()) != nullptr) &&
115 ((m_event = log_sink_pfs_event_next(m_event)) != nullptr)) {
116 m_timestamp = m_event->m_timestamp; // save timestamp
117 m_index = 1; // "calculate" new index
118 return;
119 }
120
121 // if ``other`` is valid and has a successor, use that
122 if ((other->m_index != -1) && // EOF?
124 ((m_event = log_sink_pfs_event_next(other->m_event)) != nullptr)) {
125 m_timestamp = m_event->m_timestamp; // save timestamp
126 m_index = other->m_index + 1; // "calculate" new index
127 return;
128 }
129
130 // no valid successor found
131 reset(); // reset this index
132 m_index = -1; // flag EOF
133 }
134
135 /**
136 Get event if it's still valid.
137
138 Caller should hold read-lock on ring-buffer.
139
140 If ``m_index`` is 0, the index was reset, and we re-obtain the
141 ring-buffer's read-pointer / tail. This updates m_event and
142 m_timestamp.
143
144 If ``m_index`` is -1 (EOF), we return ``nullptr``.
145
146 Otherwise, we try to obtain the event in the ring-buffer pointed
147 to by m_event. If that event is still valid, we return it;
148 otherwise, we return nullptr (but leave the stale pointer on
149 the object for debugging). It is therefore vital to to determine
150 success/failure by checking the retval rather than calling this
151 method and then checking m_event directly!
152
153 @retval nullptr no event (EOF, empty buffer, or stale index)
154 @retval !=nullptr the event this index is referring to
155 */
157 /*
158 Special case: the index was reset.
159 Refresh pointer from oldest entry in the ring-buffer.
160 */
161 if (m_index == 0) {
163 ((m_event = log_sink_pfs_event_first()) == nullptr)
164 ? 0 // first() failed: buffer empty. zero the timestamp.
166
167 /*
168 We don't log_sink_pfs_event_valid() the event here.
169 We only just got it, and we should be holding a read-lock
170 on the ring-buffer, so the event can't have expired.
171 */
172
173 return m_event; // { 0, nullptr, 0 } on empty buffer, otherwise a valid
174 // event
175 }
176
177 /*
178 If the index is at EOF, or points to an element that has since been
179 discarded from the ring-buffer, we have no event we could return.
180 */
182 return nullptr; // no event to get
183
184 return m_event; // return valid event
185 }
186
187 /**
188 Return current record (if valid), then set index to the next record.
189
190 Caller should hold read-lock on ring-buffer.
191 Returned value is only valid as long as the lock is held.
192
193 Note that three states are possible:
194 a) an event-pointer is returned, and the index points to a valid
195 succeeding event (i.e. is not EOF): there are more elements
196 b) an event-pointer is returned, but the index now flags EOF:
197 this was the last element
198 c) NULL is returned, and the index flags EOF:
199 no event could be obtained (the buffer is empty, or we're at EOF)
200
201 Updates m_event, m_timestamp, and m_index.
202
203 @retval nullptr no valid record could be obtained (end of buffer etc.)
204 @retval !=nullptr pointer to an entry in the ring-buffer
205 */
207 log_sink_pfs_event *current_event;
208
209 // Is there a valid current event that we can load into this object?
210 current_event = get_event();
211 if (current_event != nullptr) { // save current event if any
212 // try to advance index to next event
213 m_event = log_sink_pfs_event_next(current_event);
214 if (m_event != nullptr) {
215 // success. update this index object.
217 m_index++;
218 return current_event;
219 }
220 // If we get here, current_event is valid, but has no successor.
221 }
222
223 // Index now points to an invalid event. Flag EOF.
224 m_event = nullptr;
225 m_timestamp = 0;
226 m_index = -1;
227
228 // last event in buffer (if get_event() succeeded), or NULL otherwise.
229 return current_event;
230 }
231};
232
234
235/**
236 @addtogroup performance_schema_tables
237 @{
238*/
239
240/** Generic index for error_log table. Used by cursor class for open index. */
242 public:
244
245 ~PFS_index_error_log() override = default;
246
247 virtual bool match(log_sink_pfs_event *row) = 0;
248};
249
250/** Cursor CURSOR_BY_ERROR_LOG for error_log table. */
252 public:
253 static ha_rows get_row_count();
254
255 void reset_position() override;
256
257 int rnd_next() override;
258 int rnd_pos(const void *pos) override;
259
260 int index_next() override;
261
262 protected:
263 explicit cursor_by_error_log(const PFS_engine_table_share *share);
264
265 public:
266 ~cursor_by_error_log() override = default;
267
268 protected:
269 virtual int make_row(log_sink_pfs_event *row) = 0;
270
271 private:
272 /** Current position. */
274 /** Next position. */
276
277 protected:
279};
280
281/** @} */
282#endif
Definition: pfs_engine_table.h:299
Definition: pfs_engine_table.h:267
An abstract PERFORMANCE_SCHEMA table.
Definition: pfs_engine_table.h:69
Generic index for error_log table.
Definition: cursor_by_error_log.h:241
virtual bool match(log_sink_pfs_event *row)=0
PFS_index_error_log(PFS_engine_key *key)
Definition: cursor_by_error_log.h:243
~PFS_index_error_log() override=default
Index in the error-log ring-buffer.
Definition: cursor_by_error_log.h:49
void set_after(const PFS_ringbuffer_index *other)
Set our index to the element after the given one (if that is valid; otherwise, we cannot determine a ...
Definition: cursor_by_error_log.h:109
ulonglong m_timestamp
Time-stamp we copied from the event we point to when setting this index.
Definition: cursor_by_error_log.h:72
void reset()
Reset index.
Definition: cursor_by_error_log.h:78
PFS_ringbuffer_index()
Constructor.
Definition: cursor_by_error_log.h:87
int m_index
Numeric row index.
Definition: cursor_by_error_log.h:54
void set_at(const PFS_ringbuffer_index *other)
Set this index to a given position.
Definition: cursor_by_error_log.h:95
log_sink_pfs_event * m_event
Pointer to an event in the ring-buffer.
Definition: cursor_by_error_log.h:61
log_sink_pfs_event * get_event()
Get event if it's still valid.
Definition: cursor_by_error_log.h:156
log_sink_pfs_event * scan_next()
Return current record (if valid), then set index to the next record.
Definition: cursor_by_error_log.h:206
Cursor CURSOR_BY_ERROR_LOG for error_log table.
Definition: cursor_by_error_log.h:251
pos_t m_pos
Current position.
Definition: cursor_by_error_log.h:273
int rnd_pos(const void *pos) override
Random pos.
Definition: cursor_by_error_log.cc:103
static ha_rows get_row_count()
Get row-count (by getting the number of events in the ring-buffer)
Definition: cursor_by_error_log.cc:41
virtual int make_row(log_sink_pfs_event *row)=0
~cursor_by_error_log() override=default
void reset_position() override
Reset cursor position.
Definition: cursor_by_error_log.cc:61
int rnd_next() override
Read next row (from ring-buffer into table).
Definition: cursor_by_error_log.cc:74
pos_t m_next_pos
Next position.
Definition: cursor_by_error_log.h:275
cursor_by_error_log(const PFS_engine_table_share *share)
Definition: cursor_by_error_log.cc:37
int index_next() override
Go to next entry in index and retrieve the matching error log event.
Definition: cursor_by_error_log.cc:129
PFS_index_error_log * m_opened_index
Definition: cursor_by_error_log.h:278
PFS_ringbuffer_index pos_t
Definition: cursor_by_error_log.h:233
log_sink_pfs_event * log_sink_pfs_event_first()
Get oldest event still in ring-buffer.
Definition: log_sink_perfschema.cc:159
log_sink_pfs_event * log_sink_pfs_event_valid(log_sink_pfs_event *e, ulonglong logged)
Use timestamp to check whether a given event-pointer still points to a valid event in the ring-buffer...
Definition: log_sink_perfschema.cc:234
log_sink_pfs_event * log_sink_pfs_event_next(log_sink_pfs_event *e)
Get event following the supplied one.
Definition: log_sink_perfschema.cc:183
my_off_t ha_rows
Definition: my_base.h:1139
unsigned long long int ulonglong
Definition: my_inttypes.h:55
Performance schema tables (declarations).
Performance schema instruments (declarations).
required string key
Definition: replication_asynchronous_connection_failover.proto:59
This file contains.
A PERFORMANCE_SCHEMA table share.
Definition: pfs_engine_table.h:357
Definition: log_sink_perfschema.h:58
ulonglong m_timestamp
Column ERROR_LOG_TIMESTAMP.
Definition: log_sink_perfschema.h:60
Helpers to implement a performance schema table.