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