MySQL 9.0.0
Source Code Documentation
metadata_cache.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2016, 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 METADATA_CACHE_METADATA_CACHE_INCLUDED
27#define METADATA_CACHE_METADATA_CACHE_INCLUDED
28
30
31#include <algorithm>
32#include <atomic>
33#include <chrono>
34#include <ctime>
35#include <future>
36#include <memory>
37#include <mutex>
38#include <set>
39#include <string>
40#include <thread>
41
45#include "mysql_router_thread.h"
48
49class ClusterMetadata;
50
51/** @class MetadataCache
52 *
53 * The MetadataCache manages cached information fetched from the
54 * MySQL Server.
55 *
56 */
59 public:
60 /**
61 * Initialize a connection to the MySQL Metadata server.
62 *
63 * @param router_id id of the router in the cluster metadata
64 * @param clusterset_id UUID of the ClusterSet the Cluster belongs to (if
65 * bootstrapped as a ClusterSet, empty otherwise)
66 * @param metadata_servers The servers that store the metadata
67 * @param cluster_metadata metadata of the cluster
68 * @param ttl_config metadata TTL configuration
69 * @param ssl_options SSL related options for connection
70 * @param target_cluster object identifying the Cluster this operation refers
71 * to
72 * @param router_attributes Router attributes to be registered in the metadata
73 * @param thread_stack_size The maximum memory allocated for thread's stack
74 * @param use_cluster_notifications Flag indicating if the metadata cache
75 * should use GR notifications as an additional trigger for metadata refresh
76 */
78 const unsigned router_id, const std::string &clusterset_id,
79 const std::vector<mysql_harness::TCPAddress> &metadata_servers,
80 std::shared_ptr<MetaData> cluster_metadata,
82 const mysqlrouter::SSLOptions &ssl_options,
83 const mysqlrouter::TargetCluster &target_cluster,
84 const metadata_cache::RouterAttributes &router_attributes,
85 size_t thread_stack_size = mysql_harness::kDefaultStackSizeInKiloBytes,
86 bool use_cluster_notifications = false);
87
88 ~MetadataCache() override;
89
90 /** @brief Starts the Metadata Cache
91 *
92 * Starts the Metadata Cache and launch thread.
93 */
94 void start();
95
96 /** @brief Stops the Metadata Cache
97 *
98 * Stops the Metadata Cache and the launch thread.
99 */
100 void stop() noexcept;
101
102 /** @brief Returns list of managed servers in a cluster
103 *
104 *
105 * @return std::vector containing ManagedInstance objects
106 */
107 metadata_cache::cluster_nodes_list_t get_cluster_nodes();
108
109 /** @brief Returns object containing current Cluster Topology
110 */
111 metadata_cache::ClusterTopology get_cluster_topology();
112
113 /** Wait until cluster PRIMARY changes.
114 *
115 * wait until a change of the PRIMARY is noticed
116 *
117 * leave early if
118 *
119 * - 'timeout' expires
120 * - process shutdown is requested
121 *
122 * function has to handle two scenarios:
123 *
124 * connection to PRIMARY fails because:
125 *
126 * 1. PRIMARY died and group relects a new member
127 * 2. network to PRIMARY lost, but GR sees no fault and PRIMARY does not
128 * change.
129 *
130 * Therefore, if the connection to PRIMARY fails, wait for change of the
131 * membership or timeout, whatever happens earlier.
132 *
133 * @param server_uuid server-uuid of the PRIMARY that we failed to connect
134 * @param timeout - amount of time to wait for a failover
135 * @return true if a primary member exists
136 */
137 bool wait_primary_failover(const std::string &server_uuid,
139
140 /** @brief refresh cluster information */
141 void refresh_thread();
142
143 /** @brief run refresh thread */
144 static void *run_thread(void *context);
145
146 /**
147 * @brief Register observer that is notified when there is a change in the
148 * cluster nodes setup/state discovered.
149 *
150 * @param listener Observer object that is notified when cluster nodes
151 * state is changed.
152 */
155
156 /**
157 * @brief Unregister observer previously registered with add_state_listener()
158 *
159 * @param listener Observer object that should be unregistered.
160 */
163
164 /**
165 * @brief Register observer that is notified when the state of listening
166 * socket acceptors should be updated on the next metadata refresh.
167 *
168 * @param listener Observer object that is notified when replicaset nodes
169 * state is changed.
170 */
171 void add_acceptor_handler_listener(
173
174 /**
175 * @brief Unregister observer previously registered with
176 * add_acceptor_handler_listener()
177 *
178 * @param listener Observer object that should be unregistered.
179 */
180 void remove_acceptor_handler_listener(
182
183 /**
184 * @brief Register observer that is notified on each metadata refresh event.
185 *
186 * @param listener Observer object that is notified on md refresh.
187 */
188 void add_md_refresh_listener(
190
191 /**
192 * @brief Unregister observer previously registered with
193 * add_md_refresh_listener()
194 *
195 * @param listener Observer object that should be unregistered.
196 */
197 void remove_md_refresh_listener(
199
201 return stats_([](auto const &stats)
203 return {stats.refresh_failed,
204 stats.refresh_succeeded,
205 stats.last_refresh_succeeded,
206 stats.last_refresh_failed,
207 stats.last_metadata_server_host,
208 stats.last_metadata_server_port};
209 });
210 }
211
212 std::chrono::milliseconds ttl() const { return ttl_config_.ttl; }
213 mysqlrouter::TargetCluster target_cluster() const { return target_cluster_; }
214
215 virtual mysqlrouter::ClusterType cluster_type() const noexcept = 0;
216
217 std::vector<mysql_harness::TCPAddress> metadata_servers();
218
219 void enable_fetch_auth_metadata() { auth_metadata_fetch_enabled_ = true; }
220
221 void force_cache_update() { on_refresh_requested(); }
222
223 void check_auth_metadata_timers() const;
224
225 std::pair<bool, MetaData::auth_credentials_t::mapped_type>
226 get_rest_user_auth_data(const std::string &user);
227
228 /**
229 * Toggle socket acceptors state update on next metadata refresh.
230 */
232 trigger_acceptor_update_on_next_refresh_ = true;
233 }
234
235 bool fetch_whole_topology() const { return fetch_whole_topology_; }
236
237 void fetch_whole_topology(bool val);
238
239 protected:
240 /** @brief Refreshes the cache
241 *
242 */
243 virtual bool refresh(bool needs_writable_node) = 0;
244
245 void on_refresh_failed(bool terminated, bool md_servers_reachable = false);
246 void on_refresh_succeeded(
247 const metadata_cache::metadata_server_t &metadata_server);
248
249 // Called each time the metadata has changed and we need to notify
250 // the subscribed observers
251 void on_instances_changed(
252 const bool md_servers_reachable,
253 const metadata_cache::ClusterTopology &cluster_topology,
254 uint64_t view_id = 0);
255
256 /**
257 * Called when the listening sockets acceptors state should be updated but
258 * replicaset instances has not changed (in that case socket acceptors would
259 * be handled when calling on_instances_changed).
260 */
261 void on_handle_sockets_acceptors();
262
263 /**
264 * Called on each metadata refresh.
265 *
266 * @param[in] cluster_nodes_changed Information whether there was a change
267 * in instances reported by metadata refresh.
268 * @param[in] cluster_topology current cluster topology
269 */
270 void on_md_refresh(const bool cluster_nodes_changed,
271 const metadata_cache::ClusterTopology &cluster_topology);
272
273 // Called each time we were requested to refresh the metadata
274 void on_refresh_requested();
275
276 // Called each time the metadata refresh completed execution
277 void on_refresh_completed();
278
279 // Update rest users authentication data
280 bool update_auth_cache();
281
282 // Update current Router attributes in the metadata
283 void update_router_attributes();
284
285 // Update Router last_check_in timestamp in the metadata
286 void update_router_last_check_in();
287
288 // Stores the current cluster state and topology.
290
291 // identifies the Cluster we work with
293
294 // Id of the ClusterSet in case of the ClusterSet setup
295 const std::string clusterset_id_;
296
297 // The list of servers that contain the metadata about the managed
298 // topology.
300
301 // Metadata TTL configuration.
303
304 // SSL options for MySQL connections
306
307 // id of the Router in the cluster metadata
308 unsigned router_id_;
309
311 // Authentication data for the rest users
313
314 std::chrono::system_clock::time_point last_credentials_update_;
315 };
316
317 Monitor<RestAuthData> rest_auth_{{}};
318
319 // Authentication data should be fetched only when metadata_cache is used as
320 // an authentication backend
321 bool auth_metadata_fetch_enabled_{false};
322
323 // Stores the pointer to the transport layer implementation. The transport
324 // layer communicates with the servers storing the metadata and fetches the
325 // topology information.
326 std::shared_ptr<MetaData> meta_data_;
327
328 /** @brief refresh thread facade */
330
331 /** @brief notification thread facade */
333
334 // This mutex is used to ensure that a lookup of the metadata is consistent
335 // with the changes in the metadata due to a cache refresh.
337
338 // This mutex ensures that a refresh of the servers that contain the metadata
339 // is consistent with the use of the server list.
341
342 // Flag used to terminate the refresh thread.
343 std::atomic<bool> terminated_{false};
344
345 bool refresh_requested_{false};
346
348
349 std::condition_variable refresh_wait_;
351
352 std::condition_variable refresh_completed_;
354
358
359 std::set<metadata_cache::ClusterStateListenerInterface *> state_listeners_;
360 std::set<metadata_cache::AcceptorUpdateHandlerInterface *>
362 std::set<metadata_cache::MetadataRefreshListenerInterface *>
364
365 struct Stats {
366 std::chrono::system_clock::time_point last_refresh_failed;
367 std::chrono::system_clock::time_point last_refresh_succeeded;
368 uint64_t refresh_failed{0};
369 uint64_t refresh_succeeded{0};
370
373 };
374
375 Monitor<Stats> stats_{{}};
376
377 bool initial_attributes_update_done_{false};
378 uint32_t periodic_stats_update_counter_{1};
379 std::chrono::steady_clock::time_point last_periodic_stats_update_timestamp_{
380 std::chrono::steady_clock::now()};
381
382 bool ready_announced_{false};
383 std::atomic<bool> fetch_whole_topology_{false};
384
385 /**
386 * Flag indicating if socket acceptors state should be updated on next
387 * metadata refresh even if instance information has not changed.
388 */
389 std::atomic<bool> trigger_acceptor_update_on_next_refresh_{false};
390
392
393 bool needs_initial_attributes_update();
394 bool needs_last_check_in_update();
395};
396
398
399/** Gets user readable information string about the nodes attributes
400 * related to _hidden and _disconnect_existing_sessions_when_hidden tags.
401 */
402std::string get_hidden_info(const metadata_cache::ManagedInstance &instance);
403
404namespace metadata_cache {
405
410
411} // namespace metadata_cache
412
413#endif // METADATA_CACHE_METADATA_CACHE_INCLUDED
The ClusterMetadata class encapsulates a connection to the Metadata server.
Definition: cluster_metadata.h:65
std::map< std::string, std::pair< std::string, JsonDocument > > auth_credentials_t
Definition: metadata.h:57
The MetadataCache manages cached information fetched from the MySQL Server.
Definition: metadata_cache.h:58
metadata_cache::MetadataCacheTTLConfig ttl_config_
Definition: metadata_cache.h:302
const std::string clusterset_id_
Definition: metadata_cache.h:295
bool fetch_whole_topology() const
Definition: metadata_cache.h:235
metadata_cache::MetadataCacheAPIBase::RefreshStatus refresh_status()
Definition: metadata_cache.h:200
mysqlrouter::TargetCluster target_cluster_
Definition: metadata_cache.h:292
std::condition_variable refresh_completed_
Definition: metadata_cache.h:352
std::mutex cache_refreshing_mutex_
Definition: metadata_cache.h:336
mysql_harness::MySQLRouterThread refresh_thread_
refresh thread facade
Definition: metadata_cache.h:329
std::mutex cluster_instances_change_callbacks_mtx_
Definition: metadata_cache.h:355
bool use_cluster_notifications_
Definition: metadata_cache.h:347
std::shared_ptr< MetaData > meta_data_
Definition: metadata_cache.h:326
std::chrono::milliseconds ttl() const
Definition: metadata_cache.h:212
metadata_cache::ClusterTopology cluster_topology_
Definition: metadata_cache.h:289
std::set< metadata_cache::ClusterStateListenerInterface * > state_listeners_
Definition: metadata_cache.h:359
std::set< metadata_cache::MetadataRefreshListenerInterface * > md_refresh_listeners_
Definition: metadata_cache.h:363
virtual bool refresh(bool needs_writable_node)=0
Refreshes the cache.
virtual mysqlrouter::ClusterType cluster_type() const noexcept=0
std::condition_variable refresh_wait_
Definition: metadata_cache.h:349
metadata_cache::RouterAttributes router_attributes_
Definition: metadata_cache.h:391
std::mutex refresh_wait_mtx_
Definition: metadata_cache.h:350
metadata_cache::metadata_servers_list_t metadata_servers_
Definition: metadata_cache.h:299
unsigned router_id_
Definition: metadata_cache.h:308
std::mutex metadata_servers_mutex_
Definition: metadata_cache.h:340
std::mutex refresh_completed_mtx_
Definition: metadata_cache.h:353
std::mutex md_refresh_callbacks_mtx_
Definition: metadata_cache.h:357
std::mutex acceptor_handler_callbacks_mtx_
Definition: metadata_cache.h:356
mysqlrouter::SSLOptions ssl_options_
Definition: metadata_cache.h:305
void handle_sockets_acceptors_on_md_refresh()
Toggle socket acceptors state update on next metadata refresh.
Definition: metadata_cache.h:231
mysqlrouter::TargetCluster target_cluster() const
Definition: metadata_cache.h:213
void force_cache_update()
Definition: metadata_cache.h:221
std::set< metadata_cache::AcceptorUpdateHandlerInterface * > acceptor_update_listeners_
Definition: metadata_cache.h:361
mysql_harness::MySQLRouterThread notification_thread_
notification thread facade
Definition: metadata_cache.h:332
Monitor pattern.
Definition: monitor.h:39
Abstract class that provides interface for listener on whether the listening sockets acceptors state ...
Definition: metadata_cache.h:115
Abstract class that provides interface for listener on cluster status changes.
Definition: metadata_cache.h:86
Abstract class that provides interface for adding and removing observers on cluster status changes.
Definition: metadata_cache.h:177
virtual void add_state_listener(ClusterStateListenerInterface *listener)=0
Register observer that is notified when there is a change in the cluster nodes setup/state discovered...
virtual void remove_state_listener(ClusterStateListenerInterface *listener)=0
Unregister observer previously registered with add_state_listener()
Class ManagedInstance represents a server managed by the topology.
Definition: metadata_cache_datatypes.h:101
Abstract class that provides interface for listener on metadata refresh.
Definition: metadata_cache.h:143
MySQLRouterThread provides higher level interface to managing threads.
Definition: mysql_router_thread.h:80
Defines an IP address with port number
Definition: tcp_address.h:40
Definition: cluster_metadata.h:159
static void start(mysql_harness::PluginFuncEnv *env)
Definition: http_auth_backend_plugin.cc:180
Logging interface for using and extending the logging subsystem.
#define METADATA_CACHE_EXPORT
Definition: metadata_cache_export.h:15
char * user
Definition: mysqladmin.cc:66
char server_uuid[UUID_LENGTH+1]
Definition: mysqld.cc:1473
static bool timeout(bool(*wait_condition)())
Timeout function.
Definition: log0meb.cc:498
Definition: metadata_cache.h:53
std::vector< metadata_server_t > metadata_servers_list_t
Definition: metadata_cache_datatypes.h:146
bool operator!=(const metadata_cache::ManagedCluster &cluster_a, const metadata_cache::ManagedCluster &cluster_b)
Definition: metadata_cache.cc:305
std::vector< ManagedInstance > cluster_nodes_list_t
Definition: metadata_cache_datatypes.h:142
bool operator==(const metadata_cache::ManagedCluster &cluster_a, const metadata_cache::ManagedCluster &cluster_b)
Definition: metadata_cache.cc:286
Definition: common.h:42
static const size_t kDefaultStackSizeInKiloBytes
Definition: mysql_router_thread.h:44
ClusterType
Definition: cluster_metadata.h:140
ServerMode
Definition: datatypes.h:55
Definition: gcs_xcom_synode.h:64
mode
Definition: file_handle.h:61
std::vector< T, ut::allocator< T > > vector
Specialization of vector which uses allocator.
Definition: ut0new.h:2875
std::string to_string(metadata_cache::ServerMode mode)
Definition: metadata_cache.cc:333
std::string get_hidden_info(const metadata_cache::ManagedInstance &instance)
Gets user readable information string about the nodes attributes related to _hidden and _disconnect_e...
Definition: metadata_cache.cc:346
Definition: metadata_cache.h:310
MetaData::auth_credentials_t rest_auth_data_
Definition: metadata_cache.h:312
std::chrono::system_clock::time_point last_credentials_update_
Definition: metadata_cache.h:314
Definition: metadata_cache.h:365
uint16_t last_metadata_server_port
Definition: metadata_cache.h:372
std::chrono::system_clock::time_point last_refresh_failed
Definition: metadata_cache.h:366
std::chrono::system_clock::time_point last_refresh_succeeded
Definition: metadata_cache.h:367
std::string last_metadata_server_host
Definition: metadata_cache.h:371
Represents a cluster (a GR group or AR members) and its metadata servers.
Definition: metadata_cache_datatypes.h:183
Metadata TTL configuration.
Definition: metadata_cache.h:213
Definition: metadata_cache_datatypes.h:239
SSL connection related options.
Definition: datatypes.h:39
Definition: mysqlslap.cc:240
double seconds()
Definition: task.cc:310