MySQL 9.0.0
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 * Register the connection error or success to a given destination.
77 *
78 * If registering a success it will set the number of reported errors to a
79 * given connection to 0.
80 *
81 * If registering a failure it will increment the number of reported failed
82 * connections to the destination. If the number reached the
83 * quarantine_threshold the destination will be added to the quarantine. If
84 * the destination candidate is not quarantine yet it will starting the async
85 * handler for it, otherwise it will just update the referencing plugins list.
86 *
87 * @param[in] dest Reported destination address.
88 * @param[in] success Indicates if the reported connection result is success
89 * of failure.
90 *
91 * @returns true if the destination got added to the quarantine, false
92 * otherwise
93 */
95 bool success);
96
97 /**
98 * Remove unreachable destination candidate from quarantine.
99 *
100 * @param[in] dest Unreachable destination candidate address.
101 */
103 const mysql_harness::TCPAddress &dest);
104
105 /**
106 * Query the quarantined destination candidates set and check if the given
107 * destination candidate is quarantined.
108 *
109 * @param[in] dest Destination candidate address.
110 * @returns true if the destination candidate is quarantined, false otherwise.
111 */
113
114 /**
115 * Refresh the quarantined destination candidates list on metadata refresh.
116 *
117 * 1) if the destination candidates list got updated we have to go through the
118 * quarantined destinations and check if there are still routing plugins that
119 * references them.
120 * 2) for each destination returned in the metadata (which is available from
121 * the md perspective) check if it is still unreachable and should be
122 * quarantined.
123 *
124 * @param[in] instance_name Routing plugin instance name.
125 * @param[in] nodes_changed_on_md_refresh Information if the destination
126 * candidates have been updated for the given routing plugin.
127 * @param[in] available_destinations List of destination candidates that are
128 * available for the given routing plugin after metadata refresh.
129 */
131 const std::string &instance_name, const bool nodes_changed_on_md_refresh,
132 const std::vector<AvailableDestination> &available_destinations);
133
134 /**
135 * Stop all async operations and clear the quarantine list.
136 */
137 void stop_quarantine();
138
139 private:
140 /**
141 * Async handler responsible of periodic checks for destination candidate
142 * availability.
143 *
144 * @param[in] ec Result of async operation.
145 * @param[in] dest Destination candidate address.
146 */
147 void quarantine_handler(const std::error_code &ec,
148 const mysql_harness::TCPAddress &dest);
149
151 const mysql_harness::TCPAddress &dest);
152
153 /**
154 * Go through all routing instances and check if there are routing plugins
155 * which have all destination candidates added to quarantine, if so lets
156 * close the listening socket of such routing instances.
157 */
159
160 /**
161 * For a given destination get names of all routing instances that references
162 * it.
163 *
164 * @param[in] destination Destination candidate address.
165 * @returns List of referencing routing instance names
166 */
167 std::vector<std::string> get_referencing_routing_instances(
168 const mysql_harness::TCPAddress &destination);
169
170 /**
171 * On metadata refresh we got a destination candidates list that is reported
172 * to be available (from the metadata perspective). Go through this list and
173 * check if any of the destination candidate is quarantined, if so verify
174 * if it is still unreachable and should be kept in quarantine.
175 *
176 * @param[in] destination_list Destination candidates reported to be
177 * available.
178 */
179 void update_destinations_state(const AllowedNodes &destination_list);
180
181 /**
182 * If destination list of a routing instance has changed it is possible that
183 * some destinations are no longer referenced by any routing instance. In
184 * that case we should scan the quarantine list and remove those destinations.
185 *
186 * @param[in] instance_name Routing instance name that got destination
187 * candidates list update.
188 * @param[in] routing_new_destinations List of new destination candidates for
189 * the given routing instance.
190 */
191 void drop_stray_destinations(const std::string &instance_name,
192 const AllowedNodes &routing_new_destinations);
193
194 /**
195 * Class representing a single entry (destination) in quarantined destination
196 * set.
197 *
198 * Each destination has its own timer responsible for doing asynchronous
199 * availability checks and a list of names of routing instances that currently
200 * reference this destination candidate.
201 */
204 net::io_context *io_ctx, const mysql_harness::TCPAddress &addr,
205 std::vector<std::string> referencing_instances,
206 std::chrono::seconds quarantine_interval,
207 std::function<void()> on_delete, std::function<void()> on_connect_ok)
208 : io_ctx_{io_ctx},
209 address_{addr},
210 referencing_routing_instances_{std::move(referencing_instances)},
211 quarantine_interval_{quarantine_interval},
212 timer_{*io_ctx},
213 on_delete_{on_delete},
214 on_connect_ok_{on_connect_ok} {}
215
217
219 default;
222
224 const Unreachable_destination_candidate &) = delete;
226 const Unreachable_destination_candidate &) = delete;
227
229
237
240 std::vector<std::string> referencing_routing_instances_;
243
245
250
252 bool connected_{false};
253
254 enum class Function {
257 };
258
260
261 std::error_code last_ec_{
262 make_error_code(std::errc::no_such_file_or_directory)};
263
264 std::function<void()> on_delete_;
265 std::function<void()> on_connect_ok_;
266 };
267
268 std::chrono::milliseconds kQuarantinedConnectTimeout{1000};
273 std::vector<std::shared_ptr<Unreachable_destination_candidate>>
275 std::map<mysql_harness::TCPAddress, uint32_t> destination_errors_;
279 std::vector<std::string> routing_instances_;
280 std::atomic<bool> stopped_{false};
281
282 /** number of quarantined destinations */
283 std::atomic<size_t> quarantined_dest_counter_{0};
284 std::condition_variable quarantine_empty_cond_;
286
288};
289
290#endif // MYSQLROUTER_UNREACHABLE_DESTINATIONS_QUARANTINE_INCLUDED
static IoComponent & get_instance()
Definition: io_component.cc:146
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:275
QuarantineRoutingCallbacks routing_callbacks_
Definition: unreachable_destinations_quarantine.h:287
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:191
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:281
void add_destination_candidate_to_quarantine(const mysql_harness::TCPAddress &dest)
Definition: unreachable_destinations_quarantine.cc:76
std::atomic< bool > stopped_
Definition: unreachable_destinations_quarantine.h:280
void register_route(const std::string &route_name)
Definition: unreachable_destinations_quarantine.cc:44
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:313
std::chrono::seconds quarantine_interval_
Definition: unreachable_destinations_quarantine.h:269
void remove_destination_candidate_from_quarantine(const mysql_harness::TCPAddress &dest)
Remove unreachable destination candidate from quarantine.
Definition: unreachable_destinations_quarantine.cc:119
uint32_t quarantine_threshold_
Definition: unreachable_destinations_quarantine.h:270
void init(std::chrono::seconds quarantine_interval, uint32_t qurantine_threshold)
Initialize the unreachable destination candidate mechanism.
Definition: unreachable_destinations_quarantine.cc:50
net::io_context & io_ctx_
Definition: unreachable_destinations_quarantine.h:271
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:147
std::atomic< size_t > quarantined_dest_counter_
number of quarantined destinations
Definition: unreachable_destinations_quarantine.h:283
std::condition_variable quarantine_empty_cond_
Definition: unreachable_destinations_quarantine.h:284
std::vector< std::shared_ptr< Unreachable_destination_candidate > > quarantined_destination_candidates_
Definition: unreachable_destinations_quarantine.h:274
std::mutex destination_errors_mutex_
Definition: unreachable_destinations_quarantine.h:276
void stop_quarantine()
Stop all async operations and clear the quarantine list.
Definition: unreachable_destinations_quarantine.cc:167
std::mutex quarantine_mutex_
Definition: unreachable_destinations_quarantine.h:272
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:266
std::vector< std::string > routing_instances_
Definition: unreachable_destinations_quarantine.h:279
void unregister_routing_callbacks()
Definition: unreachable_destinations_quarantine.cc:39
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:157
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:297
std::mutex unreachable_destinations_init_mutex_
Definition: unreachable_destinations_quarantine.h:277
std::mutex quarantine_empty_cond_m_
Definition: unreachable_destinations_quarantine.h:285
std::mutex routing_instances_mutex_
Definition: unreachable_destinations_quarantine.h:278
void register_routing_callbacks(QuarantineRoutingCallbacks &&routing_callbacks)
Definition: unreachable_destinations_quarantine.cc:33
std::chrono::milliseconds kQuarantinedConnectTimeout
Definition: unreachable_destinations_quarantine.h:268
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:56
Defines an IP address with port number
Definition: tcp_address.h:40
Definition: socket.h:1090
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:284
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:202
bool connect_timed_out_
Definition: unreachable_destinations_quarantine.h:251
std::vector< std::string > referencing_routing_instances_
Definition: unreachable_destinations_quarantine.h:240
bool connected_
Definition: unreachable_destinations_quarantine.h:252
net::io_context * io_ctx_
Definition: unreachable_destinations_quarantine.h:238
Function
Definition: unreachable_destinations_quarantine.h:254
net::ip::tcp::resolver::results_type endpoints_
Definition: unreachable_destinations_quarantine.h:246
stdx::expected< void, std::error_code > connected()
Definition: unreachable_destinations_quarantine.cc:498
net::steady_timer timer_
Definition: unreachable_destinations_quarantine.h:242
std::function< void()> on_delete_
Definition: unreachable_destinations_quarantine.h:264
Unreachable_destination_candidate & operator=(const Unreachable_destination_candidate &)=delete
std::error_code last_ec_
Definition: unreachable_destinations_quarantine.h:261
server_protocol_type::socket server_sock_
Definition: unreachable_destinations_quarantine.h:248
net::ip::tcp::resolver::results_type::iterator endpoints_it_
Definition: unreachable_destinations_quarantine.h:247
Unreachable_destination_candidate(const Unreachable_destination_candidate &)=delete
Function func_
Definition: unreachable_destinations_quarantine.h:259
stdx::expected< void, std::error_code > connect_finish()
Definition: unreachable_destinations_quarantine.cc:464
server_protocol_type::endpoint server_endpoint_
Definition: unreachable_destinations_quarantine.h:249
stdx::expected< void, std::error_code > resolve()
Definition: unreachable_destinations_quarantine.cc:386
stdx::expected< void, std::error_code > connect()
Definition: unreachable_destinations_quarantine.cc:363
stdx::expected< void, std::error_code > connect_init()
Definition: unreachable_destinations_quarantine.cc:408
stdx::expected< void, std::error_code > try_connect()
Definition: unreachable_destinations_quarantine.cc:419
Unreachable_destination_candidate & operator=(Unreachable_destination_candidate &&)=default
std::chrono::seconds quarantine_interval_
Definition: unreachable_destinations_quarantine.h:241
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:203
std::function< void()> on_connect_ok_
Definition: unreachable_destinations_quarantine.h:265
stdx::expected< void, std::error_code > init_endpoint()
Definition: unreachable_destinations_quarantine.cc:401
stdx::expected< void, std::error_code > next_endpoint()
Definition: unreachable_destinations_quarantine.cc:453
~Unreachable_destination_candidate()
Definition: unreachable_destinations_quarantine.cc:354
mysql_harness::TCPAddress address_
Definition: unreachable_destinations_quarantine.h:239
double seconds()
Definition: task.cc:310