MySQL 8.0.37
Source Code Documentation
unreachable_destinations_quarantine.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2021, 2024, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef MYSQLROUTER_UNREACHABLE_DESTINATIONS_QUARANTINE_INCLUDED
27#define MYSQLROUTER_UNREACHABLE_DESTINATIONS_QUARANTINE_INCLUDED
28
29#include <chrono>
30#include <map>
31#include <mutex>
32#include <vector>
33
39
40/**
41 * Information about unreachable destination candidates that is shared between
42 * plugin instances.
43 *
44 * Quarantined destinations will not be used for
45 * routing purposes. Each unreachable destination candidate is periodically
46 * probed for availability and removed from the unreachable destination
47 * candidate set if it became available.
48 */
50 public:
51 /**
52 * Initialize the unreachable destination candidate mechanism.
53 *
54 * It will set up:
55 * - routing plugin instances callbacks used for probing/updating the
56 * unreachable destinations
57 * - harness context variable used for starting/stopping the routing listening
58 * sockets
59 * - quarantine_refresh_interval Used for unreachable destination candidates
60 * availability checks.
61 * @param[in] quarantine_interval The interval in seconds used for checking
62 * the health (connectivity) of the quarantined destinations.
63 * @param[in] qurantine_threshold Number of consecutive reported failed
64 * connections to the destination until it gets quarantined.
65 */
66 void init(std::chrono::seconds quarantine_interval,
67 uint32_t qurantine_threshold);
68
70 QuarantineRoutingCallbacks &&routing_callbacks);
72
73 void register_route(const std::string &route_name);
74
75 /**
76 * @brief
77 *
78 * Register the connection error or success to a given destination.
79 *
80 * If registering a success it will set the number of reported errors to a
81 * given connection to 0.
82 *
83 * If registering a failure it will increment the number of reported failed
84 * connections to the destination. If the number reached the
85 * quarantine_threshold the destination will be added to the quarantine. If
86 * the destination candidate is not quarantine yet it will starting the async
87 * handler for it, otherwise it will just update the referencing plugins list.
88 *
89 * @param[in] dest Reported destination address.
90 * @param[in] success Indicates if the reported connection result is success
91 * of failure.
92 *
93 * @returns true if the destination got added to the quarantine, false
94 * otherwise
95 */
97 bool success);
98
99 /**
100 * Remove unreachable destination candidate from quarantine.
101 *
102 * @param[in] dest Unreachable destination candidate address.
103 */
105 const mysql_harness::TCPAddress &dest);
106
107 /**
108 * Query the quarantined destination candidates set and check if the given
109 * destination candidate is quarantined.
110 *
111 * @param[in] dest Destination candidate address.
112 * @returns true if the destination candidate is quarantined, false otherwise.
113 */
115
116 /**
117 * Refresh the quarantined destination candidates list on metadata refresh.
118 *
119 * 1) if the destination candidates list got updated we have to go through the
120 * quarantined destinations and check if there are still routing plugins that
121 * references them.
122 * 2) for each destination returned in the metadata (which is available from
123 * the md perspective) check if it is still unreachable and should be
124 * quarantined.
125 *
126 * @param[in] instance_name Routing plugin instance name.
127 * @param[in] nodes_changed_on_md_refresh Information if the destination
128 * candidates have been updated for the given routing plugin.
129 * @param[in] available_destinations List of destination candidates that are
130 * available for the given routing plugin after metadata refresh.
131 */
133 const std::string &instance_name, const bool nodes_changed_on_md_refresh,
134 const std::vector<AvailableDestination> &available_destinations);
135
136 /**
137 * Stop all async operations and clear the quarantine list.
138 */
139 void stop_quarantine();
140
141 private:
142 /**
143 * Async handler responsible of periodic checks for destination candidate
144 * availability.
145 *
146 * @param[in] ec Result of async operation.
147 * @param[in] dest Destination candidate address.
148 */
149 void quarantine_handler(const std::error_code &ec,
150 const mysql_harness::TCPAddress &dest);
151
153 const mysql_harness::TCPAddress &dest);
154
155 /**
156 * Go through all routing instances and check if there are routing plugins
157 * which have all destination candidates added to quarantine, if so lets
158 * close the listening socket of such routing instances.
159 */
161
162 /**
163 * For a given destination get names of all routing instances that references
164 * it.
165 *
166 * @param[in] destination Destination candidate address.
167 * @returns List of referencing routing instance names
168 */
169 std::vector<std::string> get_referencing_routing_instances(
170 const mysql_harness::TCPAddress &destination);
171
172 /**
173 * On metadata refresh we got a destination candidates list that is reported
174 * to be available (from the metadata perspective). Go through this list and
175 * check if any of the destination candidate is quarantined, if so verify
176 * if it is still unreachable and should be kept in quarantine.
177 *
178 * @param[in] destination_list Destination candidates reported to be
179 * available.
180 */
181 void update_destinations_state(const AllowedNodes &destination_list);
182
183 /**
184 * If destination list of a routing instance has changed it is possible that
185 * some destinations are no longer referenced by any routing instance. In
186 * that case we should scan the quarantine list and remove those destinations.
187 *
188 * @param[in] instance_name Routing instance name that got destination
189 * candidates list update.
190 * @param[in] routing_new_destinations List of new destination candidates for
191 * the given routing instance.
192 */
193 void drop_stray_destinations(const std::string &instance_name,
194 const AllowedNodes &routing_new_destinations);
195
196 /**
197 * Class representing a single entry (destination) in quarantined destination
198 * set.
199 *
200 * Each destination has its own timer responsible for doing asynchronous
201 * availability checks and a list of names of routing instances that currently
202 * reference this destination candidate.
203 */
206 net::io_context *io_ctx, const mysql_harness::TCPAddress &addr,
207 std::vector<std::string> referencing_instances,
208 std::chrono::seconds quarantine_interval,
209 std::function<void()> on_delete, std::function<void()> on_connect_ok)
210 : io_ctx_{io_ctx},
211 address_{addr},
212 referencing_routing_instances_{std::move(referencing_instances)},
213 quarantine_interval_{quarantine_interval},
214 timer_{*io_ctx},
215 on_delete_{on_delete},
216 on_connect_ok_{on_connect_ok} {}
217
219
221 default;
224
226 const Unreachable_destination_candidate &) = delete;
228 const Unreachable_destination_candidate &) = delete;
229
231
239
242 std::vector<std::string> referencing_routing_instances_;
245
247
252
254 bool connected_{false};
255
256 enum class Function {
259 };
260
262
263 std::error_code last_ec_{
264 make_error_code(std::errc::no_such_file_or_directory)};
265
266 std::function<void()> on_delete_;
267 std::function<void()> on_connect_ok_;
268 };
269
270 std::chrono::milliseconds kQuarantinedConnectTimeout{1000};
275 std::vector<std::shared_ptr<Unreachable_destination_candidate>>
277 std::map<mysql_harness::TCPAddress, uint32_t> destination_errors_;
281 std::vector<std::string> routing_instances_;
282 std::atomic<bool> stopped_{false};
283
284 /** number of quarantined destinations */
285 std::atomic<size_t> quarantined_dest_counter_{0};
286 std::condition_variable quarantine_empty_cond_;
288
290};
291
292#endif // MYSQLROUTER_UNREACHABLE_DESTINATIONS_QUARANTINE_INCLUDED
static IoComponent & get_instance()
Definition: io_component.cc:147
net::io_context & io_context()
get ref to the io_context.
Definition: io_component.cc:58
Information about unreachable destination candidates that is shared between plugin instances.
Definition: unreachable_destinations_quarantine.h:49
std::map< mysql_harness::TCPAddress, uint32_t > destination_errors_
Definition: unreachable_destinations_quarantine.h:277
QuarantineRoutingCallbacks routing_callbacks_
Definition: unreachable_destinations_quarantine.h:289
void quarantine_handler(const std::error_code &ec, const mysql_harness::TCPAddress &dest)
Async handler responsible of periodic checks for destination candidate availability.
Definition: unreachable_destinations_quarantine.cc:190
std::vector< std::string > get_referencing_routing_instances(const mysql_harness::TCPAddress &destination)
For a given destination get names of all routing instances that references it.
Definition: unreachable_destinations_quarantine.cc:280
void add_destination_candidate_to_quarantine(const mysql_harness::TCPAddress &dest)
Definition: unreachable_destinations_quarantine.cc:75
std::atomic< bool > stopped_
Definition: unreachable_destinations_quarantine.h:282
void register_route(const std::string &route_name)
Definition: unreachable_destinations_quarantine.cc:43
void drop_stray_destinations(const std::string &instance_name, const AllowedNodes &routing_new_destinations)
If destination list of a routing instance has changed it is possible that some destinations are no lo...
Definition: unreachable_destinations_quarantine.cc:312
std::chrono::seconds quarantine_interval_
Definition: unreachable_destinations_quarantine.h:271
void remove_destination_candidate_from_quarantine(const mysql_harness::TCPAddress &dest)
Remove unreachable destination candidate from quarantine.
Definition: unreachable_destinations_quarantine.cc:118
uint32_t quarantine_threshold_
Definition: unreachable_destinations_quarantine.h:272
void init(std::chrono::seconds quarantine_interval, uint32_t qurantine_threshold)
Initialize the unreachable destination candidate mechanism.
Definition: unreachable_destinations_quarantine.cc:49
net::io_context & io_ctx_
Definition: unreachable_destinations_quarantine.h:273
bool is_quarantined(const mysql_harness::TCPAddress &dest)
Query the quarantined destination candidates set and check if the given destination candidate is quar...
Definition: unreachable_destinations_quarantine.cc:146
std::atomic< size_t > quarantined_dest_counter_
number of quarantined destinations
Definition: unreachable_destinations_quarantine.h:285
std::condition_variable quarantine_empty_cond_
Definition: unreachable_destinations_quarantine.h:286
std::vector< std::shared_ptr< Unreachable_destination_candidate > > quarantined_destination_candidates_
Definition: unreachable_destinations_quarantine.h:276
std::mutex destination_errors_mutex_
Definition: unreachable_destinations_quarantine.h:278
void stop_quarantine()
Stop all async operations and clear the quarantine list.
Definition: unreachable_destinations_quarantine.cc:166
std::mutex quarantine_mutex_
Definition: unreachable_destinations_quarantine.h:274
void stop_socket_acceptors_on_all_nodes_quarantined()
Go through all routing instances and check if there are routing plugins which have all destination ca...
Definition: unreachable_destinations_quarantine.cc:265
std::vector< std::string > routing_instances_
Definition: unreachable_destinations_quarantine.h:281
void unregister_routing_callbacks()
Definition: unreachable_destinations_quarantine.cc:38
void refresh_quarantine(const std::string &instance_name, const bool nodes_changed_on_md_refresh, const std::vector< AvailableDestination > &available_destinations)
Refresh the quarantined destination candidates list on metadata refresh.
Definition: unreachable_destinations_quarantine.cc:156
void update_destinations_state(const AllowedNodes &destination_list)
On metadata refresh we got a destination candidates list that is reported to be available (from the m...
Definition: unreachable_destinations_quarantine.cc:296
std::mutex unreachable_destinations_init_mutex_
Definition: unreachable_destinations_quarantine.h:279
std::mutex quarantine_empty_cond_m_
Definition: unreachable_destinations_quarantine.h:287
std::mutex routing_instances_mutex_
Definition: unreachable_destinations_quarantine.h:280
void register_routing_callbacks(QuarantineRoutingCallbacks &&routing_callbacks)
Definition: unreachable_destinations_quarantine.cc:32
std::chrono::milliseconds kQuarantinedConnectTimeout
Definition: unreachable_destinations_quarantine.h:270
bool report_connection_result(const mysql_harness::TCPAddress &dest, bool success)
Register the connection error or success to a given destination.
Definition: unreachable_destinations_quarantine.cc:55
Defines an IP address with port number
Definition: tcp_address.h:40
Definition: socket.h:1144
Definition: timer.h:57
Definition: io_context.h:61
Definition: internet.h:678
Definition: internet.h:542
const_iterator iterator
Definition: internet.h:550
TCP protocol.
Definition: internet.h:1155
Definition: expected.h:944
std::vector< AvailableDestination > AllowedNodes
Definition: destination_status_types.h:59
std::error_code make_error_code(DynamicLoaderErrc ec)
make error_code from a DynamicLoaderErrc.
Definition: dynamic_loader.cc:79
Definition: gcs_xcom_synode.h:64
Definition: destination_status_types.h:34
Class representing a single entry (destination) in quarantined destination set.
Definition: unreachable_destinations_quarantine.h:204
bool connect_timed_out_
Definition: unreachable_destinations_quarantine.h:253
std::vector< std::string > referencing_routing_instances_
Definition: unreachable_destinations_quarantine.h:242
bool connected_
Definition: unreachable_destinations_quarantine.h:254
net::io_context * io_ctx_
Definition: unreachable_destinations_quarantine.h:240
Function
Definition: unreachable_destinations_quarantine.h:256
net::ip::tcp::resolver::results_type endpoints_
Definition: unreachable_destinations_quarantine.h:248
stdx::expected< void, std::error_code > connected()
Definition: unreachable_destinations_quarantine.cc:497
net::steady_timer timer_
Definition: unreachable_destinations_quarantine.h:244
std::function< void()> on_delete_
Definition: unreachable_destinations_quarantine.h:266
Unreachable_destination_candidate & operator=(const Unreachable_destination_candidate &)=delete
std::error_code last_ec_
Definition: unreachable_destinations_quarantine.h:263
server_protocol_type::socket server_sock_
Definition: unreachable_destinations_quarantine.h:250
net::ip::tcp::resolver::results_type::iterator endpoints_it_
Definition: unreachable_destinations_quarantine.h:249
Unreachable_destination_candidate(const Unreachable_destination_candidate &)=delete
Function func_
Definition: unreachable_destinations_quarantine.h:261
stdx::expected< void, std::error_code > connect_finish()
Definition: unreachable_destinations_quarantine.cc:463
server_protocol_type::endpoint server_endpoint_
Definition: unreachable_destinations_quarantine.h:251
stdx::expected< void, std::error_code > resolve()
Definition: unreachable_destinations_quarantine.cc:385
stdx::expected< void, std::error_code > connect()
Definition: unreachable_destinations_quarantine.cc:362
stdx::expected< void, std::error_code > connect_init()
Definition: unreachable_destinations_quarantine.cc:407
stdx::expected< void, std::error_code > try_connect()
Definition: unreachable_destinations_quarantine.cc:418
Unreachable_destination_candidate & operator=(Unreachable_destination_candidate &&)=default
std::chrono::seconds quarantine_interval_
Definition: unreachable_destinations_quarantine.h:243
Unreachable_destination_candidate(Unreachable_destination_candidate &&)=default
Unreachable_destination_candidate(net::io_context *io_ctx, const mysql_harness::TCPAddress &addr, std::vector< std::string > referencing_instances, std::chrono::seconds quarantine_interval, std::function< void()> on_delete, std::function< void()> on_connect_ok)
Definition: unreachable_destinations_quarantine.h:205
std::function< void()> on_connect_ok_
Definition: unreachable_destinations_quarantine.h:267
stdx::expected< void, std::error_code > init_endpoint()
Definition: unreachable_destinations_quarantine.cc:400
stdx::expected< void, std::error_code > next_endpoint()
Definition: unreachable_destinations_quarantine.cc:452
~Unreachable_destination_candidate()
Definition: unreachable_destinations_quarantine.cc:353
mysql_harness::TCPAddress address_
Definition: unreachable_destinations_quarantine.h:241
double seconds()
Definition: task.cc:310