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