/src/mysql-server/sql/rpl_reporting.h
Line | Count | Source |
1 | | /* Copyright (c) 2006, 2025, 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 | | #ifndef RPL_REPORTING_H |
25 | | #define RPL_REPORTING_H |
26 | | |
27 | | #include <stdarg.h> |
28 | | #include <stdio.h> |
29 | | #include <sys/types.h> |
30 | | #include <time.h> |
31 | | |
32 | | #include "my_compiler.h" |
33 | | #include "my_inttypes.h" |
34 | | #include "my_systime.h" //my_getsystime |
35 | | #include "mysql/components/services/bits/mysql_mutex_bits.h" |
36 | | #include "mysql/my_loglevel.h" |
37 | | #include "mysql/psi/mysql_mutex.h" |
38 | | |
39 | | /** |
40 | | Maximum size of an error message from a slave thread. |
41 | | */ |
42 | | #define MAX_SLAVE_ERRMSG 1024 |
43 | | |
44 | | class THD; |
45 | | struct Gtid_specification; |
46 | | |
47 | | /** |
48 | | Mix-in to handle the message logging and reporting for relay log |
49 | | info and master log info structures. |
50 | | |
51 | | By inheriting from this class, the class is imbued with |
52 | | capabilities to do slave reporting. |
53 | | */ |
54 | | class Slave_reporting_capability { |
55 | | public: |
56 | | /** lock used to synchronize m_last_error on 'SHOW REPLICA STATUS' **/ |
57 | | mutable mysql_mutex_t err_lock; |
58 | | /** |
59 | | Constructor. |
60 | | |
61 | | @param thread_name Printable name of the slave thread that is reporting. |
62 | | */ |
63 | | Slave_reporting_capability(char const *thread_name); |
64 | | |
65 | | /** |
66 | | Writes a message and, if it's an error message, to Last_Error |
67 | | (which will be displayed by SHOW REPLICA STATUS). |
68 | | |
69 | | @param level The severity level |
70 | | @param err_code The error code |
71 | | @param msg The message (usually related to the error |
72 | | code, but can contain more information), in |
73 | | printf() format. |
74 | | */ |
75 | | virtual void report(loglevel level, int err_code, const char *msg, ...) const |
76 | | MY_ATTRIBUTE((format(printf, 4, 5))); |
77 | | |
78 | | virtual void report(loglevel level, int err_code, |
79 | | const Gtid_specification *gtid_next, const char *msg, |
80 | | ...) const MY_ATTRIBUTE((format(printf, 5, 6))); |
81 | | |
82 | | void va_report(loglevel level, int err_code, const char *prefix_msg, |
83 | | const char *msg, va_list v_args) const |
84 | | MY_ATTRIBUTE((format(printf, 5, 0))); |
85 | | |
86 | | /** |
87 | | Clear errors. They will not show up under <code>SHOW REPLICA |
88 | | STATUS</code>. |
89 | | */ |
90 | 0 | void clear_error() { |
91 | 0 | mysql_mutex_lock(&err_lock); |
92 | 0 | m_last_error.clear(); |
93 | 0 | mysql_mutex_unlock(&err_lock); |
94 | 0 | } |
95 | | |
96 | | /** |
97 | | Check if the current error is of temporary nature or not. |
98 | | */ |
99 | | int has_temporary_error(THD *thd, uint error_arg = 0, |
100 | | bool *silent = nullptr) const; |
101 | | |
102 | | /** |
103 | | Error information structure. |
104 | | */ |
105 | | class Error { |
106 | | friend class Slave_reporting_capability; |
107 | | |
108 | | public: |
109 | 0 | Error() { clear(); } |
110 | | |
111 | 0 | void clear() { |
112 | 0 | number = 0; |
113 | 0 | message[0] = '\0'; |
114 | 0 | timestamp[0] = '\0'; |
115 | 0 | } |
116 | | |
117 | 0 | void update_timestamp() { |
118 | 0 | struct tm tm_tmp; |
119 | 0 | struct tm *start; |
120 | 0 | time_t tt_tmp; |
121 | 0 |
|
122 | 0 | skr = my_getsystime() / 10; |
123 | 0 | tt_tmp = skr / 1000000; |
124 | 0 | localtime_r(&tt_tmp, &tm_tmp); |
125 | 0 | start = &tm_tmp; |
126 | 0 |
|
127 | 0 | snprintf(timestamp, sizeof(timestamp), "%02d%02d%02d %02d:%02d:%02d", |
128 | 0 | start->tm_year % 100, start->tm_mon + 1, start->tm_mday, |
129 | 0 | start->tm_hour, start->tm_min, start->tm_sec); |
130 | 0 | timestamp[15] = '\0'; |
131 | 0 | } |
132 | | |
133 | | /** Error code */ |
134 | | uint32 number; |
135 | | /** Error message */ |
136 | | char message[MAX_SLAVE_ERRMSG]; |
137 | | /** Error timestamp as string */ |
138 | | char timestamp[64]; |
139 | | /** Error timestamp in microseconds. Used in performance_schema */ |
140 | | ulonglong skr; |
141 | | }; |
142 | | |
143 | 0 | Error const &last_error() const { return m_last_error; } |
144 | 0 | bool is_error() const { return last_error().number != 0; } |
145 | | |
146 | | /* |
147 | | For MSR, there is a need to introduce error messages per channel. |
148 | | Instead of changing the error messages in share/messages_to_error_log.txt |
149 | | to introduce the clause, FOR CHANNEL "%s", we construct a string like this. |
150 | | There might be problem with a client applications which could print |
151 | | error messages and see no %s. |
152 | | @TODO: fix this. |
153 | | */ |
154 | | virtual const char *get_for_channel_str(bool upper_case) const = 0; |
155 | | |
156 | | virtual ~Slave_reporting_capability() = 0; |
157 | | |
158 | | protected: |
159 | | virtual void do_report(loglevel level, int err_code, const char *msg, |
160 | | va_list v_args) const |
161 | | MY_ATTRIBUTE((format(printf, 4, 0))); |
162 | | |
163 | | virtual void do_report(loglevel level, int err_code, |
164 | | const Gtid_specification *gtid_next, const char *msg, |
165 | | va_list v_args) const |
166 | | MY_ATTRIBUTE((format(printf, 5, 0))); |
167 | | |
168 | | /** |
169 | | Last error produced by the I/O or SQL thread respectively. |
170 | | */ |
171 | | mutable Error m_last_error; |
172 | | |
173 | | private: |
174 | | char const *const m_thread_name; |
175 | | |
176 | | // not implemented |
177 | | Slave_reporting_capability(const Slave_reporting_capability &rhs); |
178 | | Slave_reporting_capability &operator=(const Slave_reporting_capability &rhs); |
179 | | }; |
180 | | |
181 | | inline void Slave_reporting_capability::do_report(loglevel level, int err_code, |
182 | | const char *msg, |
183 | 0 | va_list v_args) const { |
184 | 0 | va_report(level, err_code, nullptr, msg, v_args); |
185 | 0 | } |
186 | | |
187 | | inline void Slave_reporting_capability::do_report(loglevel level, int err_code, |
188 | | const Gtid_specification *, |
189 | | const char *msg, |
190 | 0 | va_list v_args) const { |
191 | 0 | va_report(level, err_code, nullptr, msg, v_args); |
192 | 0 | } |
193 | | |
194 | | #endif // RPL_REPORTING_H |