MySQL 8.0.39
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 MYSQLROUTER_METADATA_CACHE_INCLUDED
27#define MYSQLROUTER_METADATA_CACHE_INCLUDED
28
30
31#include <atomic>
32#include <chrono>
33#include <exception>
34#include <list>
35#include <map>
36#include <stdexcept>
37#include <string>
38#include <vector>
39
40#include "my_rapidjson_size_t.h"
41
42#include <rapidjson/document.h>
43
45#include "mysql_router_thread.h"
51#include "tcp_address.h"
52
53namespace metadata_cache {
54constexpr const uint16_t kDefaultMetadataPort{32275};
55constexpr const std::string_view kDefaultMetadataAddress{"127.0.0.1:32275"};
56constexpr const std::string_view kDefaultMetadataUser{""};
57constexpr const std::string_view kDefaultMetadataPassword{""};
58constexpr const std::chrono::milliseconds kDefaultMetadataTTL{500};
59constexpr const std::chrono::milliseconds kDefaultAuthCacheTTL{
61constexpr const std::chrono::milliseconds kDefaultAuthCacheRefreshInterval{
62 2000};
63// blank cluster name means pick the 1st (and only) cluster
64constexpr const std::string_view kDefaultMetadataCluster{""};
65constexpr const unsigned int kDefaultConnectTimeout{
67constexpr const unsigned int kDefaultReadTimeout{
69
70constexpr const std::string_view kNodeTagHidden{"_hidden"};
71constexpr const std::string_view kNodeTagDisconnectWhenHidden{
72 "_disconnect_existing_sessions_when_hidden"};
73
74/** @class metadata_error
75 * Class that represents all the exceptions that are thrown while fetching the
76 * metadata.
77 *
78 */
79class metadata_error : public std::runtime_error {
80 public:
81 explicit metadata_error(const std::string &what_arg)
82 : std::runtime_error(what_arg) {}
83};
84
85/**
86 * @brief Abstract class that provides interface for listener on
87 * cluster status changes.
88 *
89 * When state of cluster is changed, notify function is called.
90 */
92 public:
93 /**
94 * @brief Callback function that is called when state of cluster is
95 * changed.
96 *
97 * @param cluster_topology current cluster topology
98 * @param md_servers_reachable true if metadata changed, false if metadata
99 * unavailable
100 * @param view_id current metadata view_id in case of ReplicaSet cluster
101 */
102 virtual void notify_instances_changed(const ClusterTopology &cluster_topology,
103 const bool md_servers_reachable,
104 const uint64_t view_id) = 0;
105
107 // disable copy as it isn't needed right now. Feel free to enable
108 // must be explicitly defined though.
110 const ClusterStateListenerInterface &) = delete;
112 const ClusterStateListenerInterface &) = delete;
114};
115
116/**
117 * @brief Abstract class that provides interface for listener on
118 * whether the listening sockets acceptors state should be updated.
119 */
121 public:
122 /**
123 * @brief Callback function that is called when the state of the sockets
124 * acceptors is handled during the metadata refresh.
125 *
126 * @param instances list of the current cluster nodes
127 */
129 const metadata_cache::cluster_nodes_list_t &instances) = 0;
130
132
134 default;
136 const AcceptorUpdateHandlerInterface &) = default;
137
140 default;
141
143};
144
145/**
146 * Abstract class that provides interface for listener on metadata refresh.
147 */
149 public:
151
153 default;
155 default;
156
158 const MetadataRefreshListenerInterface &) = default;
161
162 /**
163 * Callback that is going to be used on each metadata refresh.
164 *
165 * @param[in] instances_changed Informs if the cluster topology has changed
166 * since last md refresh.
167 * @param[in] cluster_topology current cluster topology
168 */
169 virtual void on_md_refresh(const bool instances_changed,
170 const ClusterTopology &cluster_topology) = 0;
171
173};
174/**
175 * @brief Abstract class that provides interface for adding and removing
176 * observers on cluster status changes.
177 *
178 * When state of cluster is changed, then
179 * ClusterStateListenerInterface::notify function is called
180 * for every registered observer.
181 */
183 public:
184 /**
185 * @brief Register observer that is notified when there is a change in the
186 * cluster nodes setup/state discovered.
187 *
188 * @param listener Observer object that is notified when cluster nodes
189 * state is changed.
190 *
191 * @throw std::runtime_error if metadata cache not initialized
192 */
194
195 /**
196 * @brief Unregister observer previously registered with add_state_listener()
197 *
198 * @param listener Observer object that should be unregistered.
199 *
200 * @throw std::runtime_error if metadata cache not initialized
201 */
203 ClusterStateListenerInterface *listener) = 0;
204
206 // disable copy as it isn't needed right now. Feel free to enable
207 // must be explicitly defined though.
209 const ClusterStateNotifierInterface &) = delete;
211 const ClusterStateNotifierInterface &) = delete;
213};
214
215/**
216 * @brief Metadata TTL configuration
217 */
219 // The time to live for the cached data
220 std::chrono::milliseconds ttl;
221
222 // auth_cache_ttl TTL of the rest user authentication data
223 std::chrono::milliseconds auth_cache_ttl;
224
225 // auth_cache_refresh_interval Refresh rate of the rest user authentication
226 // data
227 std::chrono::milliseconds auth_cache_refresh_interval;
228};
229
232 public:
233 /** @brief Initialize a MetadataCache object and start caching
234 *
235 * The metadata_cache::cache_init function will initialize a MetadataCache
236 * object using the given arguments and store it globally using the given
237 * cache_name.
238 *
239 * Parameters host, port, user, password are used to setup the connection with
240 * the metadata server.
241 *
242 * Cache name given by cache_name can be empty, but must be unique.
243 *
244 * The parameters connection_timeout and connection_attempts are used when
245 * connected to the metadata server.
246 *
247 * Throws a std::runtime_error when the cache object was already
248 * initialized.
249 *
250 * @param cluster_type type of the cluster the metadata cache object will
251 * represent (GR or ReplicaSet)
252 * @param router_id id of the router in the cluster metadata
253 * @param clusterset_id UUID of the ClusterSet the Cluster belongs to (if
254 * bootstrapped as a ClusterSet, empty otherwise)
255 * @param metadata_servers The list of cluster metadata servers
256 * @param ttl_config metadata TTL configuration
257 * @param ssl_options SSL related options for connection
258 * @param target_cluster object identifying the Cluster this operation refers
259 * to
260 * @param session_config Metadata MySQL session configuration
261 * @param router_attributes Router attributes to be registered in the metadata
262 * @param thread_stack_size memory in kilobytes allocated for thread's stack
263 * @param use_cluster_notifications Flag indicating if the metadata cache
264 * should use cluster notifications as an
265 * additional trigger for metadata refresh
266 * (only available for GR cluster type)
267 * @param view_id last known view_id of the cluster metadata (only relevant
268 * for ReplicaSet cluster)
269 *
270 */
271 virtual void cache_init(
272 const mysqlrouter::ClusterType cluster_type, const unsigned router_id,
273 const std::string &clusterset_id,
274 const metadata_servers_list_t &metadata_servers,
275 const MetadataCacheTTLConfig &ttl_config,
276 const mysqlrouter::SSLOptions &ssl_options,
277 const mysqlrouter::TargetCluster &target_cluster,
278 const MetadataCacheMySQLSessionConfig &session_config,
279 const RouterAttributes &router_attributes,
280 size_t thread_stack_size = mysql_harness::kDefaultStackSizeInKiloBytes,
281 bool use_cluster_notifications = false, const uint64_t view_id = 0) = 0;
282
283 virtual void instance_name(const std::string &inst_name) = 0;
284 virtual std::string instance_name() const = 0;
285
286 virtual bool is_initialized() noexcept = 0;
287
288 virtual bool fetch_whole_topology() const = 0;
289 virtual void fetch_whole_topology(bool val) = 0;
290
291 virtual mysqlrouter::ClusterType cluster_type() const = 0;
292
293 /**
294 * @brief Start the metadata cache
295 */
296 virtual void cache_start() = 0;
297
298 /**
299 * @brief Teardown the metadata cache
300 */
301 virtual void cache_stop() noexcept = 0;
302
303 /** @brief Returns list of managed server in a HA cluster
304 * * Returns a list of MySQL servers managed by the topology for the given
305 * HA cluster.
306 *
307 * @return List of ManagedInstance objects
308 */
309 virtual cluster_nodes_list_t get_cluster_nodes() = 0;
310
311 /** @brief Return object containing current cluster topology.
312 *
313 * @return List of ManagedInstance objects
314 */
315 virtual ClusterTopology get_cluster_topology() = 0;
316
317 /** @brief Wait until there's a primary member in the cluster
318 *
319 * To be called when the primary member of a single-primary cluster is down
320 * and we want to wait until one becomes elected.
321 *
322 * @param primary_server_uuid - server_uuid of the PRIMARY that shall be
323 * failover from.
324 * @param timeout - amount of time to wait for a failover, in seconds
325 * @return true if a primary member exists
326 */
327 virtual bool wait_primary_failover(const std::string &primary_server_uuid,
328 const std::chrono::seconds &timeout) = 0;
329
330 /**
331 * @brief Register observer that is notified when there is a change in the
332 * cluster nodes setup/state discovered.
333 *
334 * @param listener Observer object that is notified when cluster nodes
335 * state is changed.
336 */
337 void add_state_listener(ClusterStateListenerInterface *listener) override = 0;
338
339 /**
340 * @brief Unregister observer previously registered with add_state_listener()
341 *
342 * @param listener Observer object that should be unregistered.
343 */
344 void remove_state_listener(ClusterStateListenerInterface *listener) override =
345 0;
346
347 /**
348 * @brief Register observer that is notified when the state of listening
349 * socket acceptors should be updated on the next metadata refresh.
350 *
351 * @param listener Observer object that is notified when replicaset nodes
352 * state is changed.
353 */
354 virtual void add_acceptor_handler_listener(
355 AcceptorUpdateHandlerInterface *listener) = 0;
356
357 /**
358 * @brief Unregister observer previously registered with
359 * add_acceptor_handler_listener()
360 *
361 * @param listener Observer object that should be unregistered.
362 */
363 virtual void remove_acceptor_handler_listener(
364 AcceptorUpdateHandlerInterface *listener) = 0;
365
366 /**
367 * Register observer that is notified when the metadata refresh is triggered.
368 *
369 * @param listener Observer object that is notified on metadata refresh.
370 */
371 virtual void add_md_refresh_listener(
373
374 /**
375 * @brief Unregister observer previously registered with
376 * add_md_refresh_listener()
377 *
378 * @param listener Observer object that should be unregistered.
379 */
380 virtual void remove_md_refresh_listener(
382
383 /** @brief Get authentication data (password hash and privileges) for the
384 * given user.
385 *
386 * @param username - name of the user for which the authentidation data
387 * is requested
388 * @return true and password hash with privileges - authentication data
389 * requested for the given user.
390 * @return false and empty data set - username is not found or authentication
391 * data expired.
392 */
393 virtual std::pair<bool, std::pair<std::string, rapidjson::Document>>
394 get_rest_user_auth_data(const std::string &username) const = 0;
395
396 /**
397 * @brief Enable fetching authentication metadata when using metadata_cache
398 * http authentication backend.
399 */
400 virtual void enable_fetch_auth_metadata() = 0;
401
402 /**
403 * Force cache update in refresh loop.
404 */
405 virtual void force_cache_update() = 0;
406
407 /**
408 * Check values of auth_cache_ttl and auth_cache_refresh_interval timers.
409 *
410 * @throw std::invalid_argument for each of the following scenarios:
411 * 1. auth_cache_ttl < ttl
412 * 2. auth_cache_refresh_interval < ttl
413 * 3. auth_cache_refresh_interval > auth_cache_ttl
414 */
415 virtual void check_auth_metadata_timers() const = 0;
416
417 /**
418 * Toggle socket acceptors state update on next metadata refresh.
419 */
420 virtual void handle_sockets_acceptors_on_md_refresh() = 0;
421
423 // disable copy as it isn't needed right now. Feel free to enable
424 // must be explicitly defined though.
425 explicit MetadataCacheAPIBase(const MetadataCacheAPIBase &) = delete;
426 MetadataCacheAPIBase &operator=(const MetadataCacheAPIBase &) = delete;
427 ~MetadataCacheAPIBase() override = default;
428
432 std::chrono::system_clock::time_point last_refresh_succeeded;
433 std::chrono::system_clock::time_point last_refresh_failed;
434
437 };
438
441
442 virtual std::chrono::milliseconds ttl() const = 0;
443
444 using metadata_factory_t = std::function<std::shared_ptr<MetaData>(
445 mysqlrouter::ClusterType cluster_type,
447 const mysqlrouter::SSLOptions &ssl_options,
448 const bool use_cluster_notifications, unsigned view_id)>;
449
451};
452
453// This provides a factory method that returns a pluggable instance
454// to the underlying transport layer implementation. The transport
455// layer provides the means from which the metadata is
456// fetched.
457
458std::shared_ptr<MetaData> metadata_factory_get_instance(
459 const mysqlrouter::ClusterType cluster_type,
461 const mysqlrouter::SSLOptions &ssl_options, const bool use_gr_notifications,
462 const unsigned view_id);
463
465 public:
466 static MetadataCacheAPIBase *instance();
467
468 void cache_init(const mysqlrouter::ClusterType cluster_type,
469 const unsigned router_id, const std::string &clusterset_id,
470 const metadata_servers_list_t &metadata_servers,
471 const MetadataCacheTTLConfig &ttl_config,
472 const mysqlrouter::SSLOptions &ssl_options,
473 const mysqlrouter::TargetCluster &target_cluster,
474 const MetadataCacheMySQLSessionConfig &session_config,
475 const RouterAttributes &router_attributes,
476 size_t thread_stack_size, bool use_cluster_notifications,
477 const uint64_t view_id) override;
478
479 mysqlrouter::ClusterType cluster_type() const override;
480
481 void instance_name(const std::string &inst_name) override;
482 std::string instance_name() const override;
483
484 mysqlrouter::TargetCluster target_cluster() const override;
485 std::chrono::milliseconds ttl() const override;
486
487 bool is_initialized() noexcept override { return is_initialized_; }
488 void cache_start() override;
489
490 void cache_stop() noexcept override;
491
492 cluster_nodes_list_t get_cluster_nodes() override;
493 ClusterTopology get_cluster_topology() override;
494
495 bool wait_primary_failover(const std::string &primary_server_uuid,
496 const std::chrono::seconds &timeout) override;
497
498 void add_state_listener(ClusterStateListenerInterface *listener) override;
499
500 void remove_state_listener(ClusterStateListenerInterface *listener) override;
501
502 void add_acceptor_handler_listener(
503 AcceptorUpdateHandlerInterface *listener) override;
504
505 void remove_acceptor_handler_listener(
506 AcceptorUpdateHandlerInterface *listener) override;
507
508 void add_md_refresh_listener(
509 MetadataRefreshListenerInterface *listener) override;
510
511 void remove_md_refresh_listener(
512 MetadataRefreshListenerInterface *listener) override;
513
514 RefreshStatus get_refresh_status() override;
515
516 std::pair<bool, std::pair<std::string, rapidjson::Document>>
517 get_rest_user_auth_data(const std::string &user) const override;
518
519 void enable_fetch_auth_metadata() override;
520 void force_cache_update() override;
521 void check_auth_metadata_timers() const override;
522
523 void handle_sockets_acceptors_on_md_refresh() override;
524
525 void set_instance_factory(metadata_factory_t cb) override {
526 instance_factory_ = std::move(cb);
527 }
528
529 bool fetch_whole_topology() const override;
530 void fetch_whole_topology(bool val) override;
531
532 private:
534
535 struct InstData {
536 std::string name;
537 };
539
540 std::atomic<bool> is_initialized_{false};
541 MetadataCacheAPI() = default;
544};
545
546} // namespace metadata_cache
547
548#endif // MYSQLROUTER_METADATA_CACHE_INCLUDED
Monitor pattern.
Definition: monitor.h:39
Abstract class that provides interface for listener on whether the listening sockets acceptors state ...
Definition: metadata_cache.h:120
virtual bool update_socket_acceptor_state(const metadata_cache::cluster_nodes_list_t &instances)=0
Callback function that is called when the state of the sockets acceptors is handled during the metada...
AcceptorUpdateHandlerInterface & operator=(AcceptorUpdateHandlerInterface &&)=default
AcceptorUpdateHandlerInterface & operator=(const AcceptorUpdateHandlerInterface &)=default
AcceptorUpdateHandlerInterface(AcceptorUpdateHandlerInterface &&)=default
AcceptorUpdateHandlerInterface(const AcceptorUpdateHandlerInterface &)=default
Abstract class that provides interface for listener on cluster status changes.
Definition: metadata_cache.h:91
ClusterStateListenerInterface & operator=(const ClusterStateListenerInterface &)=delete
ClusterStateListenerInterface(const ClusterStateListenerInterface &)=delete
virtual void notify_instances_changed(const ClusterTopology &cluster_topology, const bool md_servers_reachable, const uint64_t view_id)=0
Callback function that is called when state of cluster is changed.
Abstract class that provides interface for adding and removing observers on cluster status changes.
Definition: metadata_cache.h:182
ClusterStateNotifierInterface(const ClusterStateNotifierInterface &)=delete
ClusterStateNotifierInterface & operator=(const ClusterStateNotifierInterface &)=delete
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()
Definition: metadata_cache.h:231
virtual std::string instance_name() const =0
virtual std::chrono::milliseconds ttl() const =0
virtual void instance_name(const std::string &inst_name)=0
virtual void cache_init(const mysqlrouter::ClusterType cluster_type, const unsigned router_id, const std::string &clusterset_id, const metadata_servers_list_t &metadata_servers, const MetadataCacheTTLConfig &ttl_config, const mysqlrouter::SSLOptions &ssl_options, const mysqlrouter::TargetCluster &target_cluster, const MetadataCacheMySQLSessionConfig &session_config, const RouterAttributes &router_attributes, size_t thread_stack_size=mysql_harness::kDefaultStackSizeInKiloBytes, bool use_cluster_notifications=false, const uint64_t view_id=0)=0
Initialize a MetadataCache object and start caching.
virtual bool is_initialized() noexcept=0
virtual mysqlrouter::TargetCluster target_cluster() const =0
virtual RefreshStatus get_refresh_status()=0
virtual void set_instance_factory(metadata_factory_t cb)=0
std::function< std::shared_ptr< MetaData >(mysqlrouter::ClusterType cluster_type, const metadata_cache::MetadataCacheMySQLSessionConfig &session_config, const mysqlrouter::SSLOptions &ssl_options, const bool use_cluster_notifications, unsigned view_id)> metadata_factory_t
Definition: metadata_cache.h:448
Definition: metadata_cache.h:464
bool is_initialized() noexcept override
Definition: metadata_cache.h:487
MetadataCacheAPI & operator=(const MetadataCacheAPI &)=delete
MetadataCacheAPI(const MetadataCacheAPI &)=delete
Abstract class that provides interface for listener on metadata refresh.
Definition: metadata_cache.h:148
MetadataRefreshListenerInterface & operator=(const MetadataRefreshListenerInterface &)=default
virtual void on_md_refresh(const bool instances_changed, const ClusterTopology &cluster_topology)=0
Callback that is going to be used on each metadata refresh.
MetadataRefreshListenerInterface & operator=(MetadataRefreshListenerInterface &&)=default
MetadataRefreshListenerInterface(const MetadataRefreshListenerInterface &)=default
MetadataRefreshListenerInterface(MetadataRefreshListenerInterface &&)=default
Class that represents all the exceptions that are thrown while fetching the metadata.
Definition: metadata_cache.h:79
metadata_error(const std::string &what_arg)
Definition: metadata_cache.h:81
static constexpr int kDefaultReadTimeout
Definition: mysql_session.h:156
static constexpr int kDefaultConnectTimeout
Definition: mysql_session.h:155
Definition: cluster_metadata.h:161
#define METADATA_CACHE_EXPORT
Definition: metadata_cache_export.h:15
Define rapidjson::SizeType to be std::size_t.
char * user
Definition: mysqladmin.cc:60
static bool timeout(bool(*wait_condition)())
Timeout function.
Definition: log0meb.cc:496
Definition: metadata_cache.h:53
constexpr const std::string_view kDefaultMetadataCluster
Definition: metadata_cache.h:64
constexpr const std::string_view kDefaultMetadataUser
Definition: metadata_cache.h:56
std::vector< metadata_server_t > metadata_servers_list_t
Definition: metadata_cache_datatypes.h:146
constexpr const std::string_view kNodeTagHidden
Definition: metadata_cache.h:70
std::vector< ManagedInstance > cluster_nodes_list_t
Definition: metadata_cache_datatypes.h:142
constexpr const std::string_view kDefaultMetadataAddress
Definition: metadata_cache.h:55
constexpr const std::chrono::milliseconds kDefaultMetadataTTL
Definition: metadata_cache.h:58
constexpr const std::chrono::milliseconds kDefaultAuthCacheTTL
Definition: metadata_cache.h:59
constexpr const std::string_view kDefaultMetadataPassword
Definition: metadata_cache.h:57
constexpr const unsigned int kDefaultConnectTimeout
Definition: metadata_cache.h:65
constexpr const std::chrono::milliseconds kDefaultAuthCacheRefreshInterval
Definition: metadata_cache.h:61
constexpr const uint16_t kDefaultMetadataPort
Definition: metadata_cache.h:54
constexpr const unsigned int kDefaultReadTimeout
Definition: metadata_cache.h:67
constexpr const std::string_view kNodeTagDisconnectWhenHidden
Definition: metadata_cache.h:71
std::shared_ptr< MetaData > metadata_factory_get_instance(const mysqlrouter::ClusterType cluster_type, const metadata_cache::MetadataCacheMySQLSessionConfig &session_config, const mysqlrouter::SSLOptions &ssl_options, const bool use_gr_notifications, const unsigned view_id)
Return an instance of cluster metadata.
Definition: metadata_factory.cc:48
static const size_t kDefaultStackSizeInKiloBytes
Definition: mysql_router_thread.h:44
Definition: dim.h:358
ClusterType
Definition: cluster_metadata.h:141
Definition: my_rapidjson_size_t.h:38
Definition: gcs_xcom_synode.h:64
Represents a cluster (a GR group or AR members) and its metadata servers.
Definition: metadata_cache_datatypes.h:181
std::string last_metadata_server_host
Definition: metadata_cache.h:435
uint64_t refresh_failed
Definition: metadata_cache.h:430
std::chrono::system_clock::time_point last_refresh_failed
Definition: metadata_cache.h:433
uint16_t last_metadata_server_port
Definition: metadata_cache.h:436
uint64_t refresh_succeeded
Definition: metadata_cache.h:431
std::chrono::system_clock::time_point last_refresh_succeeded
Definition: metadata_cache.h:432
Definition: metadata_cache.h:535
std::string name
Definition: metadata_cache.h:536
Metadata MySQL session configuration.
Definition: metadata_cache_datatypes.h:221
Metadata TTL configuration.
Definition: metadata_cache.h:218
std::chrono::milliseconds auth_cache_refresh_interval
Definition: metadata_cache.h:227
std::chrono::milliseconds ttl
Definition: metadata_cache.h:220
std::chrono::milliseconds auth_cache_ttl
Definition: metadata_cache.h:223
Definition: metadata_cache_datatypes.h:237
SSL connection related options.
Definition: datatypes.h:39
double seconds()
Definition: task.cc:310