MySQL 8.0.30
Source Code Documentation
rpl_gtid.h
Go to the documentation of this file.
1/* Copyright (c) 2011, 2022, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23#ifndef RPL_GTID_H_INCLUDED
24#define RPL_GTID_H_INCLUDED
25
26#include <atomic>
27#include <cinttypes>
28#include <list>
29#include <mutex> // std::adopt_lock_t
30
34#include "map_helpers.h"
35#include "my_dbug.h"
36#include "my_thread_local.h"
38#include "mysql/psi/mysql_rwlock.h" // mysql_rwlock_t
39#include "prealloced_array.h" // Prealloced_array
40#include "sql/rpl_reporting.h" // MAX_SLAVE_ERRMSG
41#include "template_utils.h"
42
43struct TABLE_LIST;
44class THD;
45
46/**
47 Report an error from code that can be linked into either the server
48 or mysqlbinlog. There is no common error reporting mechanism, so we
49 have to duplicate the error message (write it out in the source file
50 for mysqlbinlog, write it in share/messages_to_clients.txt for the
51 server).
52
53 @param MYSQLBINLOG_ERROR arguments to mysqlbinlog's 'error'
54 function, including the function call parentheses
55 @param SERVER_ERROR arguments to my_error, including the function
56 call parentheses.
57*/
58#ifndef MYSQL_SERVER
59#define BINLOG_ERROR(MYSQLBINLOG_ERROR, SERVER_ERROR) error MYSQLBINLOG_ERROR
60#else
61#define BINLOG_ERROR(MYSQLBINLOG_ERROR, SERVER_ERROR) my_error SERVER_ERROR
62#endif
63
70
71/**
72 This macro is used to check that the given character, pointed to by the
73 character pointer, is a space or not.
74*/
75#define SKIP_WHITESPACE() \
76 while (my_isspace(&my_charset_utf8_general_ci, *s)) s++
77/*
78 This macro must be used to filter out parts of the code that
79 is not used now but may be useful in future. In other words,
80 we want to keep such code until we make up our minds on whether
81 it should be removed or not.
82*/
83#undef NON_DISABLED_GTID
84
85/*
86 This macro must be used to filter out parts of the code that
87 is not used now but we are not sure if there is a bug around
88 them. In other words, we want to keep such code until we have
89 time to investigate it.
90*/
91#undef NON_ERROR_GTID
92
93#ifdef MYSQL_SERVER
94class String;
95class THD;
96#endif // ifdef MYSQL_SERVER
97
98/// Type of SIDNO (source ID number, first component of GTID)
99typedef int rpl_sidno;
100/// GNO, the second (numeric) component of a GTID, is an alias of
101/// binary_log::gtids::gno_t
104
105/**
106 Generic return type for many functions that can succeed or fail.
107
108 This is used in conjunction with the macros below for functions where
109 the return status either indicates "success" or "failure". It
110 provides the following features:
111
112 - The macros can be used to conveniently propagate errors from
113 called functions back to the caller.
114
115 - If a function is expected to print an error using my_error before
116 it returns an error status, then the macros assert that my_error
117 has been called.
118
119 - Does a DBUG_PRINT before returning failure.
120*/
122 /// The function completed successfully.
124 /// The function completed with error but did not report it.
126 /// The function completed with error and has called my_error.
129
130/**
131 @def __CHECK_RETURN_STATUS
132 Lowest level macro used in the PROPAGATE_* and RETURN_* macros
133 below.
134
135 If NDEBUG is defined, does nothing. Otherwise, if STATUS is
136 RETURN_STATUS_OK, does nothing; otherwise, make a dbug printout and
137 (if ALLOW_UNREPORTED==0) assert that STATUS !=
138 RETURN_STATUS_UNREPORTED.
139
140 @param STATUS The status to return.
141 @param ACTION A text that describes what we are doing: either
142 "Returning" or "Propagating" (used in DBUG_PRINT macros)
143 @param STATUS_NAME The stringified version of the STATUS (used in
144 DBUG_PRINT macros).
145 @param ALLOW_UNREPORTED If false, the macro asserts that STATUS is
146 not RETURN_STATUS_UNREPORTED_ERROR.
147*/
148#ifdef NDEBUG
149#define __CHECK_RETURN_STATUS(STATUS, ACTION, STATUS_NAME, ALLOW_UNREPORTED)
150#else
151extern void check_return_status(enum_return_status status, const char *action,
152 const char *status_name, int allow_unreported);
153#define __CHECK_RETURN_STATUS(STATUS, ACTION, STATUS_NAME, ALLOW_UNREPORTED) \
154 check_return_status(STATUS, ACTION, STATUS_NAME, ALLOW_UNREPORTED);
155#endif
156/**
157 Low-level macro that checks if STATUS is RETURN_STATUS_OK; if it is
158 not, then RETURN_VALUE is returned.
159 @see __DO_RETURN_STATUS
160*/
161#define __PROPAGATE_ERROR(STATUS, RETURN_VALUE, ALLOW_UNREPORTED) \
162 do { \
163 enum_return_status __propagate_error_status = STATUS; \
164 if (__propagate_error_status != RETURN_STATUS_OK) { \
165 __CHECK_RETURN_STATUS(__propagate_error_status, "Propagating", #STATUS, \
166 ALLOW_UNREPORTED); \
167 return RETURN_VALUE; \
168 } \
169 } while (0)
170/// Low-level macro that returns STATUS. @see __DO_RETURN_STATUS
171#define __RETURN_STATUS(STATUS, ALLOW_UNREPORTED) \
172 do { \
173 enum_return_status __return_status_status = STATUS; \
174 __CHECK_RETURN_STATUS(__return_status_status, "Returning", #STATUS, \
175 ALLOW_UNREPORTED); \
176 return __return_status_status; \
177 } while (0)
178/**
179 If STATUS (of type enum_return_status) returns RETURN_STATUS_OK,
180 does nothing; otherwise, does a DBUG_PRINT and returns STATUS.
181*/
182#define PROPAGATE_ERROR(STATUS) \
183 __PROPAGATE_ERROR(STATUS, __propagate_error_status, true)
184/**
185 If STATUS (of type enum_return_status) returns RETURN_STATUS_OK,
186 does nothing; otherwise asserts that STATUS ==
187 RETURN_STATUS_REPORTED_ERROR, does a DBUG_PRINT, and returns STATUS.
188*/
189#define PROPAGATE_REPORTED_ERROR(STATUS) \
190 __PROPAGATE_ERROR(STATUS, __propagate_error_status, false)
191/**
192 If STATUS (of type enum_return_status) returns RETURN_STATUS_OK,
193 does nothing; otherwise asserts that STATUS ==
194 RETURN_STATUS_REPORTED_ERROR, does a DBUG_PRINT, and returns 1.
195*/
196#define PROPAGATE_REPORTED_ERROR_INT(STATUS) __PROPAGATE_ERROR(STATUS, 1, false)
197/**
198 If STATUS returns something else than RETURN_STATUS_OK, does a
199 DBUG_PRINT. Then, returns STATUS.
200*/
201#define RETURN_STATUS(STATUS) __RETURN_STATUS(STATUS, true)
202/**
203 Asserts that STATUS is not RETURN_STATUS_UNREPORTED_ERROR. Then, if
204 STATUS is RETURN_STATUS_REPORTED_ERROR, does a DBUG_PRINT. Then,
205 returns STATUS.
206*/
207#define RETURN_REPORTED_STATUS(STATUS) __RETURN_STATUS(STATUS, false)
208/// Returns RETURN_STATUS_OK.
209#define RETURN_OK return RETURN_STATUS_OK
210/// Does a DBUG_PRINT and returns RETURN_STATUS_REPORTED_ERROR.
211#define RETURN_REPORTED_ERROR RETURN_STATUS(RETURN_STATUS_REPORTED_ERROR)
212/// Does a DBUG_PRINT and returns RETURN_STATUS_UNREPORTED_ERROR.
213#define RETURN_UNREPORTED_ERROR RETURN_STATUS(RETURN_STATUS_UNREPORTED_ERROR)
214
215/**
216 enum to map the result of Uuid::parse to the above Macros
217*/
220 if (status == 0)
221 RETURN_OK;
222 else
224}
225
226/**
227 Possible values for ENFORCE_GTID_CONSISTENCY.
228*/
234/**
235 Strings holding the enumeration values for
236 gtid_consistency_mode_names. Use get_gtid_consistency_mode_string
237 instead of accessing this directly.
238*/
239extern const char *gtid_consistency_mode_names[];
240/**
241 Current value for ENFORCE_GTID_CONSISTENCY.
242 Don't use this directly; use get_gtid_consistency_mode.
243*/
244extern ulong _gtid_consistency_mode;
245/**
246 Return the current value of ENFORCE_GTID_CONSISTENCY.
247
248 Caller must hold global_sid_lock.rdlock.
249*/
251/// Return the given GTID_CONSISTENCY_MODE as a string.
255}
256/**
257 Return the current value of ENFORCE_GTID_CONSISTENCY as a string.
258
259 Caller must hold global_sid_lock.rdlock.
260*/
263}
264
265/// One-past-the-max value of GNO
266const rpl_gno GNO_END = INT64_MAX;
267/// If the GNO goes above the number, generate a warning.
269/// The length of MAX_GNO when printed in decimal.
270const int MAX_GNO_TEXT_LENGTH = 19;
271/// The maximal possible length of thread_id when printed in decimal.
273
274/**
275 Parse a GNO from a string.
276
277 @param s Pointer to the string. *s will advance to the end of the
278 parsed GNO, if a correct GNO is found.
279 @retval GNO if a correct GNO (i.e., 0 or positive number) was found.
280 @retval -1 otherwise.
281*/
282rpl_gno parse_gno(const char **s);
283/**
284 Formats a GNO as a string.
285
286 @param s The buffer.
287 @param gno The GNO.
288 @return Length of the generated string.
289*/
290int format_gno(char *s, rpl_gno gno);
291
293
294/**
295 This has the functionality of mysql_rwlock_t, with two differences:
296 1. It has additional operations to check if the read and/or write lock
297 is held at the moment.
298 2. It is wrapped in an object-oriented interface.
299
300 Note that the assertions do not check whether *this* thread has
301 taken the lock (that would be more complicated as it would require a
302 dynamic data structure). Luckily, it is still likely that the
303 assertions find bugs where a thread forgot to take a lock, because
304 most of the time most locks are only used by one thread at a time.
305
306 The assertions are no-ops when DBUG is off.
307*/
309 public:
310 /// Initialize this Checkable_rwlock.
312#if defined(HAVE_PSI_INTERFACE)
313 PSI_rwlock_key psi_key [[maybe_unused]] = 0
314#endif
315 ) {
316#ifndef NDEBUG
317 m_lock_state.store(0);
318 m_dbug_trace = true;
319#else
320 m_is_write_lock = false;
321#endif
322#if defined(HAVE_PSI_INTERFACE)
323 mysql_rwlock_init(psi_key, &m_rwlock);
324#else
326#endif
327 }
328 /// Destroy this Checkable_lock.
330
332
333 /**
334 RAII class to acquire a lock for the duration of a block.
335 */
336 class Guard {
339
340 public:
341 /**
342 Create a guard, and optionally acquire a lock on it.
343 */
347 switch (lock_type) {
348 case READ_LOCK:
349 rdlock();
350 break;
351 case WRITE_LOCK:
352 wrlock();
353 break;
354 case TRY_READ_LOCK:
355 tryrdlock();
356 break;
357 case NO_LOCK:
358 break;
359 }
360 }
361
362 /**
363 Create a guard, assuming the caller already holds a lock on it.
364 */
366 std::adopt_lock_t t [[maybe_unused]])
367 : m_lock(lock), m_lock_type(lock_type) {
369 switch (lock_type) {
370 case READ_LOCK:
371 lock.assert_some_rdlock();
372 break;
373 case WRITE_LOCK:
374 lock.assert_some_wrlock();
375 break;
376 case TRY_READ_LOCK:
377 case NO_LOCK:
378 break;
379 }
380 }
381
382 /// Objects of this class should not be copied or moved.
383 Guard(Guard const &copy) = delete;
384 Guard(Guard const &&copy) = delete;
385
386 /// Unlock on destruct.
390 }
391
392 /// Acquire the read lock.
393 void rdlock() {
395 assert(m_lock_type == NO_LOCK);
396 m_lock.rdlock();
398 }
399
400 /// Acquire the write lock.
401 void wrlock() {
403 assert(m_lock_type == NO_LOCK);
404 m_lock.wrlock();
406 }
407
408 /**
409 Try to acquire the write lock, and fail if it cannot be
410 immediately granted.
411 */
412 int trywrlock() {
414 assert(m_lock_type == NO_LOCK);
415 int ret = m_lock.trywrlock();
416 if (ret == 0) m_lock_type = WRITE_LOCK;
417 return ret;
418 }
419
420 /**
421 Try to acquire a read lock, and fail if it cannot be
422 immediately granted.
423 */
424 int tryrdlock() {
426 assert(m_lock_type == NO_LOCK);
427 int ret = m_lock.tryrdlock();
428 if (ret == 0) m_lock_type = READ_LOCK;
429 return ret;
430 }
431
432 /// Unlock the lock.
433 void unlock() {
435 assert(m_lock_type != NO_LOCK);
436 m_lock.unlock();
437 }
438
439 /// Unlock the lock, if it was acquired by this guard.
442 if (m_lock_type != NO_LOCK) unlock();
443 }
444
445 /// Return the underlying Checkable_rwlock object.
446 Checkable_rwlock &get_lock() const { return m_lock; }
447
448 /// Return true if this object is read locked.
449 bool is_rdlocked() const { return m_lock_type == READ_LOCK; }
450
451 /// Return true if this object is write locked.
452 bool is_wrlocked() const { return m_lock_type == WRITE_LOCK; }
453
454 /// Return true if this object is either read locked or write locked.
455 bool is_locked() const { return m_lock_type != NO_LOCK; }
456 };
457
458 /// Acquire the read lock.
459 inline void rdlock() {
462#ifndef NDEBUG
463 if (m_dbug_trace) DBUG_PRINT("info", ("%p.rdlock()", this));
464 ++m_lock_state;
465#endif
466 }
467 /// Acquire the write lock.
468 inline void wrlock() {
471#ifndef NDEBUG
472 if (m_dbug_trace) DBUG_PRINT("info", ("%p.wrlock()", this));
473 m_lock_state.store(-1);
474#else
475 m_is_write_lock = true;
476#endif
477 }
478 /// Release the lock (whether it is a write or read lock).
479 inline void unlock() {
481#ifndef NDEBUG
482 if (m_dbug_trace) DBUG_PRINT("info", ("%p.unlock()", this));
483 int val = m_lock_state.load();
484 if (val > 0)
485 --m_lock_state;
486 else if (val == -1)
487 m_lock_state.store(0);
488 else
489 assert(0);
490#else
491 m_is_write_lock = false;
492#endif
494 }
495 /**
496 Return true if the write lock is held. Must only be called by
497 threads that hold a lock.
498 */
499 inline bool is_wrlock() {
501#ifndef NDEBUG
502 return get_state() == -1;
503#else
504 return m_is_write_lock;
505#endif
506 }
507
508 /**
509 Return 0 if the write lock is held, otherwise an error will be returned.
510 */
511 inline int trywrlock() {
513
514 if (ret == 0) {
516#ifndef NDEBUG
517 if (m_dbug_trace) DBUG_PRINT("info", ("%p.wrlock()", this));
518 m_lock_state.store(-1);
519#else
520 m_is_write_lock = true;
521#endif
522 }
523
524 return ret;
525 }
526
527 /**
528 Return 0 if the read lock is held, otherwise an error will be returned.
529 */
530 inline int tryrdlock() {
532
533 if (ret == 0) {
535#ifndef NDEBUG
536 if (m_dbug_trace) DBUG_PRINT("info", ("%p.rdlock()", this));
537 ++m_lock_state;
538#endif
539 }
540
541 return ret;
542 }
543
544 /// Assert that some thread holds either the read or the write lock.
545 inline void assert_some_lock() const { assert(get_state() != 0); }
546 /// Assert that some thread holds the read lock.
547 inline void assert_some_rdlock() const { assert(get_state() > 0); }
548 /// Assert that some thread holds the write lock.
549 inline void assert_some_wrlock() const { assert(get_state() == -1); }
550 /// Assert that no thread holds the write lock.
551 inline void assert_no_wrlock() const { assert(get_state() >= 0); }
552 /// Assert that no thread holds the read lock.
553 inline void assert_no_rdlock() const { assert(get_state() <= 0); }
554 /// Assert that no thread holds read or write lock.
555 inline void assert_no_lock() const { assert(get_state() == 0); }
556
557#ifndef NDEBUG
558
559 /// If enabled, print any lock/unlock operations to the DBUG trace.
561
562 private:
563 /**
564 The state of the lock:
565 0 - not locked
566 -1 - write locked
567 >0 - read locked by that many threads
568 */
569 std::atomic<int32> m_lock_state;
570 /// Read lock_state atomically and return the value.
571 inline int32 get_state() const { return m_lock_state.load(); }
572
573#else
574
575 private:
576 bool m_is_write_lock;
577
578#endif
579 /// The rwlock.
581};
582
583/// Protects Gtid_state. See comment above gtid_state for details.
585
586/**
587 Class to access the value of @@global.gtid_mode in an efficient and
588 thread-safe manner.
589*/
591 private:
592 std::atomic<int> m_atomic_mode;
593
594 public:
596
597 /**
598 The sys_var framework needs a variable of type ulong to store the
599 value in. The sys_var framework takes the value from there, but
600 we copy it (in the methods of sys_var_gtid_mode) to the atomic
601 value Gtid_mode::mode, and use only that in all other places.
602 */
603 static ulong sysvar_mode;
604
605 /// Possible values for @@global.gtid_mode.
607 /**
608 New transactions are anonymous. Replicated transactions must be
609 anonymous; replicated GTID-transactions generate an error.
610 */
611 OFF = 0,
613 /**
614 New transactions are anonyomus. Replicated transactions can be
615 either anonymous or GTID-transactions.
616 */
618 /**
619 New transactions are GTID-transactions. Replicated transactions
620 can be either anonymous or GTID-transactions.
621 */
623 /**
624 New transactions are GTID-transactions. Replicated transactions
625 must be GTID-transactions; replicated anonymous transactions
626 generate an error.
627 */
628 ON = 3
629 };
630
631 /**
632 Strings holding the enumeration values for gtid_mode. Use
633 Gtid_mode::get_string instead of accessing this directly.
634 */
635 static const char *names[];
636
637 /**
638 Protects updates to @@global.gtid_mode.
639
640 SET @@global.gtid_mode will try to take the write lock. If the
641 lock is not granted immediately, SET will fail.
642
643 Thus, any other operation can block updates to
644 @@global.gtid_mode by acquiring the read lock.
645 */
647
648 /**
649 Set a new value for @@global.gtid_mode.
650
651 This should only be called from Sys_var_gtid_mode::global_update
652 and gtid_server_init.
653 */
654 void set(value_type value);
655
656 public:
657 /**
658 Return the current gtid_mode as an enumeration value.
659 */
660 value_type get() const;
661
662#ifndef NDEBUG
663 /**
664 Return the current gtid_mode as a string.
665
666 Used only for debugging. Non-debug code typically reads and acts
667 on the enum value before printing it. Then it is better to print
668 the enum value.
669 */
670 const char *get_string() const;
671#endif // ifndef NDEBUG
672
673 /**
674 Return the given string gtid_mode as an enumeration value.
675
676 @param s The string to decode.
677
678 @return A pair, where the first component indicates failure and
679 the second component is the GTID_MODE. Specifically, the first
680 component is false if the string is a valid GTID_MODE, and true if
681 it is not.
682 */
683 static std::pair<bool, value_type> from_string(std::string s);
684
685 /// Return the given gtid_mode as a string.
686 static const char *to_string(value_type value);
687};
688
689std::ostream &operator<<(std::ostream &oss, Gtid_mode::value_type const &mode);
690#ifndef NDEBUG
691/**
692 Typically, code will print Gtid_mode only after reading and acting
693 on the enum value. Then it is better to print the enum value than to
694 read the shared resource again. Hence we enable this only in debug
695 mode, since it makes more sense to just get the string when doing a
696 debug printout.
697*/
698std::ostream &operator<<(std::ostream &oss, Gtid_mode const &mode);
699#endif
700
701/**
702 The one and only instance of Gtid_mode.
703
704 All access to @@global.gtid_mode should use this object.
705*/
707
708/**
709 Represents a bidirectional map between SID and SIDNO.
710
711 SIDNOs are always numbers greater or equal to 1.
712
713 This data structure OPTIONALLY knows of a read-write lock that
714 protects the number of SIDNOs. The lock is provided by the invoker
715 of the constructor and it is generally the caller's responsibility
716 to acquire the read lock. If the lock is not NULL, access methods
717 assert that the caller already holds the read (or write) lock. If
718 the lock is not NULL and a method of this class grows the number of
719 SIDNOs, then the method temporarily upgrades this lock to a write
720 lock and then degrades it to a read lock again; there will be a
721 short period when the lock is not held at all.
722*/
723class Sid_map {
724 public:
725 /**
726 Create this Sid_map.
727
728 @param sid_lock Read-write lock that protects updates to the
729 number of SIDNOs.
730 */
732 /// Destroy this Sid_map.
733 ~Sid_map();
734 /**
735 Clears this Sid_map (for RESET SLAVE)
736
737 @return RETURN_STATUS_OK or RETURN_STAUTS_REPORTED_ERROR
738 */
740 /**
741 Add the given SID to this map if it does not already exist.
742
743 The caller must hold the read lock or write lock on sid_lock
744 before invoking this function. If the SID does not exist in this
745 map, it will release the read lock, take a write lock, update the
746 map, release the write lock, and take the read lock again.
747
748 @param sid The SID.
749 @retval SIDNO The SIDNO for the SID (a new SIDNO if the SID did
750 not exist, an existing if it did exist).
751 @retval negative Error. This function calls my_error.
752 */
753 rpl_sidno add_sid(const rpl_sid &sid);
754 /**
755 Get the SIDNO for a given SID
756
757 The caller must hold the read lock on sid_lock before invoking
758 this function.
759
760 @param sid The SID.
761 @retval SIDNO if the given SID exists in this map.
762 @retval 0 if the given SID does not exist in this map.
763 */
764 rpl_sidno sid_to_sidno(const rpl_sid &sid) const {
765 if (sid_lock != nullptr) sid_lock->assert_some_lock();
766 const auto it = _sid_to_sidno.find(sid);
767 if (it == _sid_to_sidno.end()) return 0;
768 return it->second->sidno;
769 }
770 /**
771 Get the SID for a given SIDNO.
772
773 Raises an assertion if the SIDNO is not valid.
774
775 If need_lock is true, acquires sid_lock->rdlock; otherwise asserts
776 that it is held already.
777
778 @param sidno The SIDNO.
779 @param need_lock If true, and sid_lock!=NULL, this function will
780 acquire sid_lock before looking up the sid, and then release
781 it. If false, and sid_lock!=NULL, this function will assert the
782 sid_lock is already held. If sid_lock==NULL, nothing is done
783 w.r.t. locking.
784 @retval NULL The SIDNO does not exist in this map.
785 @retval pointer Pointer to the SID. The data is shared with this
786 Sid_map, so should not be modified. It is safe to read the data
787 even after this Sid_map is modified, but not if this Sid_map is
788 destroyed.
789 */
790 const rpl_sid &sidno_to_sid(rpl_sidno sidno, bool need_lock = false) const {
791 if (sid_lock != nullptr) {
792 if (need_lock)
793 sid_lock->rdlock();
794 else
796 }
797 assert(sidno >= 1 && sidno <= get_max_sidno());
798 const rpl_sid &ret = (_sidno_to_sid[sidno - 1])->sid;
799 if (sid_lock != nullptr && need_lock) sid_lock->unlock();
800 return ret;
801 }
802 /**
803 Return the n'th smallest sidno, in the order of the SID's UUID.
804
805 The caller must hold the read or write lock on sid_lock before
806 invoking this function.
807
808 @param n A number in the interval [0, get_max_sidno()-1], inclusively.
809 */
811 if (sid_lock != nullptr) sid_lock->assert_some_lock();
812 return _sorted[n];
813 }
814 /**
815 Return the biggest sidno in this Sid_map.
816
817 The caller must hold the read or write lock on sid_lock before
818 invoking this function.
819 */
821 if (sid_lock != nullptr) sid_lock->assert_some_lock();
822 return static_cast<rpl_sidno>(_sidno_to_sid.size());
823 }
824
825 /// Return the sid_lock.
827
828 /**
829 Deep copy this Sid_map to dest.
830
831 The caller must hold:
832 * the read lock on this sid_lock
833 * the write lock on the dest sid_lock
834 before invoking this function.
835
836 @param[out] dest The Sid_map to which the sids and sidnos will
837 be copied.
838 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
839 */
841
842 private:
843 /// Node pointed to by both the hash and the array.
844 struct Node {
847 };
848
849 static const uchar *sid_map_get_key(const uchar *ptr, size_t *length) {
850 const Node *node = pointer_cast<const Node *>(ptr);
852 return node->sid.bytes;
853 }
854
855 /**
856 Create a Node from the given SIDNO and SID and add it to
857 _sidno_to_sid, _sid_to_sidno, and _sorted.
858
859 The caller must hold the write lock on sid_lock before invoking
860 this function.
861
862 @param sidno The SIDNO to add.
863 @param sid The SID to add.
864 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
865 */
866 enum_return_status add_node(rpl_sidno sidno, const rpl_sid &sid);
867
868 /// Read-write lock that protects updates to the number of SIDNOs.
870
871 /**
872 Array that maps SIDNO to SID; the element at index N points to a
873 Node with SIDNO N-1.
874 */
876 /**
877 Hash that maps SID to SIDNO.
878 */
881 /**
882 Array that maps numbers in the interval [0, get_max_sidno()-1] to
883 SIDNOs, in order of increasing SID.
884
885 @see Sid_map::get_sorted_sidno.
886 */
888};
889
890extern Sid_map *global_sid_map;
891
892/**
893 Represents a growable array where each element contains a mutex and
894 a condition variable.
895
896 Each element can be locked, unlocked, broadcast, or waited for, and
897 it is possible to call "THD::enter_cond" for the condition. The
898 allowed indexes range from 0, inclusive, to get_max_index(),
899 inclusive. Initially there are zero elements (and get_max_index()
900 returns -1); more elements can be allocated by calling
901 ensure_index().
902
903 This data structure has a read-write lock that protects the number
904 of elements. The lock is provided by the invoker of the constructor
905 and it is generally the caller's responsibility to acquire the read
906 lock. Access methods assert that the caller already holds the read
907 (or write) lock. If a method of this class grows the number of
908 elements, then the method temporarily upgrades this lock to a write
909 lock and then degrades it to a read lock again; there will be a
910 short period when the lock is not held at all.
911*/
913 public:
914 /**
915 Create a new Mutex_cond_array.
916
917 @param global_lock Read-write lock that protects updates to the
918 number of elements.
919 */
921 /// Destroy this object.
923 /// Lock the n'th mutex.
924 inline void lock(int n) const {
927 }
928 /// Unlock the n'th mutex.
929 inline void unlock(int n) const {
932 }
933 /// Broadcast the n'th condition.
934 inline void broadcast(int n) const {
936 }
937 /**
938 Assert that this thread owns the n'th mutex.
939 This is a no-op if NDEBUG is on.
940 */
941 inline void assert_owner(int n [[maybe_unused]]) const {
942#ifndef NDEBUG
944#endif
945 }
946 /**
947 Assert that this thread does not own the n'th mutex.
948 This is a no-op if NDEBUG is on.
949 */
950 inline void assert_not_owner(int n [[maybe_unused]]) const {
951#ifndef NDEBUG
953#endif
954 }
955
956 /**
957 Wait for signal on the n'th condition variable.
958
959 The caller must hold the read lock or write lock on sid_lock, as
960 well as the nth mutex lock, before invoking this function. The
961 sid_lock will be released, whereas the mutex will be released
962 during the wait and (atomically) re-acquired when the wait ends
963 or the timeout is reached.
964
965 @param[in] thd THD object for the calling thread.
966 @param[in] sidno Condition variable to wait for.
967 @param[in] abstime The absolute point in time when the wait times
968 out and stops, or NULL to wait indefinitely.
969
970 @retval false Success.
971 @retval true Failure: either timeout or thread was killed. If
972 thread was killed, the error has been generated.
973 */
974 inline bool wait(const THD *thd, int sidno, struct timespec *abstime) const {
976 int error = 0;
977 Mutex_cond *mutex_cond = get_mutex_cond(sidno);
979 mysql_mutex_assert_owner(&mutex_cond->mutex);
980 if (is_thd_killed(thd)) return true;
981 if (abstime != nullptr)
982 error =
983 mysql_cond_timedwait(&mutex_cond->cond, &mutex_cond->mutex, abstime);
984 else
985 mysql_cond_wait(&mutex_cond->cond, &mutex_cond->mutex);
986 mysql_mutex_assert_owner(&mutex_cond->mutex);
987 return is_timeout(error);
988 }
989#ifdef MYSQL_SERVER
990 /// Execute THD::enter_cond for the n'th condition variable.
991 void enter_cond(THD *thd, int n, PSI_stage_info *stage,
992 PSI_stage_info *old_stage) const;
993#endif // ifdef MYSQL_SERVER
994 /// Return the greatest addressable index in this Mutex_cond_array.
995 inline int get_max_index() const {
997 return static_cast<int>(m_array.size() - 1);
998 }
999 /**
1000 Grows the array so that the given index fits.
1001
1002 If the array is grown, the global_lock is temporarily upgraded to
1003 a write lock and then degraded again; there will be a
1004 short period when the lock is not held at all.
1005
1006 @param n The index.
1007 @return RETURN_OK or RETURN_REPORTED_ERROR
1008 */
1009 enum_return_status ensure_index(int n);
1010
1011 private:
1012 /**
1013 Return true if the given THD is killed.
1014
1015 @param[in] thd - The thread object
1016 @retval true - thread is killed
1017 false - thread not killed
1018 */
1019 bool is_thd_killed(const THD *thd) const;
1020 /// A mutex/cond pair.
1021 struct Mutex_cond {
1024 };
1025 /// Return the Nth Mutex_cond object
1026 inline Mutex_cond *get_mutex_cond(int n) const {
1027 global_lock->assert_some_lock();
1028 assert(n <= get_max_index());
1029 Mutex_cond *ret = m_array[n];
1030 assert(ret);
1031 return ret;
1032 }
1033 /// Read-write lock that protects updates to the number of elements.
1036};
1037
1038/**
1039 Holds information about a GTID interval: the sidno, the first gno
1040 and the last gno of this interval.
1041*/
1043 /* SIDNO of this Gtid interval. */
1045 /* The first GNO of this Gtid interval. */
1047 /* The last GNO of this Gtid interval. */
1050 sidno = sid_no;
1051 gno_start = start;
1052 gno_end = end;
1053 }
1054};
1055
1056/**
1057 TODO: Move this structure to libbinlogevents/include/control_events.h
1058 when we start using C++11.
1059 Holds information about a GTID: the sidno and the gno.
1060
1061 This is a POD. It has to be a POD because it is part of
1062 Gtid_specification, which has to be a POD because it is used in
1063 THD::variables.
1064*/
1065struct Gtid {
1066 /// SIDNO of this Gtid.
1068 /// GNO of this Gtid.
1070
1071 /// Set both components to 0.
1072 void clear() {
1073 sidno = 0;
1074 gno = 0;
1075 }
1076 /// Set both components to the given, positive values.
1077 void set(rpl_sidno sidno_arg, rpl_gno gno_arg) {
1078 assert(sidno_arg > 0);
1079 assert(gno_arg > 0);
1080 assert(gno_arg < GNO_END);
1081 sidno = sidno_arg;
1082 gno = gno_arg;
1083 }
1084 /**
1085 Return true if sidno is zero (and assert that gno is zero too in
1086 this case).
1087 */
1088 bool is_empty() const {
1089 // check that gno is not set inconsistently
1090 if (sidno <= 0)
1091 assert(gno == 0);
1092 else
1093 assert(gno > 0);
1094 return sidno == 0;
1095 }
1096 /**
1097 The maximal length of the textual representation of a SID, not
1098 including the terminating '\0'.
1099 */
1100 static const int MAX_TEXT_LENGTH =
1102 /**
1103 Return true if parse() would succeed, but don't store the
1104 result anywhere.
1105 */
1106 static bool is_valid(const char *text);
1107 /**
1108 Convert a Gtid to a string.
1109 @param sid the sid to use. This overrides the sidno of this Gtid.
1110 @param[out] buf Buffer to store the Gtid in (normally
1111 MAX_TEXT_LENGTH+1 bytes long).
1112 @return Length of the string, not counting '\0'.
1113 */
1114 int to_string(const rpl_sid &sid, char *buf) const;
1115 /**
1116 Convert this Gtid to a string.
1117 @param sid_map sid_map to use when converting sidno to a SID.
1118 @param[out] buf Buffer to store the Gtid in (normally
1119 MAX_TEXT_LENGTH+1 bytes long).
1120 @param need_lock If true, the function will acquire sid_map->sid_lock;
1121 otherwise it will assert that the lock is held.
1122 @return Length of the string, not counting '\0'.
1123 */
1124 int to_string(const Sid_map *sid_map, char *buf,
1125 bool need_lock = false) const;
1126 /// Returns true if this Gtid has the same sid and gno as 'other'.
1127 bool equals(const Gtid &other) const {
1128 return sidno == other.sidno && gno == other.gno;
1129 }
1130 /**
1131 Parses the given string and stores in this Gtid.
1132
1133 @param sid_map sid_map to use when converting SID to a sidno.
1134 @param text The text to parse
1135 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
1136 */
1137 enum_return_status parse(Sid_map *sid_map, const char *text);
1138
1139#ifndef NDEBUG
1140 /// Debug only: print this Gtid to stdout.
1141 void print(const Sid_map *sid_map) const {
1142 char buf[MAX_TEXT_LENGTH + 1];
1143 to_string(sid_map, buf);
1144 printf("%s\n", buf);
1145 }
1146#endif
1147 /// Print this Gtid to the trace file if debug is enabled; no-op otherwise.
1148 void dbug_print(const Sid_map *sid_map [[maybe_unused]],
1149 const char *text [[maybe_unused]] = "",
1150 bool need_lock [[maybe_unused]] = false) const {
1151#ifndef NDEBUG
1152 char buf[MAX_TEXT_LENGTH + 1];
1153 to_string(sid_map, buf, need_lock);
1154 DBUG_PRINT("info", ("%s%s%s", text, *text ? ": " : "", buf));
1155#endif
1156 }
1157};
1158
1159/// Structure to store the GTID and timing information.
1161 /// GTID being monitored.
1163 /// OCT of the GTID being monitored.
1165 /// ICT of the GTID being monitored.
1167 /// When the GTID transaction started to be processed.
1169 /// When the GTID transaction finished to be processed.
1171 /// True if the GTID is being applied but will be skipped.
1173 /// True when this information contains useful data.
1175 /// Number of the last transient error of this transaction
1177 /// Message of the last transient error of this transaction
1179 /// Timestamp in microseconds of the last transient error of this transaction
1181 /// Number of times this transaction was retried
1183 /// True when the transaction is retrying
1185 /// The compression type
1187 /// The compressed bytes
1189 /// The uncompressed bytes
1191
1192 /// Constructor
1194 /// Copy constructor
1196
1198
1199 /// Clear all fields of the structure.
1200 void clear();
1201
1202 /**
1203 Copies this transaction monitoring information to the output parameters
1204 passed as input, which are the corresponding fields in a replication
1205 performance schema table.
1206
1207 @param[in] sid_map The SID map for the GTID.
1208 @param[out] gtid_arg GTID field in the PS table.
1209 @param[out] gtid_length_arg Length of the GTID as string.
1210 @param[out] original_commit_ts_arg The original commit timestamp.
1211 @param[out] immediate_commit_ts_arg The immediate commit timestamp.
1212 @param[out] start_time_arg The start time field.
1213 */
1214 void copy_to_ps_table(Sid_map *sid_map, char *gtid_arg, uint *gtid_length_arg,
1215 ulonglong *original_commit_ts_arg,
1216 ulonglong *immediate_commit_ts_arg,
1217 ulonglong *start_time_arg) const;
1218
1219 /**
1220 Copies this transaction monitoring information to the output parameters
1221 passed as input, which are the corresponding fields in a replication
1222 performance schema table.
1223
1224 @param[in] sid_map The SID map for the GTID.
1225 @param[out] gtid_arg GTID field in the PS table.
1226 @param[out] gtid_length_arg Length of the GTID as string.
1227 @param[out] original_commit_ts_arg The original commit timestamp.
1228 @param[out] immediate_commit_ts_arg The immediate commit timestamp.
1229 @param[out] start_time_arg The start time field.
1230 @param[out] end_time_arg The end time field. This can be null
1231 when the PS table fields are for the
1232 "still processing" information.
1233 */
1234 void copy_to_ps_table(Sid_map *sid_map, char *gtid_arg, uint *gtid_length_arg,
1235 ulonglong *original_commit_ts_arg,
1236 ulonglong *immediate_commit_ts_arg,
1237 ulonglong *start_time_arg,
1238 ulonglong *end_time_arg) const;
1239
1240 /**
1241 Copies this transaction monitoring information to the output parameters
1242 passed as input, which are the corresponding fields in a replication
1243 performance schema table.
1244
1245 @param[in] sid_map The SID map for the GTID.
1246 @param[out] gtid_arg GTID field in the PS table.
1247 @param[out] gtid_length_arg Length of the GTID as string.
1248 @param[out] original_commit_ts_arg The original commit timestamp.
1249 @param[out] immediate_commit_ts_arg The immediate commit timestamp.
1250 @param[out] start_time_arg The start time field.
1251 @param[out] last_transient_errno_arg The last transient error
1252 number.
1253 @param[out] last_transient_errmsg_arg The last transient error
1254 message.
1255 @param[out] last_transient_errmsg_length_arg Length of the last transient
1256 error message.
1257 @param[out] last_transient_timestamp_arg The last transient error
1258 timestamp.
1259 @param[out] retries_count_arg The total number of retries for
1260 this transaction.
1261 */
1262 void copy_to_ps_table(
1263 Sid_map *sid_map, char *gtid_arg, uint *gtid_length_arg,
1264 ulonglong *original_commit_ts_arg, ulonglong *immediate_commit_ts_arg,
1265 ulonglong *start_time_arg, uint *last_transient_errno_arg,
1266 char *last_transient_errmsg_arg, uint *last_transient_errmsg_length_arg,
1267 ulonglong *last_transient_timestamp_arg, ulong *retries_count_arg) const;
1268
1269 /**
1270 Copies this transaction monitoring information to the output parameters
1271 passed as input, which are the corresponding fields in a replication
1272 performance schema table.
1273
1274 @param[in] sid_map The SID map for the GTID.
1275 @param[out] gtid_arg GTID field in the PS table.
1276 @param[out] gtid_length_arg Length of the GTID as string.
1277 @param[out] original_commit_ts_arg The original commit timestamp.
1278 @param[out] immediate_commit_ts_arg The immediate commit timestamp.
1279 @param[out] start_time_arg The start time field.
1280 @param[out] end_time_arg The end time field. This can be
1281 null when the PS table fields
1282 are for the "still processing"
1283 information.
1284 @param[out] last_transient_errno_arg The last transient error
1285 number.
1286 @param[out] last_transient_errmsg_arg The last transient error
1287 message.
1288 @param[out] last_transient_errmsg_length_arg Length of the last transient
1289 error message.
1290 @param[out] last_transient_timestamp_arg The last transient error
1291 timestamp.
1292 @param[out] retries_count_arg The total number of retries for
1293 this transaction.
1294 */
1295 void copy_to_ps_table(Sid_map *sid_map, char *gtid_arg, uint *gtid_length_arg,
1296 ulonglong *original_commit_ts_arg,
1297 ulonglong *immediate_commit_ts_arg,
1298 ulonglong *start_time_arg, ulonglong *end_time_arg,
1299 uint *last_transient_errno_arg,
1300 char *last_transient_errmsg_arg,
1301 uint *last_transient_errmsg_length_arg,
1302 ulonglong *last_transient_timestamp_arg,
1303 ulong *retries_count_arg) const;
1304};
1305
1306/**
1307 Stores information to monitor a transaction during the different replication
1308 stages.
1309*/
1311 public:
1312 /**
1313 Create this GTID monitoring info object.
1314
1315 @param atomic_mutex_arg When specified, this object will rely on the mutex
1316 to arbitrate the read/update access to object data.
1317 This will be used by the receiver thread, relying
1318 on mi->data_lock. When no mutex is specified, the
1319 object will rely on its own atomic mechanism.
1320 */
1321 Gtid_monitoring_info(mysql_mutex_t *atomic_mutex_arg = nullptr);
1322
1323 /// Destroy this GTID monitoring info object.
1325
1326 protected:
1327 /// Holds information about transaction being processed.
1329 /// Holds information about the last processed transaction.
1331
1332 private:
1333 /**
1334 Mutex arbitrating the atomic access to the object.
1335
1336 Some Gtid_monitoring_info will rely on replication thread locks
1337 (i.e.: the Master_info's one rely on mi->data_lock, that is already
1338 acquired every time the Gtid_monitoring_info needs to be updated).
1339
1340 Other Gtid_monitoring_info will rely on an atomic lock implemented
1341 in this class to avoid overlapped reads and writes over the information.
1342 (i.e.: the Relay_log_info's one sometimes is updated without rli locks).
1343
1344 When atomic_mutex is NULL, the object will rely on its own atomic
1345 mechanism.
1346 */
1348
1349 /// The atomic locked flag.
1350 std::atomic<bool> atomic_locked{false};
1351#ifndef NDEBUG
1352 /// Flag to assert the atomic lock behavior.
1353 bool is_locked = false;
1354#endif
1355
1356 public:
1357 /**
1358 Lock this object when no thread mutex is used to arbitrate the access.
1359 */
1360 void atomic_lock();
1361 /**
1362 Unlock this object when no thread mutex is used to arbitrate the access.
1363 */
1364 void atomic_unlock();
1365 /**
1366 Clear all monitoring information.
1367 */
1368 void clear();
1369 /**
1370 Clear only the processing_trx monitoring info.
1371 */
1372 void clear_processing_trx();
1373 /**
1374 Clear only the last_processed_trx monitoring info.
1375 */
1377
1378 /**
1379 Sets the initial monitoring information.
1380 @param gtid_arg The Gtid to be stored.
1381 @param original_ts_arg The original commit timestamp of the GTID.
1382 @param immediate_ts_arg The immediate commit timestamp of the GTID.
1383 @param skipped_arg True if the GTID was already applied.
1384 This only make sense for applier threads.
1385 That's why it is false by default.
1386 */
1387 void start(Gtid gtid_arg, ulonglong original_ts_arg,
1388 ulonglong immediate_ts_arg, bool skipped_arg = false);
1389
1390 void update(binary_log::transaction::compression::type t, size_t payload_size,
1391 size_t uncompressed_size);
1392
1393 /**
1394 Sets the final information, copy processing info to last_processed
1395 and clears processing info.
1396 */
1397 void finish();
1398 /**
1399 Copies both processing_trx and last_processed_trx info to other
1400 Trx_monitoring_info structures.
1401
1402 @param[out] processing_dest The destination of processing_trx.
1403 @param[out] last_processed_dest The destination of last_processed_trx.
1404 */
1405 void copy_info_to(Trx_monitoring_info *processing_dest,
1406 Trx_monitoring_info *last_processed_dest);
1407 /**
1408 Copies all monitoring info to other Gtid_monitoring_info object.
1409
1410 @param[out] dest The destination Gtid_monitoring_info.
1411 */
1413 /// Returns true if the processing_trx is set, false otherwise.
1414 bool is_processing_trx_set();
1415 /// Returns the GTID of the processing_trx.
1417 /**
1418 Stores the information about the last transient error in the current
1419 transaction, namely: the error number, message and total number of retries.
1420 It also sets the timestamp for this error.
1421
1422 @param transient_errno_arg The number of the transient error in this
1423 transaction.
1424 @param transient_err_message_arg The message of this transient error.
1425 @param trans_retries_arg The number of times this transaction has
1426 been retried.
1427 */
1428 void store_transient_error(uint transient_errno_arg,
1429 const char *transient_err_message_arg,
1430 ulong trans_retries_arg);
1431};
1432
1433/**
1434 Represents a set of GTIDs.
1435
1436 This is structured as an array, indexed by SIDNO, where each element
1437 contains a linked list of intervals.
1438
1439 This data structure OPTIONALLY knows of a Sid_map that gives a
1440 correspondence between SIDNO and SID. If the Sid_map is NULL, then
1441 operations that require a Sid_map - printing and parsing - raise an
1442 assertion.
1443
1444 This data structure OPTIONALLY knows of a read-write lock that
1445 protects the number of SIDNOs. The lock is provided by the invoker
1446 of the constructor and it is generally the caller's responsibility
1447 to acquire the read lock. If the lock is not NULL, access methods
1448 assert that the caller already holds the read (or write) lock. If
1449 the lock is not NULL and a method of this class grows the number of
1450 SIDNOs, then the method temporarily upgrades this lock to a write
1451 lock and then degrades it to a read lock again; there will be a
1452 short period when the lock is not held at all.
1453*/
1455 public:
1457 /**
1458 Constructs a new, empty Gtid_set.
1459
1460 @param sid_map The Sid_map to use, or NULL if this Gtid_set
1461 should not have a Sid_map.
1462 @param sid_lock Read-write lock that protects updates to the
1463 number of SIDs. This may be NULL if such changes do not need to be
1464 protected.
1465 */
1467 /**
1468 Constructs a new Gtid_set that contains the gtids in the given
1469 string, in the same format as add_gtid_text(char *).
1470
1471 @param sid_map The Sid_map to use for SIDs.
1472 @param text The text to parse.
1473 @param status Will be set to RETURN_STATUS_OK on success or
1474 RETURN_STATUS_REPORTED_ERROR on error.
1475 @param sid_lock Read/write lock to protect changes in the number
1476 of SIDs with. This may be NULL if such changes do not need to be
1477 protected.
1478 If sid_lock != NULL, then the read lock on sid_lock must be held
1479 before calling this function. If the array is grown, sid_lock is
1480 temporarily upgraded to a write lock and then degraded again;
1481 there will be a short period when the lock is not held at all.
1482 */
1483 Gtid_set(Sid_map *sid_map, const char *text, enum_return_status *status,
1484 Checkable_rwlock *sid_lock = nullptr);
1485
1486 private:
1487 /// Worker for the constructor.
1488 void init();
1489
1490 public:
1491 /// Destroy this Gtid_set.
1492 ~Gtid_set();
1493 /**
1494 Removes all gtids from this Gtid_set.
1495
1496 This does not deallocate anything: if gtids are added later,
1497 existing allocated memory will be re-used.
1498 */
1499 void clear();
1500 /**
1501 Removes all gtids from this Gtid_set and clear all the sidnos
1502 used by the Gtid_set and it's SID map.
1503
1504 This does not deallocate anything: if gtids are added later,
1505 existing allocated memory will be re-used.
1506 */
1507 void clear_set_and_sid_map();
1508 /**
1509 Adds the given GTID to this Gtid_set.
1510
1511 The SIDNO must exist in the Gtid_set before this function is called.
1512
1513 @param sidno SIDNO of the GTID to add.
1514 @param gno GNO of the GTID to add.
1515 */
1516 void _add_gtid(rpl_sidno sidno, rpl_gno gno) {
1517 DBUG_TRACE;
1518 assert(sidno > 0);
1519 assert(gno > 0);
1520 assert(gno < GNO_END);
1521 Interval_iterator ivit(this, sidno);
1523 add_gno_interval(&ivit, gno, gno + 1, &lock);
1524 return;
1525 }
1526 /**
1527 Removes the given GTID from this Gtid_set.
1528
1529 @param sidno SIDNO of the GTID to remove.
1530 @param gno GNO of the GTID to remove.
1531 */
1532 void _remove_gtid(rpl_sidno sidno, rpl_gno gno) {
1533 DBUG_TRACE;
1534 if (sidno <= get_max_sidno()) {
1535 Interval_iterator ivit(this, sidno);
1537 remove_gno_interval(&ivit, gno, gno + 1, &lock);
1538 }
1539 return;
1540 }
1541 /**
1542 Adds the given GTID to this Gtid_set.
1543
1544 The SIDNO must exist in the Gtid_set before this function is called.
1545
1546 @param gtid Gtid to add.
1547 */
1548 void _add_gtid(const Gtid &gtid) { _add_gtid(gtid.sidno, gtid.gno); }
1549 /**
1550 Removes the given GTID from this Gtid_set.
1551
1552 @param gtid Gtid to remove.
1553 */
1554 void _remove_gtid(const Gtid &gtid) { _remove_gtid(gtid.sidno, gtid.gno); }
1555 /**
1556 Adds all gtids from the given Gtid_set to this Gtid_set.
1557
1558 If sid_lock != NULL, then the read lock must be held before
1559 calling this function. If a new sidno is added so that the array
1560 of lists of intervals is grown, sid_lock is temporarily upgraded
1561 to a write lock and then degraded again; there will be a short
1562 period when the lock is not held at all.
1563
1564 @param other The Gtid_set to add.
1565 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
1566 */
1568 /**
1569 Removes all gtids in the given Gtid_set from this Gtid_set.
1570
1571 @param other The Gtid_set to remove.
1572 */
1573 void remove_gtid_set(const Gtid_set *other);
1574 /**
1575 Removes all intervals of 'other' for a given SIDNO, from 'this'.
1576
1577 Example:
1578 this = A:1-100, B:1-100
1579 other = A:1-100, B:1-50, C:1-100
1580 this.remove_intervals_for_sidno(other, B) = A:1-100, B:51-100
1581
1582 It is not required that the intervals exist in this Gtid_set.
1583
1584 @param other The set to remove.
1585 @param sidno The sidno to remove.
1586 */
1587 void remove_intervals_for_sidno(Gtid_set *other, rpl_sidno sidno);
1588 /**
1589 Adds the set of GTIDs represented by the given string to this Gtid_set.
1590
1591 The string must have the format of a comma-separated list of zero
1592 or more of the following items:
1593
1594 XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX(:NUMBER+(-NUMBER)?)*
1595 | ANONYMOUS
1596
1597 Each X is a hexadecimal digit (upper- or lowercase).
1598 NUMBER is a decimal, 0xhex, or 0oct number.
1599
1600 The start of an interval must be greater than 0. The end of an
1601 interval may be 0, but any interval that has an endpoint that
1602 is smaller than the start is discarded.
1603
1604 The string can start with an optional '+' appender qualifier
1605 which triggers @c executed_gtids and @c lost_gtids set examination
1606 on the matter of disjointness with the one being added.
1607
1608 If sid_lock != NULL, then the read lock on sid_lock must be held
1609 before calling this function. If a new sidno is added so that the
1610 array of lists of intervals is grown, sid_lock is temporarily
1611 upgraded to a write lock and then degraded again; there will be a
1612 short period when the lock is not held at all.
1613
1614 @param text The string to parse.
1615 @param [in,out] anonymous If this is NULL, ANONYMOUS is not
1616 allowed. If this is not NULL, it will be set to true if the
1617 anonymous GTID was found; false otherwise.
1618 @param[in,out] starts_with_plus If this is not NULL, the string may
1619 optionally begin with a '+' character, and *starts_with_plus will
1620 be set to true if the plus character is present. If this is NULL,
1621 no plus is allowed at the begin of the string.
1622
1623 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
1624 */
1625 enum_return_status add_gtid_text(const char *text, bool *anonymous = nullptr,
1626 bool *starts_with_plus = nullptr);
1627 /**
1628 Decodes a Gtid_set from the given string.
1629
1630 @param encoded The string to parse.
1631 @param length The number of bytes.
1632 @param actual_length If this is not NULL, it is set to the number
1633 of bytes used by the encoding (which may be less than 'length').
1634 If this is NULL, an error is generated if the encoding is shorter
1635 than the given 'length'.
1636 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
1637 */
1638 enum_return_status add_gtid_encoding(const uchar *encoded, size_t length,
1639 size_t *actual_length = nullptr);
1640 /// Return true iff the given GTID exists in this set.
1641 bool contains_gtid(rpl_sidno sidno, rpl_gno gno) const;
1642 /// Return true iff the given GTID exists in this set.
1643 bool contains_gtid(const Gtid &gtid) const {
1644 return contains_gtid(gtid.sidno, gtid.gno);
1645 }
1646 // Get last gno or 0 if this set is empty.
1647 rpl_gno get_last_gno(rpl_sidno sidno) const;
1648 /// Returns the maximal sidno that this Gtid_set currently has space for.
1651 return static_cast<rpl_sidno>(m_intervals.size());
1652 }
1653 /**
1654 Allocates space for all sidnos up to the given sidno in the array of
1655 intervals. The sidno must exist in the Sid_map associated with this
1656 Gtid_set.
1657
1658 If sid_lock != NULL, then the read lock on sid_lock must be held
1659 before calling this function. If the array is grown, sid_lock is
1660 temporarily upgraded to a write lock and then degraded again;
1661 there will be a short period when the lock is not held at all.
1662
1663 @param sidno The SIDNO.
1664 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
1665 */
1667 /// Returns true if this Gtid_set is a subset of the other Gtid_set.
1668 bool is_subset(const Gtid_set *super) const;
1669 /// Returns true if this Gtid_set is a non equal subset of the other Gtid_set.
1670 bool is_subset_not_equals(const Gtid_set *super) const {
1671 return (is_subset(super) && !equals(super));
1672 }
1673
1674 /**
1675 Returns true if this Gtid_set is a subset of the given gtid_set
1676 on the given superset_sidno and subset_sidno.
1677
1678 @param super Gtid_set with which this->gtid_set needs to be
1679 compared
1680 @param superset_sidno The sidno that will be compared, relative to
1681 super->sid_map.
1682 @param subset_sidno The sidno that will be compared, relative to
1683 this->sid_map.
1684 @return true If 'this' Gtid_set is subset of given
1685 'super' Gtid_set.
1686 false If 'this' Gtid_set is *not* subset of given
1687 'super' Gtid_set.
1688 */
1689 bool is_subset_for_sid(const Gtid_set *super, rpl_sidno superset_sidno,
1690 rpl_sidno subset_sidno) const;
1691 /// Returns true if there is a least one element of this Gtid_set in
1692 /// the other Gtid_set.
1693 bool is_intersection_nonempty(const Gtid_set *other) const;
1694 /**
1695 Add the intersection of this Gtid_set and the other Gtid_set to result.
1696
1697 @param other The Gtid_set to intersect with this Gtid_set
1698 @param result Gtid_set where the result will be stored.
1699 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
1700 */
1702 /// Returns true if this Gtid_set is empty.
1703 bool is_empty() const {
1704 Gtid_iterator git(this);
1705 return git.get().sidno == 0;
1706 }
1707
1708 /**
1709 Return true if the size of the set is greater than or equal to the given
1710 number. The size is measure in number of GTIDs, i.e., total length of all
1711 intervals.
1712
1713 @param num Number to compare with
1714 @retval true if the set contains >= num GTIDs.
1715 @retval false if the set contains < num GTIDs.
1716 */
1718
1719 /**
1720 What is the count of all the GTIDs in all intervals for a sidno
1721
1722 @param sidno The sidno that contains the intervals
1723
1724 @return the number of all GTIDs in all intervals
1725 */
1727 Const_interval_iterator ivit(this, sidno);
1728 ulonglong ret = 0;
1729 while (ivit.get() != nullptr) {
1730 ret += ivit.get()->end - ivit.get()->start;
1731 ivit.next();
1732 }
1733 return ret;
1734 }
1735
1736 /**
1737 Returns true if this Gtid_set contains at least one GTID with
1738 the given SIDNO.
1739
1740 @param sidno The SIDNO to test.
1741 @retval true The SIDNO is less than or equal to the max SIDNO, and
1742 there is at least one GTID with this SIDNO.
1743 @retval false The SIDNO is greater than the max SIDNO, or there is
1744 no GTID with this SIDNO.
1745 */
1746 bool contains_sidno(rpl_sidno sidno) const {
1747 assert(sidno >= 1);
1748 if (sidno > get_max_sidno()) return false;
1749 Const_interval_iterator ivit(this, sidno);
1750 return ivit.get() != nullptr;
1751 }
1752 /**
1753 Returns true if the given string is a valid specification of a
1754 Gtid_set, false otherwise.
1755 */
1756 static bool is_valid(const char *text);
1757
1758 /**
1759 Class Gtid_set::String_format defines the separators used by
1760 Gtid_set::to_string.
1761 */
1763 /// The generated string begins with this.
1764 const char *begin;
1765 /// The generated string begins with this.
1766 const char *end;
1767 /// In 'SID:GNO', this is the ':'
1769 /// In 'SID:GNO-GNO', this is the '-'
1771 /// In 'SID:GNO:GNO', this is the second ':'
1773 /// In 'SID:GNO,SID:GNO', this is the ','
1775 /// If the set is empty and this is not NULL, then this string is generated.
1776 const char *empty_set_string;
1777 /// The following fields are the lengths of each field above.
1778 const int begin_length;
1779 const int end_length;
1785 };
1786 /**
1787 Returns the length of the output from to_string.
1788
1789 @warning This does not include the trailing '\0', so your buffer
1790 needs space for get_string_length() + 1 characters.
1791
1792 @param string_format String_format object that specifies
1793 separators in the resulting text.
1794 @return The length.
1795 */
1796 size_t get_string_length(const String_format *string_format = nullptr) const;
1797 /**
1798 Formats this Gtid_set as a string and saves in a given buffer.
1799
1800 @param[out] buf Pointer to the buffer where the string should be
1801 stored. This should have size at least get_string_length()+1.
1802 @param need_lock If this Gtid_set has a sid_lock, then the write
1803 lock must be held while generating the string. If this parameter
1804 is true, then this function acquires and releases the lock;
1805 otherwise it asserts that the caller holds the lock.
1806 @param string_format String_format object that specifies
1807 separators in the resulting text.
1808 @return Length of the generated string.
1809 */
1810 size_t to_string(char *buf, bool need_lock = false,
1811 const String_format *string_format = nullptr) const;
1812
1813 /**
1814 Formats a Gtid_set as a string and saves in a newly allocated buffer.
1815 @param[out] buf Pointer to pointer to string. The function will
1816 set it to point to the newly allocated buffer, or NULL on out of memory.
1817 @param need_lock If this Gtid_set has a sid_lock, then the write
1818 lock must be held while generating the string. If this parameter
1819 is true, then this function acquires and releases the lock;
1820 otherwise it asserts that the caller holds the lock.
1821 @param string_format Specifies how to format the string.
1822 @retval Length of the generated string, or -1 on out of memory.
1823 */
1824 long to_string(char **buf, bool need_lock = false,
1825 const String_format *string_format = nullptr) const;
1826#ifndef NDEBUG
1827 /// Debug only: Print this Gtid_set to stdout.
1828
1829 /// For use with C `printf`
1830 void print(bool need_lock = false,
1831 const Gtid_set::String_format *sf = nullptr) const {
1832 char *str;
1833 to_string(&str, need_lock, sf);
1834 printf("%s\n", str ? str : "out of memory in Gtid_set::print");
1835 my_free(str);
1836 }
1837
1838 /// For use with C++ `std::ostream`
1839 inline friend std::ostream &operator<<(std::ostream &os, const Gtid_set &in) {
1840 char *str;
1841 in.to_string(&str, true, nullptr);
1842 os << std::string(str) << std::flush;
1843 my_free(str);
1844 return os;
1845 }
1846#endif
1847 /**
1848 Print this Gtid_set to the trace file if debug is enabled; no-op
1849 otherwise.
1850 */
1851 void dbug_print(const char *text [[maybe_unused]] = "",
1852 bool need_lock [[maybe_unused]] = false,
1853 const Gtid_set::String_format *sf
1854 [[maybe_unused]] = nullptr) const {
1855#ifndef NDEBUG
1856 char *str;
1857 to_string(&str, need_lock, sf);
1858 DBUG_PRINT("info", ("%s%s'%s'", text, *text ? ": " : "",
1859 str ? str : "out of memory in Gtid_set::dbug_print"));
1860 my_free(str);
1861#endif
1862 }
1863 /**
1864 Gets all gtid intervals from this Gtid_set.
1865
1866 @param[out] gtid_intervals Store all gtid intervals from this Gtid_set.
1867 */
1868 void get_gtid_intervals(std::list<Gtid_interval> *gtid_intervals) const;
1869 /**
1870 The default String_format: the format understood by
1871 add_gtid_text(const char *).
1872 */
1874 /**
1875 String_format useful to generate an SQL string: the string is
1876 wrapped in single quotes and there is a newline between SIDs.
1877 */
1879 /**
1880 String_format for printing the Gtid_set commented: the string is
1881 not quote-wrapped, and every SID is on a new line with a leading '# '.
1882 */
1884
1885 /// Return the Sid_map associated with this Gtid_set.
1886 Sid_map *get_sid_map() const { return sid_map; }
1887
1888 /**
1889 Represents one element in the linked list of intervals associated
1890 with a SIDNO.
1891 */
1892 struct Interval {
1893 public:
1894 /// The first GNO of this interval.
1896 /// The first GNO after this interval.
1898 /// Return true iff this interval is equal to the given interval.
1899 bool equals(const Interval &other) const {
1900 return start == other.start && end == other.end;
1901 }
1902 /// Pointer to next interval in list.
1904 };
1905
1906 /**
1907 Provides an array of Intervals that this Gtid_set can use when
1908 gtids are subsequently added. This can be used as an
1909 optimization, to reduce allocation for sets that have a known
1910 number of intervals.
1911
1912 @param n_intervals The number of intervals to add.
1913 @param intervals_param Array of n_intervals intervals.
1914 */
1915 void add_interval_memory(int n_intervals, Interval *intervals_param) {
1917 add_interval_memory_lock_taken(n_intervals, intervals_param);
1919 }
1920
1921 /**
1922 Iterator over intervals for a given SIDNO.
1923
1924 This is an abstract template class, used as a common base class
1925 for Const_interval_iterator and Interval_iterator.
1926
1927 The iterator always points to an interval pointer. The interval
1928 pointer is either the initial pointer into the list, or the next
1929 pointer of one of the intervals in the list.
1930 */
1931 template <typename Gtid_set_p, typename Interval_p>
1933 public:
1934 /**
1935 Construct a new iterator over the GNO intervals for a given Gtid_set.
1936
1937 @param gtid_set The Gtid_set.
1938 @param sidno The SIDNO.
1939 */
1940 Interval_iterator_base(Gtid_set_p gtid_set, rpl_sidno sidno) {
1941 assert(sidno >= 1 && sidno <= gtid_set->get_max_sidno());
1942 init(gtid_set, sidno);
1943 }
1944 /// Construct a new iterator over the free intervals of a Gtid_set.
1945 Interval_iterator_base(Gtid_set_p gtid_set) {
1946 p = const_cast<Interval_p *>(&gtid_set->free_intervals);
1947 }
1948 /// Reset this iterator.
1949 inline void init(Gtid_set_p gtid_set, rpl_sidno sidno) {
1950 p = const_cast<Interval_p *>(&gtid_set->m_intervals[sidno - 1]);
1951 }
1952 /// Advance current_elem one step.
1953 inline void next() {
1954 assert(*p != nullptr);
1955 p = const_cast<Interval_p *>(&(*p)->next);
1956 }
1957 /// Return current_elem.
1958 inline Interval_p get() const { return *p; }
1959
1960 protected:
1961 /**
1962 Holds the address of the 'next' pointer of the previous element,
1963 or the address of the initial pointer into the list, if the
1964 current element is the first element.
1965 */
1966 Interval_p *p;
1967 };
1968
1969 /**
1970 Iterator over intervals of a const Gtid_set.
1971 */
1973 : public Interval_iterator_base<const Gtid_set *, const Interval *> {
1974 public:
1975 /// Create this Const_interval_iterator.
1977 : Interval_iterator_base<const Gtid_set *, const Interval *>(gtid_set,
1978 sidno) {}
1979 /// Create this Const_interval_iterator.
1981 : Interval_iterator_base<const Gtid_set *, const Interval *>(gtid_set) {
1982 }
1983 };
1984
1985 /**
1986 Iterator over intervals of a non-const Gtid_set, with additional
1987 methods to modify the Gtid_set.
1988 */
1990 : public Interval_iterator_base<Gtid_set *, Interval *> {
1991 public:
1992 /// Create this Interval_iterator.
1994 : Interval_iterator_base<Gtid_set *, Interval *>(gtid_set, sidno) {}
1995 /// Destroy this Interval_iterator.
1997 : Interval_iterator_base<Gtid_set *, Interval *>(gtid_set) {}
1998
1999 private:
2000 /**
2001 Set current_elem to the given Interval but do not touch the
2002 next pointer of the given Interval.
2003 */
2004 inline void set(Interval *iv) { *p = iv; }
2005 /// Insert the given element before current_elem.
2006 inline void insert(Interval *iv) {
2007 iv->next = *p;
2008 set(iv);
2009 }
2010 /// Remove current_elem.
2011 inline void remove(Gtid_set *gtid_set) {
2012 assert(get() != nullptr);
2013 Interval *next = (*p)->next;
2014 gtid_set->put_free_interval(*p);
2015 set(next);
2016 }
2017 /**
2018 Only Gtid_set is allowed to use set/insert/remove.
2019
2020 They are not safe to use from other code because: (1) very easy
2021 to make a mistakes (2) they don't clear cached_string_format or
2022 cached_string_length.
2023 */
2024 friend class Gtid_set;
2025 };
2026
2027 /**
2028 Iterator over all gtids in a Gtid_set. This is a const
2029 iterator; it does not allow modification of the Gtid_set.
2030 */
2032 public:
2033 Gtid_iterator(const Gtid_set *gs) : gtid_set(gs), sidno(0), ivit(gs) {
2034 if (gs->sid_lock != nullptr) gs->sid_lock->assert_some_wrlock();
2035 next_sidno();
2036 }
2037 /// Advance to next gtid.
2038 inline void next() {
2039 assert(gno > 0 && sidno > 0);
2040 // go to next GTID in current interval
2041 gno++;
2042 // end of interval? then go to next interval for this sidno
2043 if (gno == ivit.get()->end) {
2044 ivit.next();
2045 const Interval *iv = ivit.get();
2046 // last interval for this sidno? then go to next sidno
2047 if (iv == nullptr) {
2048 next_sidno();
2049 // last sidno? then don't try more
2050 if (sidno == 0) return;
2051 iv = ivit.get();
2052 }
2053 gno = iv->start;
2054 }
2055 }
2056 /// Return next gtid, or {0,0} if we reached the end.
2057 inline Gtid get() const {
2058 Gtid ret = {sidno, gno};
2059 return ret;
2060 }
2061
2062 private:
2063 /// Find the next sidno that has one or more intervals.
2064 inline void next_sidno() {
2065 const Interval *iv;
2066 do {
2067 sidno++;
2068 if (sidno > gtid_set->get_max_sidno()) {
2069 sidno = 0;
2070 gno = 0;
2071 return;
2072 }
2074 iv = ivit.get();
2075 } while (iv == nullptr);
2076 gno = iv->start;
2077 }
2078 /// The Gtid_set we iterate over.
2080 /**
2081 The SIDNO of the current element, or 0 if the iterator is past
2082 the last element.
2083 */
2085 /**
2086 The GNO of the current element, or 0 if the iterator is past the
2087 last element.
2088 */
2090 /// Iterator over the intervals for the current SIDNO.
2092 };
2093
2094 public:
2095 /**
2096 Encodes this Gtid_set as a binary string.
2097 */
2098 void encode(uchar *buf) const;
2099 /**
2100 Returns the length of this Gtid_set when encoded using the
2101 encode() function.
2102 */
2103 size_t get_encoded_length() const;
2104
2105 private:
2106 /**
2107 Contains a list of intervals allocated by this Gtid_set. When a
2108 method of this class needs a new interval and there are no more
2109 free intervals, a new Interval_chunk is allocated and the
2110 intervals of it are added to the list of free intervals.
2111 */
2115 };
2116 /// The default number of intervals in an Interval_chunk.
2117 static const int CHUNK_GROW_SIZE = 8;
2118
2119 /**
2120 Return true if the given sidno of this Gtid_set contains the same
2121 intervals as the given sidno of the other Gtid_set.
2122
2123 @param sidno SIDNO to check for this Gtid_set.
2124 @param other Other Gtid_set
2125 @param other_sidno SIDNO to check in other.
2126 @return true if equal, false is not equal.
2127 */
2128 bool sidno_equals(rpl_sidno sidno, const Gtid_set *other,
2129 rpl_sidno other_sidno) const;
2130 /// Returns true if this Gtid_set is equal to the other Gtid_set.
2131 bool equals(const Gtid_set *other) const;
2132
2133 /// Return the number of intervals for the given sidno.
2134 int get_n_intervals(rpl_sidno sidno) const {
2135 Const_interval_iterator ivit(this, sidno);
2136 int ret = 0;
2137 while (ivit.get() != nullptr) {
2138 ret++;
2139 ivit.next();
2140 }
2141 return ret;
2142 }
2143 /// Return the number of intervals in this Gtid_set.
2144 int get_n_intervals() const {
2145 if (sid_lock != nullptr) sid_lock->assert_some_wrlock();
2146 rpl_sidno max_sidno = get_max_sidno();
2147 int ret = 0;
2148 for (rpl_sidno sidno = 1; sidno < max_sidno; sidno++)
2149 ret += get_n_intervals(sidno);
2150 return ret;
2151 }
2152 /**
2153 Allocates a new chunk of Intervals and adds them to the list of
2154 unused intervals.
2155
2156 @param size The number of intervals in this chunk
2157 */
2158 void create_new_chunk(int size);
2159 /**
2160 Returns a fresh new Interval object.
2161
2162 This usually does not require any real allocation, it only pops
2163 the first interval from the list of free intervals. If there are
2164 no free intervals, it calls create_new_chunk.
2165
2166 @param out The resulting Interval* will be stored here.
2167 */
2168 void get_free_interval(Interval **out);
2169 /**
2170 Puts the given interval in the list of free intervals. Does not
2171 unlink it from its place in any other list.
2172 */
2173 void put_free_interval(Interval *iv);
2174 /**
2175 Like add_interval_memory, but does not acquire
2176 free_intervals_mutex.
2177 @see Gtid_set::add_interval_memory
2178 */
2179 void add_interval_memory_lock_taken(int n_ivs, Interval *ivs);
2180
2181 /// Read-write lock that protects updates to the number of SIDs.
2183 /**
2184 Lock protecting the list of free intervals. This lock is only
2185 used if sid_lock is not NULL.
2186 */
2188 /**
2189 Class representing a lock on free_intervals_mutex.
2190
2191 This is used by the add_* and remove_* functions. The lock is
2192 declared by the top-level function and a pointer to the lock is
2193 passed down to low-level functions. If the low-level function
2194 decides to access the free intervals list, then it acquires the
2195 lock. The lock is then automatically released by the destructor
2196 when the top-level function returns.
2197
2198 The lock is not taken if Gtid_set->sid_lock == NULL; such
2199 Gtid_sets are assumed to be thread-local.
2200 */
2202 public:
2203 /// Create a new lock, but do not acquire it.
2205 : gtid_set(_gtid_set), locked(false) {}
2206 /// Lock the lock if it is not already locked.
2208 if (gtid_set->sid_lock && !locked) {
2210 locked = true;
2211 }
2212 }
2213 /// Lock the lock if it is locked.
2215 if (gtid_set->sid_lock && locked) {
2217 locked = false;
2218 }
2219 }
2220 /// Destroy this object and unlock the lock if it is locked.
2222
2223 private:
2226 };
2229 }
2230
2231 /**
2232 Adds the interval (start, end) to the given Interval_iterator.
2233
2234 This is the lowest-level function that adds gtids; this is where
2235 Interval objects are added, grown, or merged.
2236
2237 @param ivitp Pointer to iterator. After this function returns,
2238 the current_element of the iterator will be the interval that
2239 contains start and end.
2240 @param start The first GNO in the interval.
2241 @param end The first GNO after the interval.
2242 @param lock If this function has to add or remove an interval,
2243 then this lock will be taken unless it is already taken. This
2244 mechanism means that the lock will be taken lazily by
2245 e.g. add_gtid_set() the first time that the list of free intervals
2246 is accessed, and automatically released when add_gtid_set()
2247 returns.
2248 */
2249 void add_gno_interval(Interval_iterator *ivitp, rpl_gno start, rpl_gno end,
2250 Free_intervals_lock *lock);
2251 /**
2252 Removes the interval (start, end) from the given
2253 Interval_iterator. This is the lowest-level function that removes
2254 gtids; this is where Interval objects are removed, truncated, or
2255 split.
2256
2257 It is not required that the gtids in the interval exist in this
2258 Gtid_set.
2259
2260 @param ivitp Pointer to iterator. After this function returns,
2261 the current_element of the iterator will be the next interval
2262 after end.
2263 @param start The first GNO in the interval.
2264 @param end The first GNO after the interval.
2265 @param lock If this function has to add or remove an interval,
2266 then this lock will be taken unless it is already taken. This
2267 mechanism means that the lock will be taken lazily by
2268 e.g. add_gtid_set() the first time that the list of free intervals
2269 is accessed, and automatically released when add_gtid_set()
2270 returns.
2271 */
2272 void remove_gno_interval(Interval_iterator *ivitp, rpl_gno start, rpl_gno end,
2273 Free_intervals_lock *lock);
2274 /**
2275 Adds a list of intervals to the given SIDNO.
2276
2277 The SIDNO must exist in the Gtid_set before this function is called.
2278
2279 @param sidno The SIDNO to which intervals will be added.
2280 @param ivit Iterator over the intervals to add. This is typically
2281 an iterator over some other Gtid_set.
2282 @param lock If this function has to add or remove an interval,
2283 then this lock will be taken unless it is already taken. This
2284 mechanism means that the lock will be taken lazily by
2285 e.g. add_gtid_set() the first time that the list of free intervals
2286 is accessed, and automatically released when add_gtid_set()
2287 returns.
2288 */
2289 void add_gno_intervals(rpl_sidno sidno, Const_interval_iterator ivit,
2290 Free_intervals_lock *lock);
2291 /**
2292 Removes a list of intervals from the given SIDNO.
2293
2294 It is not required that the intervals exist in this Gtid_set.
2295
2296 @param sidno The SIDNO from which intervals will be removed.
2297 @param ivit Iterator over the intervals to remove. This is typically
2298 an iterator over some other Gtid_set.
2299 @param lock If this function has to add or remove an interval,
2300 then this lock will be taken unless it is already taken. This
2301 mechanism means that the lock will be taken lazily by
2302 e.g. add_gtid_set() the first time that the list of free intervals
2303 is accessed, and automatically released when add_gtid_set()
2304 returns.
2305 */
2306 void remove_gno_intervals(rpl_sidno sidno, Const_interval_iterator ivit,
2307 Free_intervals_lock *lock);
2308
2309 /// Returns true if every interval of sub is a subset of some
2310 /// interval of super.
2311 static bool is_interval_subset(Const_interval_iterator *sub,
2312 Const_interval_iterator *super);
2313 /// Returns true if at least one sidno in ivit1 is also in ivit2.
2314 static bool is_interval_intersection_nonempty(Const_interval_iterator *ivit1,
2315 Const_interval_iterator *ivit2);
2316
2317 /// Sid_map associated with this Gtid_set.
2319 /**
2320 Array where the N'th element contains the head pointer to the
2321 intervals of SIDNO N+1.
2322 */
2324 /// Linked list of free intervals.
2326 /// Linked list of chunks.
2328 /// If the string is cached.
2330 /// The string length.
2331 mutable size_t cached_string_length;
2332 /// The String_format that was used when cached_string_length was computed.
2334#ifndef NDEBUG
2335 /**
2336 The number of chunks. Used only to check some invariants when
2337 DBUG is on.
2338 */
2340#endif
2341 /// Used by unit tests that need to access private members.
2342#ifdef FRIEND_OF_GTID_SET
2343 friend FRIEND_OF_GTID_SET;
2344#endif
2345 /// Only Free_intervals_lock is allowed to access free_intervals_mutex.
2347};
2348
2349/**
2350 Holds information about a Gtid_set. Can also be NULL.
2351
2352 This is used as backend storage for @@session.gtid_next_list. The
2353 idea is that we allow the user to set this to NULL, but we keep the
2354 Gtid_set object so that we can re-use the allocated memory and
2355 avoid costly allocations later.
2356
2357 This is stored in struct system_variables (defined in sql_class.h),
2358 which is cleared using memset(0); hence the negated form of
2359 is_non_null.
2360
2361 The convention is: if is_non_null is false, then the value of the
2362 session variable is NULL, and the field gtid_set may be NULL or
2363 non-NULL. If is_non_null is true, then the value of the session
2364 variable is not NULL, and the field gtid_set has to be non-NULL.
2365
2366 This is a POD. It has to be a POD because it is stored in
2367 THD::variables.
2368*/
2370 /// Pointer to the Gtid_set.
2372 /// True if this Gtid_set is NULL.
2374 /// Return NULL if this is NULL, otherwise return the Gtid_set.
2375 inline Gtid_set *get_gtid_set() const {
2376 assert(!(is_non_null && gtid_set == nullptr));
2377 return is_non_null ? gtid_set : nullptr;
2378 }
2379 /**
2380 Do nothing if this object is non-null; set to empty set otherwise.
2381
2382 @return NULL if out of memory; Gtid_set otherwise.
2383 */
2385 if (!is_non_null) {
2386 if (gtid_set == nullptr)
2387 gtid_set = new Gtid_set(sm);
2388 else
2389 gtid_set->clear();
2390 }
2391 is_non_null = (gtid_set != nullptr);
2392 return gtid_set;
2393 }
2394 /// Set this Gtid_set to NULL.
2395 inline void set_null() { is_non_null = false; }
2396};
2397
2398/**
2399 Represents the set of GTIDs that are owned by some thread.
2400
2401 This data structure has a read-write lock that protects the number
2402 of SIDNOs. The lock is provided by the invoker of the constructor
2403 and it is generally the caller's responsibility to acquire the read
2404 lock. Access methods assert that the caller already holds the read
2405 (or write) lock. If a method of this class grows the number of
2406 SIDNOs, then the method temporarily upgrades this lock to a write
2407 lock and then degrades it to a read lock again; there will be a
2408 short period when the lock is not held at all.
2409
2410 The internal representation is a multi-valued map from GTIDs to
2411 threads, mapping GTIDs to one or more threads that owns it.
2412
2413 In Group Replication multiple threads can own a GTID whereas if GR
2414 is disabeld there is at most one owner per GTID.
2415*/
2417 public:
2418 /**
2419 Constructs a new, empty Owned_gtids object.
2420
2421 @param sid_lock Read-write lock that protects updates to the
2422 number of SIDs.
2423 */
2425 /// Destroys this Owned_gtids.
2426 ~Owned_gtids();
2427 /**
2428 Add a GTID to this Owned_gtids.
2429
2430 @param gtid The Gtid to add.
2431 @param owner The my_thread_id of the gtid to add.
2432 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
2433 */
2435
2436 /*
2437 Fill all gtids into the given Gtid_set object. It doesn't clear the given
2438 gtid set before filling its owned gtids into it.
2439 */
2440 void get_gtids(Gtid_set &gtid_set) const;
2441 /**
2442 Removes the given GTID.
2443
2444 If the gtid does not exist in this Owned_gtids object, does
2445 nothing.
2446
2447 @param gtid The Gtid.
2448 @param owner thread_id of the owner thread
2449 */
2450 void remove_gtid(const Gtid &gtid, const my_thread_id owner);
2451 /**
2452 Ensures that this Owned_gtids object can accommodate SIDNOs up to
2453 the given SIDNO.
2454
2455 If this Owned_gtids object needs to be resized, then the lock
2456 will be temporarily upgraded to a write lock and then degraded to
2457 a read lock again; there will be a short period when the lock is
2458 not held at all.
2459
2460 @param sidno The SIDNO.
2461 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
2462 */
2464 /// Returns true if there is a least one element of this Owned_gtids
2465 /// set in the other Gtid_set.
2466 bool is_intersection_nonempty(const Gtid_set *other) const;
2467 /// Returns true if this Owned_gtids is empty.
2468 bool is_empty() const {
2469 Gtid_iterator git(this);
2470 return git.get().sidno == 0;
2471 }
2472 /// Returns the maximal sidno that this Owned_gtids currently has space for.
2475 return static_cast<rpl_sidno>(sidno_to_hash.size());
2476 }
2477
2478 /**
2479 Write a string representation of this Owned_gtids to the given buffer.
2480
2481 @param out Buffer to write to.
2482 @return Number of characters written.
2483 */
2484 int to_string(char *out) const {
2485 char *p = out;
2486 rpl_sidno max_sidno = get_max_sidno();
2487 rpl_sidno sid_map_max_sidno = global_sid_map->get_max_sidno();
2488 for (rpl_sidno sid_i = 0; sid_i < sid_map_max_sidno; sid_i++) {
2490 if (sidno > max_sidno) continue;
2491 bool printed_sid = false;
2492 for (const auto &key_and_value : *get_hash(sidno)) {
2493 Node *node = key_and_value.second.get();
2494 assert(node != nullptr);
2495 if (!printed_sid) {
2497 printed_sid = true;
2498 }
2499 p += sprintf(p, ":%" PRId64 "#%u", node->gno, node->owner);
2500 }
2501 }
2502 *p = 0;
2503 return (int)(p - out);
2504 }
2505
2506 /**
2507 Return an upper bound on the length of the string representation
2508 of this Owned_gtids. The actual length may be smaller. This
2509 includes the trailing '\0'.
2510 */
2511 size_t get_max_string_length() const {
2512 rpl_sidno max_sidno = get_max_sidno();
2513 size_t ret = 0;
2514 for (rpl_sidno sidno = 1; sidno <= max_sidno; sidno++) {
2515 size_t records = get_hash(sidno)->size();
2516 if (records > 0)
2517 ret +=
2519 records * (1 + MAX_GNO_TEXT_LENGTH + 1 + MAX_THREAD_ID_TEXT_LENGTH);
2520 }
2521 return 1 + ret;
2522 }
2523
2524 /**
2525 Return true if the given thread is the owner of any gtids.
2526 */
2528 Gtid_iterator git(this);
2529 Node *node = git.get_node();
2530 while (node != nullptr) {
2531 if (node->owner == thd_id) return true;
2532 git.next();
2533 node = git.get_node();
2534 }
2535 return false;
2536 }
2537
2538#ifndef NDEBUG
2539 /**
2540 Debug only: return a newly allocated string representation of
2541 this Owned_gtids.
2542 */
2543 char *to_string() const {
2546 assert(str != nullptr);
2547 to_string(str);
2548 return str;
2549 }
2550 /// Debug only: print this Owned_gtids to stdout.
2551 void print() const {
2552 char *str = to_string();
2553 printf("%s\n", str);
2554 my_free(str);
2555 }
2556#endif
2557 /**
2558 Print this Owned_gtids to the trace file if debug is enabled; no-op
2559 otherwise.
2560 */
2561 void dbug_print(const char *text [[maybe_unused]] = "") const {
2562#ifndef NDEBUG
2563 char *str = to_string();
2564 DBUG_PRINT("info", ("%s%s%s", text, *text ? ": " : "", str));
2565 my_free(str);
2566#endif
2567 }
2568
2569 /**
2570 If thd_id==0, returns true when gtid is not owned by any thread.
2571 If thd_id!=0, returns true when gtid is owned by that thread.
2572 */
2573 bool is_owned_by(const Gtid &gtid, const my_thread_id thd_id) const;
2574
2575 private:
2576 /// Represents one owned GTID.
2577 struct Node {
2578 /// GNO of the GTID.
2580 /// Owner of the GTID.
2582 };
2583 /// Read-write lock that protects updates to the number of SIDs.
2585 /// Returns the hash for the given SIDNO.
2587 rpl_sidno sidno) const {
2588 assert(sidno >= 1 && sidno <= get_max_sidno());
2590 return sidno_to_hash[sidno - 1];
2591 }
2592 /// Return true iff this Owned_gtids object contains the given gtid.
2593 bool contains_gtid(const Gtid &gtid) const;
2594
2595 /// Growable array of hashes.
2599
2600 public:
2601 /**
2602 Iterator over all gtids in a Owned_gtids set. This is a const
2603 iterator; it does not allow modification of the set.
2604 */
2606 public:
2608 : owned_gtids(og), sidno(1), hash(nullptr), node(nullptr) {
2610 if (sidno <= max_sidno) {
2612 node_it = hash->begin();
2613 }
2614 next();
2615 }
2616 /// Advance to next GTID.
2617 inline void next() {
2618#ifndef NDEBUG
2620#endif
2621
2622 while (sidno <= max_sidno) {
2623 assert(hash != nullptr);
2624 if (node_it != hash->end()) {
2625 node = node_it->second.get();
2626 assert(node != nullptr);
2627 // Jump to next node on next iteration.
2628 ++node_it;
2629 return;
2630 }
2631
2632 // hash is initialized on constructor or in previous iteration
2633 // for current SIDNO, so we must increment for next iteration.
2634 sidno++;
2635 if (sidno <= max_sidno) {
2637 node_it = hash->begin();
2638 }
2639 }
2640 node = nullptr;
2641 }
2642 /// Return next GTID, or {0,0} if we reached the end.
2643 inline Gtid get() const {
2644 Gtid ret = {0, 0};
2645 if (node) {
2646 ret.sidno = sidno;
2647 ret.gno = node->gno;
2648 }
2649 return ret;
2650 }
2651 /// Return the current GTID Node, or NULL if we reached the end.
2652 inline Node *get_node() const { return node; }
2653
2654 private:
2655 /// The Owned_gtids set we iterate over.
2657 /// The SIDNO of the current element, or 1 in the initial iteration.
2659 /// Max SIDNO of the current iterator.
2661 /// Current SIDNO hash.
2663 /// Current node iterator on current SIDNO hash.
2666 /// Current node on current SIDNO hash.
2668 };
2669};
2670
2671/**
2672 Represents the server's GTID state: the set of committed GTIDs, the
2673 set of lost gtids, the set of owned gtids, the owner of each owned
2674 gtid, and a Mutex_cond_array that protects updates to gtids of
2675 each SIDNO.
2676
2677 Locking:
2678
2679 This data structure has a read-write lock that protects the number
2680 of SIDNOs, and a Mutex_cond_array that contains one mutex per SIDNO.
2681 The rwlock is always the global_sid_lock.
2682
2683 Access methods generally assert that the caller already holds the
2684 appropriate lock:
2685
2686 - before accessing any global data, hold at least the rdlock.
2687
2688 - before accessing a specific SIDNO in a Gtid_set or Owned_gtids
2689 (e.g., calling Gtid_set::_add_gtid(Gtid)), hold either the rdlock
2690 and the SIDNO's mutex lock; or the wrlock. If you need to hold
2691 multiple mutexes, they must be acquired in order of increasing
2692 SIDNO.
2693
2694 - before starting an operation that needs to access all SIDs
2695 (e.g. Gtid_set::to_string()), hold the wrlock.
2696
2697 The access type (read/write) does not matter; the write lock only
2698 implies that the entire data structure is locked whereas the read
2699 lock implies that everything except SID-specific data is locked.
2700*/
2702 public:
2703 /**
2704 Constructs a new Gtid_state object.
2705
2706 @param _sid_lock Read-write lock that protects updates to the
2707 number of SIDs.
2708 @param _sid_map Sid_map used by this Gtid_state.
2709 */
2710 Gtid_state(Checkable_rwlock *_sid_lock, Sid_map *_sid_map)
2711 : sid_lock(_sid_lock),
2712 sid_map(_sid_map),
2720 /**
2721 Add @@GLOBAL.SERVER_UUID to this binlog's Sid_map.
2722
2723 This can't be done in the constructor because the constructor is
2724 invoked at server startup before SERVER_UUID is initialized.
2725
2726 The caller must hold the read lock or write lock on sid_locks
2727 before invoking this function.
2728
2729 @retval 0 Success
2730 @retval 1 Error (out of memory or IO error).
2731 */
2732 int init();
2733 /**
2734 Reset the state and persistor after RESET MASTER: remove all logged
2735 and lost gtids, but keep owned gtids as they are.
2736
2737 The caller must hold the write lock on sid_lock before calling
2738 this function.
2739
2740 @param thd Thread requesting to reset the persistor
2741
2742 @retval 0 Success
2743 @retval -1 Error
2744 */
2745 int clear(THD *thd);
2746 /**
2747 Returns true if the given GTID is logged.
2748
2749 @param gtid The Gtid to check.
2750
2751 @retval true The gtid is logged in the binary log.
2752 @retval false The gtid is not logged in the binary log.
2753 */
2754 bool is_executed(const Gtid &gtid) const {
2755 DBUG_TRACE;
2757 bool ret = executed_gtids.contains_gtid(gtid);
2758 return ret;
2759 }
2760 /**
2761 Returns true if GTID is owned, otherwise returns 0.
2762
2763 @param gtid The Gtid to check.
2764 @return true if some thread owns the gtid, false if the gtid is
2765 not owned
2766 */
2767 bool is_owned(const Gtid &gtid) const {
2768 return !owned_gtids.is_owned_by(gtid, 0);
2769 }
2770#ifdef MYSQL_SERVER
2771 /**
2772 Acquires ownership of the given GTID, on behalf of the given thread.
2773
2774 The caller must lock the SIDNO before invoking this function.
2775
2776 @param thd The thread that will own the GTID.
2777 @param gtid The Gtid to acquire ownership of.
2778 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
2779 */
2780 enum_return_status acquire_ownership(THD *thd, const Gtid &gtid);
2781 /**
2782 This function updates both the THD and the Gtid_state to reflect that
2783 the transaction set of transactions has ended, and it does this for the
2784 whole commit group (by following the thd->next_to_commit pointer).
2785
2786 It will:
2787
2788 - Clean up the thread state when a thread owned GTIDs is empty.
2789 - Release ownership of all GTIDs owned by the THDs. This removes
2790 the GTIDs from Owned_gtids and clears the ownership status in the
2791 THDs object.
2792 - Add the owned GTIDs to executed_gtids when the thread is committing.
2793 - Decrease counters of GTID-violating transactions.
2794 - Send a broadcast on the condition variable for every sidno for
2795 which we released ownership.
2796
2797 @param first_thd The first thread of the group commit that needs GTIDs to
2798 be updated.
2799 */
2800 void update_commit_group(THD *first_thd);
2801 /**
2802 Remove the GTID owned by thread from owned GTIDs, stating that
2803 thd->owned_gtid was committed.
2804
2805 This will:
2806 - remove owned GTID from owned_gtids;
2807 - remove all owned GTIDS from thd->owned_gtid and thd->owned_gtid_set;
2808
2809 @param thd Thread for which owned gtids are updated.
2810 */
2811 void update_on_commit(THD *thd);
2812 /**
2813 Update the state after the given thread has rollbacked.
2814
2815 This will:
2816 - release ownership of all GTIDs owned by the THD;
2817 - remove owned GTID from owned_gtids;
2818 - remove all owned GTIDS from thd->owned_gtid and thd->owned_gtid_set;
2819 - send a broadcast on the condition variable for every sidno for
2820 which we released ownership.
2821
2822 @param thd Thread for which owned gtids are updated.
2823 */
2824 void update_on_rollback(THD *thd);
2825
2826 /**
2827 Acquire anonymous ownership.
2828
2829 The caller must hold either sid_lock.rdlock or
2830 sid_lock.wrlock. (The caller must have taken the lock and checked
2831 that gtid_mode!=ON before calling this function, or else the
2832 gtid_mode could have changed to ON by a concurrent SET GTID_MODE.)
2833 */
2835 DBUG_TRACE;
2837 assert(global_gtid_mode.get() != Gtid_mode::ON);
2838#ifndef NDEBUG
2839 int32 new_value =
2840#endif
2842 DBUG_PRINT("info",
2843 ("atomic_anonymous_gtid_count increased to %d", new_value));
2844 assert(new_value >= 1);
2845 return;
2846 }
2847
2848 /// Release anonymous ownership.
2850 DBUG_TRACE;
2852 assert(global_gtid_mode.get() != Gtid_mode::ON);
2853#ifndef NDEBUG
2854 int32 new_value =
2855#endif
2857 DBUG_PRINT("info",
2858 ("atomic_anonymous_gtid_count decreased to %d", new_value));
2859 assert(new_value >= 0);
2860 return;
2861 }
2862
2863 /// Return the number of clients that hold anonymous ownership.
2865
2866 /**
2867 Increase the global counter when starting a GTID-violating
2868 transaction having GTID_NEXT=AUTOMATIC.
2869 */
2871 DBUG_TRACE;
2874#ifndef NDEBUG
2875 int32 new_value =
2876#endif
2878 DBUG_PRINT(
2879 "info",
2880 ("ongoing_automatic_gtid_violating_transaction_count increased to %d",
2881 new_value));
2882 assert(new_value >= 1);
2883 return;
2884 }
2885
2886 /**
2887 Decrease the global counter when ending a GTID-violating
2888 transaction having GTID_NEXT=AUTOMATIC.
2889 */
2891 DBUG_TRACE;
2892#ifndef NDEBUG
2897 int32 new_value =
2898#endif
2900 DBUG_PRINT(
2901 "info",
2902 ("ongoing_automatic_gtid_violating_transaction_count decreased to %d",
2903 new_value));
2904 assert(new_value >= 0);
2905 return;
2906 }
2907
2908 /**
2909 Return the number of ongoing GTID-violating transactions having
2910 GTID_NEXT=AUTOMATIC.
2911 */
2914 }
2915
2916 /**
2917 Increase the global counter when starting a GTID-violating
2918 transaction having GTID_NEXT=ANONYMOUS.
2919 */
2921 DBUG_TRACE;
2922 assert(global_gtid_mode.get() != Gtid_mode::ON);
2924#ifndef NDEBUG
2925 int32 new_value =
2926#endif
2928 DBUG_PRINT("info", ("atomic_anonymous_gtid_violation_count increased to %d",
2929 new_value));
2930 assert(new_value >= 1);
2931 return;
2932 }
2933
2934 /**
2935 Decrease the global counter when ending a GTID-violating
2936 transaction having GTID_NEXT=ANONYMOUS.
2937 */
2939 DBUG_TRACE;
2940#ifndef NDEBUG
2942 assert(global_gtid_mode.get() != Gtid_mode::ON);
2945 int32 new_value =
2946#endif
2948 DBUG_PRINT(
2949 "info",
2950 ("ongoing_anonymous_gtid_violating_transaction_count decreased to %d",
2951 new_value));
2952 assert(new_value >= 0);
2953 return;
2954 }
2955
2957
2958 /**
2959 Return the number of ongoing GTID-violating transactions having
2960 GTID_NEXT=AUTOMATIC.
2961 */
2964 }
2965
2966 /**
2967 Increase the global counter when starting a call to
2968 WAIT_FOR_EXECUTED_GTID_SET or WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS.
2969 */
2971 DBUG_TRACE;
2972 assert(global_gtid_mode.get() != Gtid_mode::OFF);
2973#ifndef NDEBUG
2974 int32 new_value =
2975#endif
2977 DBUG_PRINT("info", ("atomic_gtid_wait_count changed from %d to %d",
2978 new_value - 1, new_value));
2979 assert(new_value >= 1);
2980 return;
2981 }
2982
2983 /**
2984 Decrease the global counter when ending a call to
2985 WAIT_FOR_EXECUTED_GTID_SET or WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS.
2986 */
2988 DBUG_TRACE;
2989 assert(global_gtid_mode.get() != Gtid_mode::OFF);
2990#ifndef NDEBUG
2991 int32 new_value =
2992#endif
2994 DBUG_PRINT("info", ("atomic_gtid_wait_count changed from %d to %d",
2995 new_value + 1, new_value));
2996 assert(new_value >= 0);
2997 return;
2998 }
2999
3000 /**
3001 Return the number of clients that have an ongoing call to
3002 WAIT_FOR_EXECUTED_GTID_SET or WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS.
3003 */
3005
3006#endif // ifdef MYSQL_SERVER
3007 /**
3008 Computes the next available GNO.
3009
3010 @param sidno The GTID's SIDNO.
3011
3012 @retval -1 The range of GNOs was exhausted (i.e., more than 1<<63-1
3013 GTIDs with the same UUID have been generated).
3014 @retval >0 The GNO for the GTID.
3015 */
3016 rpl_gno get_automatic_gno(rpl_sidno sidno) const;
3017
3018 private:
3019 /**
3020 The next_free_gno variable will be set with the supposed next free GNO
3021 every time a new GNO is delivered automatically or when a transaction is
3022 rolled back, releasing a GNO smaller than the last one delivered.
3023 It was introduced in an optimization of Gtid_state::get_automatic_gno and
3024 Gtid_state::generate_automatic_gtid functions.
3025
3026 Locking scheme
3027
3028 This variable can be read and modified in four places:
3029 - During server startup, holding global_sid_lock.wrlock;
3030 - By a client thread holding global_sid_lock.wrlock (doing a RESET MASTER);
3031 - By a client thread calling MYSQL_BIN_LOG::write_transaction function
3032 (often the group commit FLUSH stage leader). It will call
3033 Gtid_state::generate_automatic_gtid, that will acquire
3034 global_sid_lock.rdlock and lock_sidno(get_server_sidno()) when getting a
3035 new automatically generated GTID;
3036 - By a client thread rolling back, holding global_sid_lock.rdlock
3037 and lock_sidno(get_server_sidno()).
3038 */
3040
3041 public:
3042 /**
3043 Return the last executed GNO for a given SIDNO, e.g.
3044 for the following set: UUID:1-10, UUID:12, UUID:15-20
3045 20 will be returned.
3046
3047 @param sidno The GTID's SIDNO.
3048
3049 @retval The GNO or 0 if set is empty.
3050 */
3052 /**
3053 Generates the GTID (or ANONYMOUS, if GTID_MODE = OFF or
3054 OFF_PERMISSIVE) for the THD, and acquires ownership.
3055
3056 @param thd The thread.
3057 @param specified_sidno Externally generated sidno.
3058 @param specified_gno Externally generated gno.
3059 @param[in,out] locked_sidno This parameter should be used when there is
3060 a need of generating many GTIDs without having
3061 to acquire/release a sidno_lock many times.
3062 The caller must hold global_sid_lock and unlock
3063 the locked_sidno after invocation when
3064 locked_sidno > 0 if locked_sidno!=NULL.
3065 The caller must not hold global_sid_lock when
3066 locked_sidno==NULL.
3067 See comments on function code to more details.
3068
3069 @return RETURN_STATUS_OK or RETURN_STATUS_ERROR. Error can happen
3070 in case of out of memory or if the range of GNOs was exhausted.
3071 */
3073 rpl_sidno specified_sidno = 0,
3074 rpl_gno specified_gno = 0,
3075 rpl_sidno *locked_sidno = nullptr);
3076
3077 /// Locks a mutex for the given SIDNO.
3078 void lock_sidno(rpl_sidno sidno) { sid_locks.lock(sidno); }
3079 /// Unlocks a mutex for the given SIDNO.
3080 void unlock_sidno(rpl_sidno sidno) { sid_locks.unlock(sidno); }
3081 /// Broadcasts updates for the given SIDNO.
3083 /// Assert that we own the given SIDNO.
3085 sid_locks.assert_owner(sidno);
3086 }
3087#ifdef MYSQL_SERVER
3088 /**
3089 Wait for a signal on the given SIDNO.
3090
3091 NOTE: This releases a lock!
3092
3093 This requires that the caller holds a read lock on sid_lock. It
3094 will release the lock before waiting; neither global_sid_lock nor
3095 the mutex lock on SIDNO will not be held when this function
3096 returns.
3097
3098 @param thd THD object of the caller.
3099 @param sidno Sidno to wait for.
3100 @param[in] abstime The absolute point in time when the wait times
3101 out and stops, or NULL to wait indefinitely.
3102 @param[in] update_thd_status when true updates the stage info with
3103 the new wait condition, when false keeps the current stage info.
3104
3105 @retval false Success.
3106 @retval true Failure: either timeout or thread was killed. If
3107 thread was killed, the error has been generated.
3108 */
3109 bool wait_for_sidno(THD *thd, rpl_sidno sidno, struct timespec *abstime,
3110 bool update_thd_status = true);
3111 /**
3112 This is only a shorthand for wait_for_sidno, which contains
3113 additional debug printouts and assertions for the case when the
3114 caller waits for one specific GTID.
3115 */
3116 bool wait_for_gtid(THD *thd, const Gtid &gtid,
3117 struct timespec *abstime = nullptr);
3118 /**
3119 Wait until the given Gtid_set is included in @@GLOBAL.GTID_EXECUTED.
3120
3121 @param thd The calling thread.
3122 @param gtid_set Gtid_set to wait for.
3123 @param[in] timeout The maximum number of milliseconds that the
3124 function should wait, or 0 to wait indefinitely.
3125 @param[in] update_thd_status when true updates the stage info with
3126 the new wait condition, when false keeps the current stage info.
3127
3128 @retval false Success.
3129 @retval true Failure: either timeout or thread was killed. If
3130 thread was killed, the error has been generated.
3131 */
3132 bool wait_for_gtid_set(THD *thd, Gtid_set *gtid_set, double timeout,
3133 bool update_thd_status = true);
3134#endif // ifdef MYSQL_SERVER
3135 /**
3136 Locks one mutex for each SIDNO where the given Gtid_set has at
3137 least one GTID. Locks are acquired in order of increasing SIDNO.
3138 */
3139 void lock_sidnos(const Gtid_set *set);
3140 /**
3141 Unlocks the mutex for each SIDNO where the given Gtid_set has at
3142 least one GTID.
3143 */
3144 void unlock_sidnos(const Gtid_set *set);
3145 /**
3146 Broadcasts the condition variable for each SIDNO where the given
3147 Gtid_set has at least one GTID.
3148 */
3149 void broadcast_sidnos(const Gtid_set *set);
3150 /**
3151 Ensure that owned_gtids, executed_gtids, lost_gtids, gtids_only_in_table,
3152 previous_gtids_logged and sid_locks have room for at least as many SIDNOs
3153 as sid_map.
3154
3155 This function must only be called in one place:
3156 Sid_map::add_sid().
3157
3158 Requires that the write lock on sid_locks is held. If any object
3159 needs to be resized, then the lock will be temporarily upgraded to
3160 a write lock and then degraded to a read lock again; there will be
3161 a short period when the lock is not held at all.
3162
3163 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
3164 */
3166
3167 /**
3168 Adds the given Gtid_set to lost_gtids and executed_gtids.
3169 lost_gtids must be a subset of executed_gtids.
3170 purged_gtid and executed_gtid sets are appended with the argument set
3171 provided the latter is disjoint with gtid_executed owned_gtids.
3172
3173 Requires that the caller holds global_sid_lock.wrlock.
3174
3175 @param[in,out] gtid_set The gtid_set to add. If the gtid_set
3176 does not start with a plus sign (starts_with_plus is false),
3177 @@GLOBAL.GTID_PURGED will be removed from the gtid_set.
3178 @param starts_with_plus If true, the gtid_set passed is required to
3179 be disjoint from @@GLOBAL.GTID_PURGED; if false, the gtid_set passed
3180 is required to be a superset of @@GLOBAL.GTID_PURGED.
3181 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
3182 */
3183 enum_return_status add_lost_gtids(Gtid_set *gtid_set, bool starts_with_plus);
3184
3185 /** Updates previously logged GTID set before writing to table. */
3186 void update_prev_gtids(Gtid_set *write_gtid_set);
3187
3188 /// Return a pointer to the Gtid_set that contains the lost gtids.
3189 const Gtid_set *get_lost_gtids() const { return &lost_gtids; }
3190 /*
3191 Return a pointer to the Gtid_set that contains the stored gtids
3192 in gtid_executed table.
3193 */
3194 const Gtid_set *get_executed_gtids() const { return &executed_gtids; }
3195 /*
3196 Return a pointer to the Gtid_set that contains the stored gtids
3197 only in gtid_executed table, not in binlog files.
3198 */
3200 return &gtids_only_in_table;
3201 }
3202 /*
3203 Return a pointer to the Gtid_set that contains the previous stored
3204 gtids in the last binlog file.
3205 */
3207 return &previous_gtids_logged;
3208 }
3209 /// Return a pointer to the Owned_gtids that contains the owned gtids.
3210 const Owned_gtids *get_owned_gtids() const { return &owned_gtids; }
3211 /// Return the server's SID's SIDNO
3213 /// Return the server's SID
3214 const rpl_sid &get_server_sid() const {
3216 }
3217#ifndef NDEBUG
3218 /**
3219 Debug only: Returns an upper bound on the length of the string
3220 generated by to_string(), not counting '\0'. The actual length
3221 may be shorter.
3222 */
3223 size_t get_max_string_length() const {
3228 }
3229 /// Debug only: Generate a string in the given buffer and return the length.
3230 int to_string(char *buf) const {
3231 char *p = buf;
3232 p += sprintf(p, "Executed GTIDs:\n");
3234 p += sprintf(p, "\nOwned GTIDs:\n");
3236 p += sprintf(p, "\nLost GTIDs:\n");
3237 p += lost_gtids.to_string(p);
3238 p += sprintf(p, "\nGTIDs only_in_table:\n");
3239 p += lost_gtids.to_string(p);
3240 return (int)(p - buf);
3241 }
3242 /// Debug only: return a newly allocated string, or NULL on out-of-memory.
3243 char *to_string() const {
3246 to_string(str);
3247 return str;
3248 }
3249 /// Debug only: print this Gtid_state to stdout.
3250 void print() const {
3251 char *str = to_string();
3252 printf("%s", str);
3253 my_free(str);
3254 }
3255#endif
3256 /**
3257 Print this Gtid_state to the trace file if debug is enabled; no-op
3258 otherwise.
3259 */
3260 void dbug_print(const char *text [[maybe_unused]] = "") const {
3261#ifndef NDEBUG
3263 char *str = to_string();
3264 DBUG_PRINT("info", ("%s%s%s", text, *text ? ": " : "", str));
3265 my_free(str);
3266#endif
3267 }
3268 /**
3269 Save gtid owned by the thd into executed_gtids variable
3270 and gtid_executed table.
3271
3272 @param thd Session to commit
3273 @retval
3274 0 OK
3275 @retval
3276 -1 Error
3277 */
3278 int save(THD *thd);
3279 /**
3280 Insert the gtid set into table.
3281
3282 @param gtid_set contains a set of gtid, which holds
3283 the sidno and the gno.
3284
3285 @retval
3286 0 OK
3287 @retval
3288 -1 Error
3289 */
3290 int save(const Gtid_set *gtid_set);
3291 /**
3292 Save the set of gtids logged in the last binlog into gtid_executed table.
3293
3294 @retval
3295 0 OK
3296 @retval
3297 -1 Error
3298 */
3300 /**
3301 Fetch gtids from gtid_executed table and store them into
3302 gtid_executed set.
3303
3304 @retval
3305 0 OK
3306 @retval
3307 1 The table was not found.
3308 @retval
3309 -1 Error
3310 */
3312 /**
3313 Compress the gtid_executed table, read each row by the PK(sid, gno_start)
3314 in increasing order, compress the first consecutive gtids range
3315 (delete consecutive gtids from the second consecutive gtid, then
3316 update the first gtid) within a single transaction.
3317
3318 @param thd Thread requesting to compress the table
3319
3320 @retval
3321 0 OK
3322 @retval
3323 1 The table was not found.
3324 @retval
3325 -1 Error
3326 */
3327 int compress(THD *thd);
3328#ifdef MYSQL_SERVER
3329 /**
3330 Push a warning to client if user is modifying the gtid_executed
3331 table explicitly by a non-XA transaction. Push an error to client
3332 if user is modifying it explicitly by a XA transaction.
3333
3334 @param thd Thread requesting to access the table
3335 @param table The table is being accessed.
3336
3337 @retval 0 No warning or error was pushed to the client.
3338 @retval 1 Push a warning to client.
3339 @retval 2 Push an error to client.
3340 */
3342#endif
3343
3344 private:
3345 /**
3346 Remove the GTID owned by thread from owned GTIDs.
3347
3348 This will:
3349
3350 - Clean up the thread state if the thread owned GTIDs is empty.
3351 - Release ownership of all GTIDs owned by the THD. This removes
3352 the GTID from Owned_gtids and clears the ownership status in the
3353 THD object.
3354 - Add the owned GTID to executed_gtids if the is_commit flag is
3355 set.
3356 - Decrease counters of GTID-violating transactions.
3357 - Send a broadcast on the condition variable for every sidno for
3358 which we released ownership.
3359
3360 @param[in] thd Thread for which owned gtids are updated.
3361 @param[in] is_commit If true, the update is for a commit (not a rollback).
3362 */
3363 void update_gtids_impl(THD *thd, bool is_commit);
3364#ifdef HAVE_GTID_NEXT_LIST
3365 /// Lock all SIDNOs owned by the given THD.
3366 void lock_owned_sidnos(const THD *thd);
3367#endif
3368 /// Unlock all SIDNOs owned by the given THD.
3369 void unlock_owned_sidnos(const THD *thd);
3370 /// Broadcast the condition for all SIDNOs owned by the given THD.
3371 void broadcast_owned_sidnos(const THD *thd);
3372 /// Read-write lock that protects updates to the number of SIDs.
3374 /// The Sid_map used by this Gtid_state.
3376 /// Contains one mutex/cond pair for every SIDNO.
3378 /**
3379 The set of GTIDs that existed in some previously purged binary log.
3380 This is always a subset of executed_gtids.
3381 */
3383 /*
3384 The set of GTIDs that has been executed and
3385 stored into gtid_executed table.
3386 */
3388 /*
3389 The set of GTIDs that exists only in gtid_executed table, not in
3390 binlog files.
3391 */
3393 /* The previous GTIDs in the last binlog. */
3395 /// The set of GTIDs that are owned by some thread.
3397 /// The SIDNO for this server.
3399
3400 /// The number of anonymous transactions owned by any client.
3401 std::atomic<int32> atomic_anonymous_gtid_count{0};
3402 /// The number of GTID-violating transactions that use GTID_NEXT=AUTOMATIC.
3404 /// The number of GTID-violating transactions that use GTID_NEXT=AUTOMATIC.
3406 /// The number of clients that are executing
3407 /// WAIT_FOR_EXECUTED_GTID_SET or WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS.
3408 std::atomic<int32> atomic_gtid_wait_count{0};
3409
3410 /// Used by unit tests that need to access private members.
3411#ifdef FRIEND_OF_GTID_STATE
3412 friend FRIEND_OF_GTID_STATE;
3413#endif
3414
3415 /**
3416 This is a sub task of update_on_rollback responsible only to handle
3417 the case of a thread that needs to skip GTID operations when it has
3418 "failed to commit".
3419
3420 Administrative commands [CHECK|REPAIR|OPTIMIZE|ANALYZE] TABLE
3421 are written to the binary log even when they fail. When the
3422 commands fail, they will call update_on_rollback; later they will
3423 write the binary log. But we must not do any of the things in
3424 update_gtids_impl if we are going to write the binary log. So
3425 these statements set the skip_gtid_rollback flag, which tells
3426 update_on_rollback to return early. When the statements are
3427 written to the binary log they will call update_on_commit as
3428 usual.
3429
3430 @param[in] thd - Thread to be evaluated.
3431
3432 @retval true The transaction should skip the rollback, false otherwise.
3433 */
3435 /**
3436 This is a sub task of update_gtids_impl responsible only to handle
3437 the case of a thread that owns nothing and does not violate GTID
3438 consistency.
3439
3440 If the THD does not own anything, there is nothing to do, so we can do an
3441 early return of the update process. Except if there is a GTID consistency
3442 violation; then we need to decrease the counter, so then we can continue
3443 executing inside update_gtids_impl.
3444
3445 @param[in] thd - Thread to be evaluated.
3446 @retval true The transaction can be skipped because it owns nothing and
3447 does not violate GTID consistency, false otherwise.
3448 */
3450 /**
3451 This is a sub task of update_gtids_impl responsible only to evaluate
3452 if the thread is committing in the middle of a statement by checking
3453 THD's is_commit_in_middle_of_statement flag.
3454
3455 This flag is true for anonymous transactions, when the
3456 'transaction' has been split into multiple transactions in the
3457 binlog, and the present transaction is not the last one.
3458
3459 This means two things:
3460
3461 - We should not release anonymous ownership in case
3462 gtid_next=anonymous. If we did, it would be possible for user
3463 to set GTID_MODE=ON from a concurrent transaction, making it
3464 impossible to commit the current transaction.
3465
3466 - We should not decrease the counters for GTID-violating
3467 statements. If we did, it would be possible for a concurrent
3468 client to set ENFORCE_GTID_CONSISTENCY=ON despite there is an
3469 ongoing transaction that violates GTID consistency.
3470
3471 The flag is set in two cases:
3472
3473 1. We are committing the statement cache when there are more
3474 changes in the transaction cache.
3475
3476 This happens either because a single statement in the
3477 beginning of a transaction updates both transactional and
3478 non-transactional tables, or because we are committing a
3479 non-transactional update in the middle of a transaction when
3480 binlog_direct_non_transactional_updates=1.
3481
3482 In this case, the flag is set further down in this function.
3483
3484 2. The statement is one of the special statements that may
3485 generate multiple transactions: CREATE...SELECT, DROP TABLE,
3486 DROP DATABASE. See comment for THD::owned_gtid in
3487 sql/sql_class.h.
3488
3489 In this case, the THD::is_commit_in_middle_of_statement flag
3490 is set by the caller and the flag becomes true here.
3491
3492 @param[in] thd - Thread to be evaluated.
3493 @return The value of thread's is_commit_in_middle_of_statement flag.
3494 */
3495 bool update_gtids_impl_begin(THD *thd);
3496 /**
3497 Handle the case that the thread own a set of GTIDs.
3498
3499 This is a sub task of update_gtids_impl responsible only to handle
3500 the case of a thread with a set of GTIDs being updated.
3501
3502 - Release ownership of the GTIDs owned by the THD. This removes
3503 the GTID from Owned_gtids and clears the ownership status in the
3504 THD object.
3505 - Add the owned GTIDs to executed_gtids if the is_commit flag is set.
3506 - Send a broadcast on the condition variable for the sidno which we
3507 released ownership.
3508
3509 @param[in] thd - Thread for which owned GTID set should be updated.
3510 @param[in] is_commit - If the thread is being updated by a commit.
3511 */
3512 void update_gtids_impl_own_gtid_set(THD *thd, bool is_commit);
3513 /**
3514 Lock a given sidno of a transaction being updated.
3515
3516 This is a sub task of update_gtids_impl responsible only to lock the
3517 sidno of the GTID being updated.
3518
3519 @param[in] sidno - The sidno to be locked.
3520 */
3522 /**
3523
3524 Locks the sidnos of all the GTIDs of the commit group starting on the
3525 transaction passed as parameter.
3526
3527 This is a sub task of update_commit_group responsible only to lock the
3528 sidno(s) of the GTID(s) being updated.
3529
3530 The function should follow thd->next_to_commit to lock all sidnos of all
3531 transactions being updated in a group.
3532
3533 @param[in] thd - Thread that owns the GTID(s) to be updated or leader
3534 of the commit group in the case of a commit group
3535 update.
3536 */
3538 /**
3539 Handle the case that the thread own a single non-anonymous GTID.
3540
3541 This is a sub task of update_gtids_impl responsible only to handle
3542 the case of a thread with a single non-anonymous GTID being updated
3543 either for commit or rollback.
3544
3545 - Release ownership of the GTID owned by the THD. This removes
3546 the GTID from Owned_gtids and clears the ownership status in the
3547 THD object.
3548 - Add the owned GTID to executed_gtids if the is_commit flag is set.
3549 - Send a broadcast on the condition variable for the sidno which we
3550 released ownership.
3551
3552 @param[in] thd - Thread to be updated that owns single non-anonymous GTID.
3553 @param[in] is_commit - If the thread is being updated by a commit.
3554 */
3555 void update_gtids_impl_own_gtid(THD *thd, bool is_commit);
3556 /**
3557 Unlock a given sidno after broadcasting its changes.
3558
3559 This is a sub task of update_gtids_impl responsible only to
3560 unlock the sidno of the GTID being updated after broadcasting
3561 its changes.
3562
3563 @param[in] sidno - The sidno to be broadcasted and unlocked.
3564 */
3566 /**
3567 Unlocks all locked sidnos after broadcasting their changes.
3568
3569 This is a sub task of update_commit_group responsible only to
3570 unlock the sidno(s) of the GTID(s) being updated after broadcasting
3571 their changes.
3572 */
3574 /**
3575 Handle the case that the thread owns ANONYMOUS GTID.
3576
3577 This is a sub task of update_gtids_impl responsible only to handle
3578 the case of a thread with an ANONYMOUS GTID being updated.
3579
3580 - Release ownership of the anonymous GTID owned by the THD and clears
3581 the ownership status in the THD object.
3582 - Decrease counters of GTID-violating transactions.
3583
3584 @param[in] thd - Thread to be updated that owns anonymous GTID.
3585 @param[in,out] more_trx - If the 'transaction' has been split into
3586 multiple transactions in the binlog.
3587 This is firstly assigned with the return of
3588 Gtid_state::update_gtids_impl_begin function, and
3589 its value can be set to true when
3590 Gtid_state::update_gtids_impl_anonymous_gtid
3591 detects more content on the transaction cache.
3592 */
3593 void update_gtids_impl_own_anonymous(THD *thd, bool *more_trx);
3594 /**
3595 Handle the case that the thread owns nothing.
3596
3597 This is a sub task of update_gtids_impl responsible only to handle
3598 the case of a thread that owns nothing being updated.
3599
3600 There are two cases when this happens:
3601 - Normally, it is a rollback of an automatic transaction, so
3602 the is_commit is false and gtid_next=automatic.
3603 - There is also a corner case. This case may happen for a transaction
3604 that uses GTID_NEXT=AUTOMATIC, and violates GTID_CONSISTENCY, and
3605 commits changes to the database, but does not write to the binary log,
3606 so that no GTID is generated. An example is CREATE TEMPORARY TABLE
3607 inside a transaction when binlog_format=row. Despite the thread does
3608 not own anything, the GTID consistency violation makes it necessary to
3609 call end_gtid_violating_transaction. Therefore
3610 MYSQL_BIN_LOG::gtid_end_transaction will call
3611 gtid_state->update_on_commit in this case, and subsequently we will
3612 reach this case.
3613
3614 @param[in] thd - Thread to be updated that owns anonymous GTID.
3615 */
3617 /**
3618 Handle the final part of update_gtids_impl.
3619
3620 This is a sub task of update_gtids_impl responsible only to handle
3621 the call to end_gtid_violating_transaction function when there is no
3622 more transactions split after the current transaction.
3623
3624 @param[in] thd - Thread for which owned GTID is updated.
3625 @param[in] more_trx - This is the value returned from
3626 Gtid_state::update_gtids_impl_begin and can be
3627 changed for transactions owning anonymous GTID at
3628 Gtid_state::update_gtids_impl_own_anonymous.
3629 */
3630 void update_gtids_impl_end(THD *thd, bool more_trx);
3631 /**
3632 This array is used by Gtid_state_update_gtids_impl* functions.
3633
3634 The array items (one per sidno of the sid_map) will be set as true for
3635 each sidno that requires to be locked when updating a set of GTIDs
3636 (at Gtid_set::update_gtids_impl_lock_sidnos).
3637
3638 The array items will be set false at
3639 Gtid_set::update_gtids_impl_broadcast_and_unlock_sidnos.
3640
3641 It is used to so that lock, unlock, and broadcast operations are only
3642 called once per sidno per commit group, instead of once per transaction.
3643
3644 Its access is protected by:
3645 - global_sid_lock->wrlock when growing and cleaning up;
3646 - MYSQL_BIN_LOG::LOCK_commit when setting true/false on array items.
3647 */
3649 /**
3650 Ensure that commit_group_sidnos have room for the SIDNO passed as
3651 parameter.
3652
3653 This function must only be called in one place:
3654 Gtid_state::ensure_sidno().
3655
3656 @param sidno The SIDNO.
3657 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
3658 */
3660};
3661
3662/*
3663 BUG# #18089914 - REFACTORING: RENAME GROUP TO GTID
3664 changed AUTOMATIC_GROUP to AUTOMATIC_GTID
3665 changed ANONYMOUS_GROUP to ANONYMOUS_GTID
3666 changed INVALID_GROUP to INVALID_GTID
3667 changed UNDEFINED_GROUP to UNDEFINED_GTID
3668 changed GTID_GROUPto ASSIGNED_GTID
3669 changed NOT_YET_DETERMINED_GROUP to NOT_YET_DETERMINED_GTID
3670*/
3671
3672/**
3673 Enumeration of different types of values for Gtid_specification,
3674 i.e, the different internal states that @@session.gtid_next can be in.
3675*/
3677 /**
3678 Specifies that the GTID has not been generated yet; it will be
3679 generated on commit. It will depend on the GTID_MODE: if
3680 GTID_MODE<=OFF_PERMISSIVE, then the transaction will be anonymous;
3681 if GTID_MODE>=ON_PERMISSIVE, then the transaction will be assigned
3682 a new GTID.
3683
3684 This is the default value: thd->variables.gtid_next has this state
3685 when GTID_NEXT="AUTOMATIC".
3686
3687 It is important that AUTOMATIC_GTID==0 so that the default value
3688 for thd->variables->gtid_next.type is AUTOMATIC_GTID.
3689 */
3691 /**
3692 Specifies that the transaction has been assigned a GTID (UUID:NUMBER).
3693
3694 thd->variables.gtid_next has this state when GTID_NEXT="UUID:NUMBER".
3695
3696 This is the state of GTID-transactions replicated to the slave.
3697 */
3699 /**
3700 Specifies that the transaction is anonymous, i.e., it does not
3701 have a GTID and will never be assigned one.
3702
3703 thd->variables.gtid_next has this state when GTID_NEXT="ANONYMOUS".
3704
3705 This is the state of any transaction generated on a pre-GTID
3706 server, or on a server with GTID_MODE==OFF.
3707 */
3709 /**
3710 GTID_NEXT is set to this state after a transaction with
3711 GTID_NEXT=='UUID:NUMBER' is committed.
3712
3713 This is used to protect against a special case of unsafe
3714 non-transactional updates.
3715
3716 Background: Non-transactional updates are allowed as long as they
3717 are sane. Non-transactional updates must be single-statement
3718 transactions; they must not be mixed with transactional updates in
3719 the same statement or in the same transaction. Since
3720 non-transactional updates must be logged separately from
3721 transactional updates, a single mixed statement would generate two
3722 different transactions.
3723
3724 Problematic case: Consider a transaction, Tx1, that updates two
3725 transactional tables on the master, t1 and t2. Then slave (s1) later
3726 replays Tx1. However, t2 is a non-transactional table at s1. As such, s1
3727 will report an error because it cannot split Tx1 into two different
3728 transactions. Had no error been reported, then Tx1 would be split into Tx1
3729 and Tx2, potentially causing severe harm in case some form of fail-over
3730 procedure is later engaged by s1.
3731
3732 To detect this case on the slave and generate an appropriate error
3733 message rather than causing an inconsistency in the GTID state, we
3734 do as follows. When committing a transaction that has
3735 GTID_NEXT==UUID:NUMBER, we set GTID_NEXT to UNDEFINED_GTID. When
3736 the next part of the transaction is being processed, an error is
3737 generated, because it is not allowed to execute a transaction when
3738 GTID_NEXT==UNDEFINED. In the normal case, the error is not
3739 generated, because there will always be a Gtid_log_event after the
3740 next transaction.
3741 */
3743 /**
3744 GTID_NEXT is set to this state by the slave applier thread when it
3745 reads a Format_description_log_event that does not originate from
3746 this server.
3747
3748 Background: when the slave applier thread reads a relay log that
3749 comes from a pre-GTID master, it must preserve the transactions as
3750 anonymous transactions, even if GTID_MODE>=ON_PERMISSIVE. This
3751 may happen, e.g., if the relay log was received when master and
3752 slave had GTID_MODE=OFF or when master and slave were old, and the
3753 relay log is applied when slave has GTID_MODE>=ON_PERMISSIVE.
3754
3755 So the slave thread should set GTID_NEXT=ANONYMOUS for the next
3756 transaction when it starts to process an old binary log. However,
3757 there is no way for the slave to tell if the binary log is old,
3758 until it sees the first transaction. If the first transaction
3759 begins with a Gtid_log_event, we have the GTID there; if it begins
3760 with query_log_event, row events, etc, then this is an old binary
3761log. So at the time the binary log begins, we just set
3762 GTID_NEXT=NOT_YET_DETERMINED_GTID. If it remains
3763 NOT_YET_DETERMINED when the next transaction begins,
3764 gtid_pre_statement_checks will automatically turn it into an
3765 anonymous transaction. If a Gtid_log_event comes across before
3766 the next transaction starts, then the Gtid_log_event will just set
3767 GTID_NEXT='UUID:NUMBER' accordingly.
3768 */
3770 /**
3771 The applier sets GTID_NEXT this state internally, when it
3772 processes an Anonymous_gtid_log_event on a channel having
3773 ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS, before it calls
3774 set_gtid_next. This tells set_gtid_next to generate a new,
3775 sequential GTID, and acquire ownership for it. Thus, this state
3776 is only used for a very brief period of time. It is not
3777 user-visible.
3778 */
3781/// Global state of GTIDs.
3782extern Gtid_state *gtid_state;
3783
3784/**
3785 This struct represents a specification of a GTID for a statement to
3786 be executed: either "AUTOMATIC", "ANONYMOUS", or "SID:GNO".
3787
3788 This is a POD. It has to be a POD because it is used in THD::variables.
3789*/
3791 /// The type of this GTID
3793 /**
3794 The GTID:
3795 { SIDNO, GNO } if type == GTID;
3796 { 0, 0 } if type == AUTOMATIC or ANONYMOUS.
3797 */
3799 /// Set the type to ASSIGNED_GTID and SID, GNO to the given values.
3800 void set(rpl_sidno sidno, rpl_gno gno) {
3801 gtid.set(sidno, gno);
3803 }
3804 /// Set the type to ASSIGNED_GTID and SID, GNO to the given Gtid.
3805 void set(const Gtid &gtid_param) { set(gtid_param.sidno, gtid_param.gno); }
3806 /// Set the type to AUTOMATIC_GTID.
3808 /// Set the type to ANONYMOUS_GTID.
3810 /// Set the type to NOT_YET_DETERMINED_GTID.
3812 /// Set to undefined. Must only be called if the type is ASSIGNED_GTID.
3814 assert(type == ASSIGNED_GTID);
3816 }
3817 /// Return true if this Gtid_specification is equal to 'other'.
3818 bool equals(const Gtid_specification &other) const {
3819 return (type == other.type &&
3820 (type != ASSIGNED_GTID || gtid.equals(other.gtid)));
3821 }
3822 /**
3823 Return true if this Gtid_specification is a ASSIGNED_GTID with the
3824 same SID, GNO as 'other_gtid'.
3825 */
3826 bool equals(const Gtid &other_gtid) const {
3827 return type == ASSIGNED_GTID && gtid.equals(other_gtid);
3828 }
3829#ifdef MYSQL_SERVER
3830 /**
3831 Parses the given string and stores in this Gtid_specification.
3832
3833 @param sid_map sid_map to use when converting SID to a sidno.
3834 @param text The text to parse
3835 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
3836 */
3837 enum_return_status parse(Sid_map *sid_map, const char *text);
3838 /// Returns true if the given string is a valid Gtid_specification.
3839 static bool is_valid(const char *text);
3840#endif
3842 /**
3843 Writes this Gtid_specification to the given string buffer.
3844
3845 @param sid_map Sid_map to use if the type of this
3846 Gtid_specification is ASSIGNED_GTID.
3847 @param [out] buf The buffer
3848 @param need_lock If true, this function acquires global_sid_lock
3849 before looking up the sidno in sid_map, and then releases it. If
3850 false, this function asserts that the lock is held by the caller.
3851 @retval The number of characters written.
3852 */
3853 int to_string(const Sid_map *sid_map, char *buf,
3854 bool need_lock = false) const;
3855 /**
3856 Writes this Gtid_specification to the given string buffer.
3857
3858 @param sid SID to use if the type of this Gtid_specification is
3859 ASSIGNED_GTID. Can be NULL if this Gtid_specification is
3860 ANONYMOUS_GTID or AUTOMATIC_GTID.
3861 @param[out] buf The buffer
3862 @retval The number of characters written.
3863 */
3864 int to_string(const rpl_sid *sid, char *buf) const;
3865#ifndef NDEBUG
3866 /// Debug only: print this Gtid_specification to stdout.
3867 void print() const {
3868 char buf[MAX_TEXT_LENGTH + 1];
3870 printf("%s\n", buf);
3871 }
3872#endif
3873 /**
3874 Print this Gtid_specification to the trace file if debug is
3875 enabled; no-op otherwise.
3876 */
3877 void dbug_print(const char *text [[maybe_unused]] = "",
3878 bool need_lock [[maybe_unused]] = false) const {
3879#ifndef NDEBUG
3880 char buf[MAX_TEXT_LENGTH + 1];
3881 to_string(global_sid_map, buf, need_lock);
3882 DBUG_PRINT("info", ("%s%s%s", text, *text ? ": " : "", buf));
3883#endif
3884 }
3885};
3886
3887/**
3888 Indicates if a statement should be skipped or not. Used as return
3889 value from gtid_before_statement.
3890*/
3892 /// Statement can execute.
3894 /// Statement should be cancelled.
3896 /**
3897 Statement should be skipped, but there may be an implicit commit
3898 after the statement if gtid_commit is set.
3899 */
3902
3903#ifdef MYSQL_SERVER
3904
3905/**
3906 Check if current transaction should be skipped, that is, if GTID_NEXT
3907 was already logged.
3908
3909 @param thd The calling thread.
3910
3911 @retval true Transaction was already logged.
3912 @retval false Transaction must be executed.
3913*/
3914bool is_already_logged_transaction(const THD *thd);
3915
3916/**
3917 Perform GTID-related checks before executing a statement:
3918
3919 - Check that the current statement does not contradict
3920 enforce_gtid_consistency.
3921
3922 - Check that there is no implicit commit in a transaction when
3923 GTID_NEXT==UUID:NUMBER.
3924
3925 - Change thd->variables.gtid_next.type to ANONYMOUS_GTID if it is
3926 currently NOT_YET_DETERMINED_GTID.
3927
3928 - Check whether the statement should be cancelled.
3929
3930 @param thd THD object for the session.
3931
3932 @retval GTID_STATEMENT_EXECUTE The normal case: the checks
3933 succeeded, and statement can execute.
3934
3935 @retval GTID_STATEMENT_CANCEL The checks failed; an
3936 error has be generated and the statement must stop.
3937
3938 @retval GTID_STATEMENT_SKIP The checks succeeded, but the GTID has
3939 already been executed (exists in GTID_EXECUTED). So the statement
3940 must not execute; however, if there are implicit commits, then the
3941 implicit commits must execute.
3942*/
3944
3945/**
3946 Perform GTID-related checks before executing a statement, but after
3947 executing an implicit commit before the statement, if any:
3948
3949 If gtid_next=anonymous, but the thread does not hold anonymous
3950 ownership, then acquire anonymous ownership. (Do this only if this
3951 is not an 'innocent' statement, i.e., SET/SHOW/DO/SELECT that does
3952 not invoke a stored function.)
3953
3954 It is important that this is done after the implicit commit, because
3955 the implicit commit may release anonymous ownership.
3956
3957 @param thd THD object for the session
3958
3959 @retval false Success.
3960
3961 @retval true Error. Error can happen if GTID_MODE=ON. The error has
3962 been reported by (a function called by) this function.
3963*/
3965
3966/**
3967 Acquire ownership of the given Gtid_specification.
3968
3969 The Gtid_specification must be of type ASSIGNED_GTID or ANONYMOUS_GTID.
3970
3971 The caller must hold global_sid_lock (normally the rdlock). The
3972 lock may be temporarily released and acquired again. In the end,
3973 the lock will be released, so the caller should *not* release the
3974 lock.
3975
3976 The function will try to acquire ownership of the GTID and update
3977 both THD::gtid_next, Gtid_state::owned_gtids, and
3978 THD::owned_gtid / THD::owned_sid.
3979
3980 @param thd The thread that acquires ownership.
3981
3982 @param spec The Gtid_specification.
3983
3984 @retval false Success: either we have acquired ownership of the
3985 GTID, or it is already included in GTID_EXECUTED and will be
3986 skipped.
3987
3988 @retval true Failure; the thread was killed or an error occurred.
3989 The error has been reported using my_error.
3990*/
3991bool set_gtid_next(THD *thd, const Gtid_specification &spec);
3992#ifdef HAVE_GTID_NEXT_LIST
3993int gtid_acquire_ownership_multiple(THD *thd);
3994#endif
3995
3996/**
3997 Return sidno for a given sid, see Sid_map::add_sid() for details.
3998*/
4000
4001/**
4002 Return last gno for a given sidno, see
4003 Gtid_state::get_last_executed_gno() for details.
4004*/
4006
4008
4009/**
4010 If gtid_next=ANONYMOUS or NOT_YET_DETERMINED, but the thread does
4011 not hold anonymous ownership, acquire anonymous ownership.
4012
4013 @param thd Thread.
4014
4015 @retval true Error (can happen if gtid_mode=ON and
4016 gtid_next=anonymous). The error has already been reported using
4017 my_error.
4018
4019 @retval false Success.
4020*/
4022
4023/**
4024 The function commits or rolls back the gtid state if it needs to.
4025 It's supposed to be invoked at the end of transaction commit or
4026 rollback, as well as as at the end of XA prepare.
4027
4028 @param thd Thread context
4029 @param needs_to The actual work will be done when the parameter is true
4030 @param do_commit When true the gtid state changes are committed, otherwise
4031 they are rolled back.
4032*/
4033
4034inline void gtid_state_commit_or_rollback(THD *thd, bool needs_to,
4035 bool do_commit) {
4036 if (needs_to) {
4037 if (do_commit)
4039 else
4041 }
4042}
4043
4044#endif // ifdef MYSQL_SERVER
4045
4046#endif /* RPL_GTID_H_INCLUDED */
RAII class to acquire a lock for the duration of a block.
Definition: rpl_gtid.h:336
void unlock_if_locked()
Unlock the lock, if it was acquired by this guard.
Definition: rpl_gtid.h:440
Guard(Checkable_rwlock &lock, enum_lock_type lock_type)
Create a guard, and optionally acquire a lock on it.
Definition: rpl_gtid.h:344
Checkable_rwlock & m_lock
Definition: rpl_gtid.h:337
Guard(Checkable_rwlock &lock, enum_lock_type lock_type, std::adopt_lock_t t)
Create a guard, assuming the caller already holds a lock on it.
Definition: rpl_gtid.h:365
bool is_locked() const
Return true if this object is either read locked or write locked.
Definition: rpl_gtid.h:455
bool is_wrlocked() const
Return true if this object is write locked.
Definition: rpl_gtid.h:452
int tryrdlock()
Try to acquire a read lock, and fail if it cannot be immediately granted.
Definition: rpl_gtid.h:424
enum_lock_type m_lock_type
Definition: rpl_gtid.h:338
Guard(Guard const &copy)=delete
Objects of this class should not be copied or moved.
void unlock()
Unlock the lock.
Definition: rpl_gtid.h:433
void rdlock()
Acquire the read lock.
Definition: rpl_gtid.h:393
Guard(Guard const &&copy)=delete
bool is_rdlocked() const
Return true if this object is read locked.
Definition: rpl_gtid.h:449
~Guard()
Unlock on destruct.
Definition: rpl_gtid.h:387
Checkable_rwlock & get_lock() const
Return the underlying Checkable_rwlock object.
Definition: rpl_gtid.h:446
int trywrlock()
Try to acquire the write lock, and fail if it cannot be immediately granted.
Definition: rpl_gtid.h:412
void wrlock()
Acquire the write lock.
Definition: rpl_gtid.h:401
This has the functionality of mysql_rwlock_t, with two differences:
Definition: rpl_gtid.h:308
int32 get_state() const
Read lock_state atomically and return the value.
Definition: rpl_gtid.h:571
void assert_no_rdlock() const
Assert that no thread holds the read lock.
Definition: rpl_gtid.h:553
int trywrlock()
Return 0 if the write lock is held, otherwise an error will be returned.
Definition: rpl_gtid.h:511
enum_lock_type
Definition: rpl_gtid.h:331
@ TRY_READ_LOCK
Definition: rpl_gtid.h:331
@ WRITE_LOCK
Definition: rpl_gtid.h:331
@ READ_LOCK
Definition: rpl_gtid.h:331
@ NO_LOCK
Definition: rpl_gtid.h:331
void rdlock()
Acquire the read lock.
Definition: rpl_gtid.h:459
void wrlock()
Acquire the write lock.
Definition: rpl_gtid.h:468
std::atomic< int32 > m_lock_state
The state of the lock: 0 - not locked -1 - write locked >0 - read locked by that many threads.
Definition: rpl_gtid.h:569
void assert_no_lock() const
Assert that no thread holds read or write lock.
Definition: rpl_gtid.h:555
int tryrdlock()
Return 0 if the read lock is held, otherwise an error will be returned.
Definition: rpl_gtid.h:530
~Checkable_rwlock()
Destroy this Checkable_lock.
Definition: rpl_gtid.h:329
void assert_no_wrlock() const
Assert that no thread holds the write lock.
Definition: rpl_gtid.h:551
void assert_some_lock() const
Assert that some thread holds either the read or the write lock.
Definition: rpl_gtid.h:545
Checkable_rwlock(PSI_rwlock_key psi_key=0)
Initialize this Checkable_rwlock.
Definition: rpl_gtid.h:311
void assert_some_rdlock() const
Assert that some thread holds the read lock.
Definition: rpl_gtid.h:547
void unlock()
Release the lock (whether it is a write or read lock).
Definition: rpl_gtid.h:479
bool m_dbug_trace
If enabled, print any lock/unlock operations to the DBUG trace.
Definition: rpl_gtid.h:560
bool is_wrlock()
Return true if the write lock is held.
Definition: rpl_gtid.h:499
void assert_some_wrlock() const
Assert that some thread holds the write lock.
Definition: rpl_gtid.h:549
mysql_rwlock_t m_rwlock
The rwlock.
Definition: rpl_gtid.h:580
Class to access the value of @global.gtid_mode in an efficient and thread-safe manner.
Definition: rpl_gtid.h:590
static std::pair< bool, value_type > from_string(std::string s)
Return the given string gtid_mode as an enumeration value.
Definition: rpl_gtid_mode.cc:54
static ulong sysvar_mode
The sys_var framework needs a variable of type ulong to store the value in.
Definition: rpl_gtid.h:603
std::atomic< int > m_atomic_mode
Definition: rpl_gtid.h:592
const char * get_string() const
Return the current gtid_mode as a string.
Definition: rpl_gtid_mode.cc:51
Gtid_mode()
Definition: rpl_gtid.h:595
static const char * names[]
Strings holding the enumeration values for gtid_mode.
Definition: rpl_gtid.h:635
void set(value_type value)
Set a new value for @global.gtid_mode.
Definition: rpl_gtid_mode.cc:42
value_type get() const
Return the current gtid_mode as an enumeration value.
Definition: rpl_gtid_mode.cc:46
static const char * to_string(value_type value)
Return the given gtid_mode as a string.
Definition: rpl_gtid_mode.cc:66
static Checkable_rwlock lock
Protects updates to @global.gtid_mode.
Definition: rpl_gtid.h:646
value_type
Possible values for @global.gtid_mode.
Definition: rpl_gtid.h:606
@ ON_PERMISSIVE
New transactions are GTID-transactions.
Definition: rpl_gtid.h:622
@ OFF
New transactions are anonymous.
Definition: rpl_gtid.h:611
@ OFF_PERMISSIVE
New transactions are anonyomus.
Definition: rpl_gtid.h:617
@ ON
New transactions are GTID-transactions.
Definition: rpl_gtid.h:628
@ DEFAULT
Definition: rpl_gtid.h:612
Stores information to monitor a transaction during the different replication stages.
Definition: rpl_gtid.h:1310
Trx_monitoring_info * last_processed_trx
Holds information about the last processed transaction.
Definition: rpl_gtid.h:1330
const Gtid * get_processing_trx_gtid()
Returns the GTID of the processing_trx.
Definition: rpl_gtid_misc.cc:525
void clear()
Clear all monitoring information.
Definition: rpl_gtid_misc.cc:419
void finish()
Sets the final information, copy processing info to last_processed and clears processing info.
Definition: rpl_gtid_misc.cc:486
void start(Gtid gtid_arg, ulonglong original_ts_arg, ulonglong immediate_ts_arg, bool skipped_arg=false)
Sets the initial monitoring information.
Definition: rpl_gtid_misc.cc:446
void update(binary_log::transaction::compression::type t, size_t payload_size, size_t uncompressed_size)
Definition: rpl_gtid_misc.cc:438
~Gtid_monitoring_info()
Destroy this GTID monitoring info object.
Definition: rpl_gtid_misc.cc:378
Trx_monitoring_info * processing_trx
Holds information about transaction being processed.
Definition: rpl_gtid.h:1328
void atomic_lock()
Lock this object when no thread mutex is used to arbitrate the access.
Definition: rpl_gtid_misc.cc:383
void atomic_unlock()
Unlock this object when no thread mutex is used to arbitrate the access.
Definition: rpl_gtid_misc.cc:408
mysql_mutex_t * atomic_mutex
Mutex arbitrating the atomic access to the object.
Definition: rpl_gtid.h:1347
void copy_info_to(Trx_monitoring_info *processing_dest, Trx_monitoring_info *last_processed_dest)
Copies both processing_trx and last_processed_trx info to other Trx_monitoring_info structures.
Definition: rpl_gtid_misc.cc:503
std::atomic< bool > atomic_locked
The atomic locked flag.
Definition: rpl_gtid.h:1350
bool is_processing_trx_set()
Returns true if the processing_trx is set, false otherwise.
Definition: rpl_gtid_misc.cc:516
bool is_locked
Flag to assert the atomic lock behavior.
Definition: rpl_gtid.h:1353
void store_transient_error(uint transient_errno_arg, const char *transient_err_message_arg, ulong trans_retries_arg)
Stores the information about the last transient error in the current transaction, namely: the error n...
Definition: rpl_gtid_misc.cc:534
Gtid_monitoring_info(mysql_mutex_t *atomic_mutex_arg=nullptr)
Create this GTID monitoring info object.
Definition: rpl_gtid_misc.cc:372
void clear_last_processed_trx()
Clear only the last_processed_trx monitoring info.
Definition: rpl_gtid_misc.cc:432
void clear_processing_trx()
Clear only the processing_trx monitoring info.
Definition: rpl_gtid_misc.cc:426
Iterator over intervals of a const Gtid_set.
Definition: rpl_gtid.h:1973
Const_interval_iterator(const Gtid_set *gtid_set)
Create this Const_interval_iterator.
Definition: rpl_gtid.h:1980
Const_interval_iterator(const Gtid_set *gtid_set, rpl_sidno sidno)
Create this Const_interval_iterator.
Definition: rpl_gtid.h:1976
Class representing a lock on free_intervals_mutex.
Definition: rpl_gtid.h:2201
bool locked
Definition: rpl_gtid.h:2225
void unlock_if_locked()
Lock the lock if it is locked.
Definition: rpl_gtid.h:2214
Free_intervals_lock(Gtid_set *_gtid_set)
Create a new lock, but do not acquire it.
Definition: rpl_gtid.h:2204
~Free_intervals_lock()
Destroy this object and unlock the lock if it is locked.
Definition: rpl_gtid.h:2221
void lock_if_not_locked()
Lock the lock if it is not already locked.
Definition: rpl_gtid.h:2207
Gtid_set * gtid_set
Definition: rpl_gtid.h:2224
Iterator over all gtids in a Gtid_set.
Definition: rpl_gtid.h:2031
Gtid get() const
Return next gtid, or {0,0} if we reached the end.
Definition: rpl_gtid.h:2057
rpl_sidno sidno
The SIDNO of the current element, or 0 if the iterator is past the last element.
Definition: rpl_gtid.h:2084
const Gtid_set * gtid_set
The Gtid_set we iterate over.
Definition: rpl_gtid.h:2079
void next()
Advance to next gtid.
Definition: rpl_gtid.h:2038
rpl_gno gno
The GNO of the current element, or 0 if the iterator is past the last element.
Definition: rpl_gtid.h:2089
Const_interval_iterator ivit
Iterator over the intervals for the current SIDNO.
Definition: rpl_gtid.h:2091
Gtid_iterator(const Gtid_set *gs)
Definition: rpl_gtid.h:2033
void next_sidno()
Find the next sidno that has one or more intervals.
Definition: rpl_gtid.h:2064
Iterator over intervals for a given SIDNO.
Definition: rpl_gtid.h:1932
Interval_p get() const
Return current_elem.
Definition: rpl_gtid.h:1958
void init(Gtid_set_p gtid_set, rpl_sidno sidno)
Reset this iterator.
Definition: rpl_gtid.h:1949
Interval_iterator_base(Gtid_set_p gtid_set, rpl_sidno sidno)
Construct a new iterator over the GNO intervals for a given Gtid_set.
Definition: rpl_gtid.h:1940
Interval_p * p
Holds the address of the 'next' pointer of the previous element, or the address of the initial pointe...
Definition: rpl_gtid.h:1966
Interval_iterator_base(Gtid_set_p gtid_set)
Construct a new iterator over the free intervals of a Gtid_set.
Definition: rpl_gtid.h:1945
void next()
Advance current_elem one step.
Definition: rpl_gtid.h:1953
Iterator over intervals of a non-const Gtid_set, with additional methods to modify the Gtid_set.
Definition: rpl_gtid.h:1990
Interval_iterator(Gtid_set *gtid_set)
Destroy this Interval_iterator.
Definition: rpl_gtid.h:1996
void set(Interval *iv)
Set current_elem to the given Interval but do not touch the next pointer of the given Interval.
Definition: rpl_gtid.h:2004
void insert(Interval *iv)
Insert the given element before current_elem.
Definition: rpl_gtid.h:2006
void remove(Gtid_set *gtid_set)
Remove current_elem.
Definition: rpl_gtid.h:2011
Interval_iterator(Gtid_set *gtid_set, rpl_sidno sidno)
Create this Interval_iterator.
Definition: rpl_gtid.h:1993
Represents a set of GTIDs.
Definition: rpl_gtid.h:1454
void encode(uchar *buf) const
Encodes this Gtid_set as a binary string.
Definition: rpl_gtid_set.cc:1236
void put_free_interval(Interval *iv)
Puts the given interval in the list of free intervals.
Definition: rpl_gtid_set.cc:254
rpl_gno get_last_gno(rpl_sidno sidno) const
Definition: rpl_gtid_set.cc:723
bool is_size_greater_than_or_equal(ulonglong num) const
Return true if the size of the set is greater than or equal to the given number.
Definition: rpl_gtid_set.cc:1225
bool is_intersection_nonempty(const Gtid_set *other) const
Returns true if there is a least one element of this Gtid_set in the other Gtid_set.
Definition: rpl_gtid_set.cc:1146
bool is_subset(const Gtid_set *super) const
Returns true if this Gtid_set is a subset of the other Gtid_set.
Definition: rpl_gtid_set.cc:1067
void add_interval_memory(int n_intervals, Interval *intervals_param)
Provides an array of Intervals that this Gtid_set can use when gtids are subsequently added.
Definition: rpl_gtid.h:1915
bool contains_sidno(rpl_sidno sidno) const
Returns true if this Gtid_set contains at least one GTID with the given SIDNO.
Definition: rpl_gtid.h:1746
int get_n_intervals() const
Return the number of intervals in this Gtid_set.
Definition: rpl_gtid.h:2144
bool sidno_equals(rpl_sidno sidno, const Gtid_set *other, rpl_sidno other_sidno) const
Return true if the given sidno of this Gtid_set contains the same intervals as the given sidno of the...
Definition: rpl_gtid_set.cc:912
Sid_map * sid_map
Sid_map associated with this Gtid_set.
Definition: rpl_gtid.h:2318
friend std::ostream & operator<<(std::ostream &os, const Gtid_set &in)
For use with C++ std::ostream
Definition: rpl_gtid.h:1839
void add_gno_intervals(rpl_sidno sidno, Const_interval_iterator ivit, Free_intervals_lock *lock)
Adds a list of intervals to the given SIDNO.
Definition: rpl_gtid_set.cc:610
Checkable_rwlock * sid_lock
Read-write lock that protects updates to the number of SIDs.
Definition: rpl_gtid.h:2182
static bool is_interval_subset(Const_interval_iterator *sub, Const_interval_iterator *super)
Returns true if every interval of sub is a subset of some interval of super.
Definition: rpl_gtid_set.cc:988
void init()
Worker for the constructor.
Definition: rpl_gtid_set.cc:101
static const int CHUNK_GROW_SIZE
The default number of intervals in an Interval_chunk.
Definition: rpl_gtid.h:2117
Interval_chunk * chunks
Linked list of chunks.
Definition: rpl_gtid.h:2327
static const String_format commented_string_format
String_format for printing the Gtid_set commented: the string is not quote-wrapped,...
Definition: rpl_gtid.h:1883
bool contains_gtid(rpl_sidno sidno, rpl_gno gno) const
Return true iff the given GTID exists in this set.
Definition: rpl_gtid_set.cc:705
enum_return_status ensure_sidno(rpl_sidno sidno)
Allocates space for all sidnos up to the given sidno in the array of intervals.
Definition: rpl_gtid_set.cc:131
int get_n_intervals(rpl_sidno sidno) const
Return the number of intervals for the given sidno.
Definition: rpl_gtid.h:2134
enum_return_status add_gtid_set(const Gtid_set *other)
Adds all gtids from the given Gtid_set to this Gtid_set.
Definition: rpl_gtid_set.cc:646
Gtid_set(Sid_map *sid_map, Checkable_rwlock *sid_lock=nullptr)
Constructs a new, empty Gtid_set.
Definition: rpl_gtid_set.cc:84
Interval * free_intervals
Linked list of free intervals.
Definition: rpl_gtid.h:2325
bool contains_gtid(const Gtid &gtid) const
Return true iff the given GTID exists in this set.
Definition: rpl_gtid.h:1643
static const String_format default_string_format
The default String_format: the format understood by add_gtid_text(const char *).
Definition: rpl_gtid.h:1873
void clear_set_and_sid_map()
Removes all gtids from this Gtid_set and clear all the sidnos used by the Gtid_set and it's SID map.
Definition: rpl_gtid_set.cc:287
void add_interval_memory_lock_taken(int n_ivs, Interval *ivs)
Like add_interval_memory, but does not acquire free_intervals_mutex.
Definition: rpl_gtid_set.cc:179
void remove_gtid_set(const Gtid_set *other)
Removes all gtids in the given Gtid_set from this Gtid_set.
Definition: rpl_gtid_set.cc:678
void print(bool need_lock=false, const Gtid_set::String_format *sf=nullptr) const
Debug only: Print this Gtid_set to stdout.
Definition: rpl_gtid.h:1830
Prealloced_array< Interval *, 8 > m_intervals
Array where the N'th element contains the head pointer to the intervals of SIDNO N+1.
Definition: rpl_gtid.h:2323
mysql_mutex_t free_intervals_mutex
Lock protecting the list of free intervals.
Definition: rpl_gtid.h:2187
void dbug_print(const char *text="", bool need_lock=false, const Gtid_set::String_format *sf=nullptr) const
Print this Gtid_set to the trace file if debug is enabled; no-op otherwise.
Definition: rpl_gtid.h:1851
bool is_subset_for_sid(const Gtid_set *super, rpl_sidno superset_sidno, rpl_sidno subset_sidno) const
Returns true if this Gtid_set is a subset of the given gtid_set on the given superset_sidno and subse...
Definition: rpl_gtid_set.cc:1029
int n_chunks
The number of chunks.
Definition: rpl_gtid.h:2339
void remove_gno_intervals(rpl_sidno sidno, Const_interval_iterator ivit, Free_intervals_lock *lock)
Removes a list of intervals from the given SIDNO.
Definition: rpl_gtid_set.cc:623
static bool is_valid(const char *text)
Returns true if the given string is a valid specification of a Gtid_set, false otherwise.
Definition: rpl_gtid_set.cc:567
void clear()
Removes all gtids from this Gtid_set.
Definition: rpl_gtid_set.cc:262
static bool is_interval_intersection_nonempty(Const_interval_iterator *ivit1, Const_interval_iterator *ivit2)
Returns true if at least one sidno in ivit1 is also in ivit2.
Definition: rpl_gtid_set.cc:1109
enum_return_status intersection(const Gtid_set *other, Gtid_set *result)
Add the intersection of this Gtid_set and the other Gtid_set to result.
Definition: rpl_gtid_set.cc:1199
void remove_gno_interval(Interval_iterator *ivitp, rpl_gno start, rpl_gno end, Free_intervals_lock *lock)
Removes the interval (start, end) from the given Interval_iterator.
Definition: rpl_gtid_set.cc:349
void get_gtid_intervals(std::list< Gtid_interval > *gtid_intervals) const
Gets all gtid intervals from this Gtid_set.
Definition: rpl_gtid_set.cc:826
bool is_subset_not_equals(const Gtid_set *super) const
Returns true if this Gtid_set is a non equal subset of the other Gtid_set.
Definition: rpl_gtid.h:1670
size_t get_string_length(const String_format *string_format=nullptr) const
Returns the length of the output from to_string.
Definition: rpl_gtid_set.cc:868
size_t cached_string_length
The string length.
Definition: rpl_gtid.h:2331
enum_return_status add_gtid_text(const char *text, bool *anonymous=nullptr, bool *starts_with_plus=nullptr)
Adds the set of GTIDs represented by the given string to this Gtid_set.
Definition: rpl_gtid_set.cc:423
void add_gno_interval(Interval_iterator *ivitp, rpl_gno start, rpl_gno end, Free_intervals_lock *lock)
Adds the interval (start, end) to the given Interval_iterator.
Definition: rpl_gtid_set.cc:300
void _add_gtid(rpl_sidno sidno, rpl_gno gno)
Adds the given GTID to this Gtid_set.
Definition: rpl_gtid.h:1516
bool is_empty() const
Returns true if this Gtid_set is empty.
Definition: rpl_gtid.h:1703
static PSI_mutex_key key_gtid_executed_free_intervals_mutex
Definition: rpl_gtid.h:1456
static const String_format sql_string_format
String_format useful to generate an SQL string: the string is wrapped in single quotes and there is a...
Definition: rpl_gtid.h:1878
bool equals(const Gtid_set *other) const
Returns true if this Gtid_set is equal to the other Gtid_set.
Definition: rpl_gtid_set.cc:930
enum_return_status add_gtid_encoding(const uchar *encoded, size_t length, size_t *actual_length=nullptr)
Decodes a Gtid_set from the given string.
Definition: rpl_gtid_set.cc:1284
void remove_intervals_for_sidno(Gtid_set *other, rpl_sidno sidno)
Removes all intervals of 'other' for a given SIDNO, from 'this'.
Definition: rpl_gtid_set.cc:637
size_t get_encoded_length() const
Returns the length of this Gtid_set when encoded using the encode() function.
Definition: rpl_gtid_set.cc:1369
~Gtid_set()
Destroy this Gtid_set.
Definition: rpl_gtid_set.cc:116
bool has_cached_string_length
If the string is cached.
Definition: rpl_gtid.h:2329
const String_format * cached_string_format
The String_format that was used when cached_string_length was computed.
Definition: rpl_gtid.h:2333
void get_free_interval(Interval **out)
Returns a fresh new Interval object.
Definition: rpl_gtid_set.cc:241
size_t to_string(char *buf, bool need_lock=false, const String_format *string_format=nullptr) const
Formats this Gtid_set as a string and saves in a given buffer.
Definition: rpl_gtid_set.cc:760
void _remove_gtid(const Gtid &gtid)
Removes the given GTID from this Gtid_set.
Definition: rpl_gtid.h:1554
Sid_map * get_sid_map() const
Return the Sid_map associated with this Gtid_set.
Definition: rpl_gtid.h:1886
void _remove_gtid(rpl_sidno sidno, rpl_gno gno)
Removes the given GTID from this Gtid_set.
Definition: rpl_gtid.h:1532
void create_new_chunk(int size)
Allocates a new chunk of Intervals and adds them to the list of unused intervals.
Definition: rpl_gtid_set.cc:190
void _add_gtid(const Gtid &gtid)
Adds the given GTID to this Gtid_set.
Definition: rpl_gtid.h:1548
rpl_sidno get_max_sidno() const
Returns the maximal sidno that this Gtid_set currently has space for.
Definition: rpl_gtid.h:1649
void assert_free_intervals_locked()
Definition: rpl_gtid.h:2227
ulonglong get_gtid_count(rpl_sidno sidno) const
What is the count of all the GTIDs in all intervals for a sidno.
Definition: rpl_gtid.h:1726
Represents the server's GTID state: the set of committed GTIDs, the set of lost gtids,...
Definition: rpl_gtid.h:2701
bool update_gtids_impl_check_skip_gtid_rollback(THD *thd)
Used by unit tests that need to access private members.
Definition: rpl_gtid_state.cc:767
int init()
Add @GLOBAL.SERVER_UUID to this binlog's Sid_map.
Definition: rpl_gtid_state.cc:659
int warn_or_err_on_modify_gtid_table(THD *thd, TABLE_LIST *table)
Push a warning to client if user is modifying the gtid_executed table explicitly by a non-XA transact...
Definition: rpl_gtid_state.cc:760
bool update_gtids_impl_do_nothing(THD *thd)
This is a sub task of update_gtids_impl responsible only to handle the case of a thread that owns not...
Definition: rpl_gtid_state.cc:776
void end_automatic_gtid_violating_transaction()
Decrease the global counter when ending a GTID-violating transaction having GTID_NEXT=AUTOMATIC.
Definition: rpl_gtid.h:2890
void broadcast_owned_sidnos(const THD *thd)
Broadcast the condition for all SIDNOs owned by the given THD.
Definition: rpl_gtid_state.cc:142
const Gtid_set * get_executed_gtids() const
Definition: rpl_gtid.h:3194
void unlock_sidnos(const Gtid_set *set)
Unlocks the mutex for each SIDNO where the given Gtid_set has at least one GTID.
Definition: rpl_gtid_state.cc:555
void print() const
Debug only: print this Gtid_state to stdout.
Definition: rpl_gtid.h:3250
const Gtid_set * get_lost_gtids() const
Return a pointer to the Gtid_set that contains the lost gtids.
Definition: rpl_gtid.h:3189
enum_return_status ensure_sidno()
Ensure that owned_gtids, executed_gtids, lost_gtids, gtids_only_in_table, previous_gtids_logged and s...
Definition: rpl_gtid_state.cc:569
void begin_anonymous_gtid_violating_transaction()
Increase the global counter when starting a GTID-violating transaction having GTID_NEXT=ANONYMOUS.
Definition: rpl_gtid.h:2920
rpl_sidno server_sidno
The SIDNO for this server.
Definition: rpl_gtid.h:3398
bool wait_for_gtid_set(THD *thd, Gtid_set *gtid_set, double timeout, bool update_thd_status=true)
Wait until the given Gtid_set is included in @GLOBAL.GTID_EXECUTED.
Definition: rpl_gtid_state.cc:300
enum_return_status acquire_ownership(THD *thd, const Gtid &gtid)
Acquires ownership of the given GTID, on behalf of the given thread.
Definition: rpl_gtid_state.cc:77
void update_gtids_impl_own_nothing(THD *thd)
Handle the case that the thread owns nothing.
Definition: rpl_gtid_state.cc:946
void update_gtids_impl_lock_sidno(rpl_sidno sidno)
Lock a given sidno of a transaction being updated.
Definition: rpl_gtid_state.cc:827
rpl_gno next_free_gno
The next_free_gno variable will be set with the supposed next free GNO every time a new GNO is delive...
Definition: rpl_gtid.h:3039
Sid_map * sid_map
The Sid_map used by this Gtid_state.
Definition: rpl_gtid.h:3375
std::atomic< int32 > atomic_anonymous_gtid_count
The number of anonymous transactions owned by any client.
Definition: rpl_gtid.h:3401
int save_gtids_of_last_binlog_into_table()
Save the set of gtids logged in the last binlog into gtid_executed table.
Definition: rpl_gtid_state.cc:701
void end_gtid_wait()
Decrease the global counter when ending a call to WAIT_FOR_EXECUTED_GTID_SET or WAIT_UNTIL_SQL_THREAD...
Definition: rpl_gtid.h:2987
Gtid_state(Checkable_rwlock *_sid_lock, Sid_map *_sid_map)
Constructs a new Gtid_state object.
Definition: rpl_gtid.h:2710
Gtid_set lost_gtids
The set of GTIDs that existed in some previously purged binary log.
Definition: rpl_gtid.h:3382
const Owned_gtids * get_owned_gtids() const
Return a pointer to the Owned_gtids that contains the owned gtids.
Definition: rpl_gtid.h:3210
void unlock_owned_sidnos(const THD *thd)
Unlock all SIDNOs owned by the given THD.
Definition: rpl_gtid_state.cc:130
const rpl_sid & get_server_sid() const
Return the server's SID.
Definition: rpl_gtid.h:3214
Owned_gtids owned_gtids
The set of GTIDs that are owned by some thread.
Definition: rpl_gtid.h:3396
enum_return_status generate_automatic_gtid(THD *thd, rpl_sidno specified_sidno=0, rpl_gno specified_gno=0, rpl_sidno *locked_sidno=nullptr)
Generates the GTID (or ANONYMOUS, if GTID_MODE = OFF or OFF_PERMISSIVE) for the THD,...
Definition: rpl_gtid_state.cc:472
rpl_sidno get_server_sidno() const
Return the server's SID's SIDNO.
Definition: rpl_gtid.h:3212
const Gtid_set * get_previous_gtids_logged() const
Definition: rpl_gtid.h:3206
void update_gtids_impl_broadcast_and_unlock_sidno(rpl_sidno sidno)
Unlock a given sidno after broadcasting its changes.
Definition: rpl_gtid_state.cc:908
int32 get_gtid_wait_count()
Return the number of clients that have an ongoing call to WAIT_FOR_EXECUTED_GTID_SET or WAIT_UNTIL_SQ...
Definition: rpl_gtid.h:3004
Mutex_cond_array sid_locks
Contains one mutex/cond pair for every SIDNO.
Definition: rpl_gtid.h:3377
char * to_string() const
Debug only: return a newly allocated string, or NULL on out-of-memory.
Definition: rpl_gtid.h:3243
int read_gtid_executed_from_table()
Fetch gtids from gtid_executed table and store them into gtid_executed set.
Definition: rpl_gtid_state.cc:752
Gtid_set previous_gtids_logged
Definition: rpl_gtid.h:3394
enum_return_status add_lost_gtids(Gtid_set *gtid_set, bool starts_with_plus)
Adds the given Gtid_set to lost_gtids and executed_gtids.
Definition: rpl_gtid_state.cc:615
bool wait_for_sidno(THD *thd, rpl_sidno sidno, struct timespec *abstime, bool update_thd_status=true)
Wait for a signal on the given SIDNO.
Definition: rpl_gtid_state.cc:265
const Gtid_set * get_gtids_only_in_table() const
Definition: rpl_gtid.h:3199
int compress(THD *thd)
Compress the gtid_executed table, read each row by the PK(sid, gno_start) in increasing order,...
Definition: rpl_gtid_state.cc:756
int32 get_anonymous_gtid_violating_transaction_count()
Return the number of ongoing GTID-violating transactions having GTID_NEXT=AUTOMATIC.
Definition: rpl_gtid.h:2962
void lock_sidnos(const Gtid_set *set)
Locks one mutex for each SIDNO where the given Gtid_set has at least one GTID.
Definition: rpl_gtid_state.cc:548
void assert_sidno_lock_owner(rpl_sidno sidno) const
Assert that we own the given SIDNO.
Definition: rpl_gtid.h:3084
enum_return_status ensure_commit_group_sidnos(rpl_sidno sidno)
Ensure that commit_group_sidnos have room for the SIDNO passed as parameter.
Definition: rpl_gtid_state.cc:956
void update_gtids_impl_own_anonymous(THD *thd, bool *more_trx)
Handle the case that the thread owns ANONYMOUS GTID.
Definition: rpl_gtid_state.cc:922
bool wait_for_gtid(THD *thd, const Gtid &gtid, struct timespec *abstime=nullptr)
This is only a shorthand for wait_for_sidno, which contains additional debug printouts and assertions...
Definition: rpl_gtid_state.cc:288
void acquire_anonymous_ownership()
Acquire anonymous ownership.
Definition: rpl_gtid.h:2834
void update_on_rollback(THD *thd)
Update the state after the given thread has rollbacked.
Definition: rpl_gtid_state.cc:209
Gtid_set gtids_only_in_table
Definition: rpl_gtid.h:3392
rpl_gno get_automatic_gno(rpl_sidno sidno) const
Computes the next available GNO.
Definition: rpl_gtid_state.cc:411
Gtid_set executed_gtids
Definition: rpl_gtid.h:3387
void update_gtids_impl_own_gtid(THD *thd, bool is_commit)
Handle the case that the thread own a single non-anonymous GTID.
Definition: rpl_gtid_state.cc:854
int32 get_automatic_gtid_violating_transaction_count()
Return the number of ongoing GTID-violating transactions having GTID_NEXT=AUTOMATIC.
Definition: rpl_gtid.h:2912
void dbug_print(const char *text="") const
Print this Gtid_state to the trace file if debug is enabled; no-op otherwise.
Definition: rpl_gtid.h:3260
void update_commit_group(THD *first_thd)
This function updates both the THD and the Gtid_state to reflect that the transaction set of transact...
Definition: rpl_gtid_state.cc:154
void unlock_sidno(rpl_sidno sidno)
Unlocks a mutex for the given SIDNO.
Definition: rpl_gtid.h:3080
bool is_owned(const Gtid &gtid) const
Returns true if GTID is owned, otherwise returns 0.
Definition: rpl_gtid.h:2767
int to_string(char *buf) const
Debug only: Generate a string in the given buffer and return the length.
Definition: rpl_gtid.h:3230
bool is_executed(const Gtid &gtid) const
Returns true if the given GTID is logged.
Definition: rpl_gtid.h:2754
Prealloced_array< bool, 8 > commit_group_sidnos
This array is used by Gtid_state_update_gtids_impl* functions.
Definition: rpl_gtid.h:3648
void update_prev_gtids(Gtid_set *write_gtid_set)
Updates previously logged GTID set before writing to table.
Definition: rpl_gtid_state.cc:596
Checkable_rwlock * sid_lock
Read-write lock that protects updates to the number of SIDs.
Definition: rpl_gtid.h:3373
void end_gtid_violating_transaction(THD *thd)
Definition: rpl_gtid_state.cc:252
void begin_automatic_gtid_violating_transaction()
Increase the global counter when starting a GTID-violating transaction having GTID_NEXT=AUTOMATIC.
Definition: rpl_gtid.h:2870
void update_gtids_impl_broadcast_and_unlock_sidnos()
Unlocks all locked sidnos after broadcasting their changes.
Definition: rpl_gtid_state.cc:914
void lock_sidno(rpl_sidno sidno)
Locks a mutex for the given SIDNO.
Definition: rpl_gtid.h:3078
void update_gtids_impl_own_gtid_set(THD *thd, bool is_commit)
Handle the case that the thread own a set of GTIDs.
Definition: rpl_gtid_state.cc:799
void broadcast_sidnos(const Gtid_set *set)
Broadcasts the condition variable for each SIDNO where the given Gtid_set has at least one GTID.
Definition: rpl_gtid_state.cc:562
size_t get_max_string_length() const
Debug only: Returns an upper bound on the length of the string generated by to_string(),...
Definition: rpl_gtid.h:3223
std::atomic< int32 > atomic_automatic_gtid_violation_count
The number of GTID-violating transactions that use GTID_NEXT=AUTOMATIC.
Definition: rpl_gtid.h:3403
std::atomic< int32 > atomic_gtid_wait_count
The number of clients that are executing WAIT_FOR_EXECUTED_GTID_SET or WAIT_UNTIL_SQL_THREAD_AFTER_GT...
Definition: rpl_gtid.h:3408
void end_anonymous_gtid_violating_transaction()
Decrease the global counter when ending a GTID-violating transaction having GTID_NEXT=ANONYMOUS.
Definition: rpl_gtid.h:2938
rpl_gno get_last_executed_gno(rpl_sidno sidno) const
Return the last executed GNO for a given SIDNO, e.g.
Definition: rpl_gtid_state.cc:461
int clear(THD *thd)
Reset the state and persistor after RESET MASTER: remove all logged and lost gtids,...
Definition: rpl_gtid_state.cc:55
std::atomic< int32 > atomic_anonymous_gtid_violation_count
The number of GTID-violating transactions that use GTID_NEXT=AUTOMATIC.
Definition: rpl_gtid.h:3405
void update_on_commit(THD *thd)
Remove the GTID owned by thread from owned GTIDs, stating that thd->owned_gtid was committed.
Definition: rpl_gtid_state.cc:202
void update_gtids_impl_lock_sidnos(THD *thd)
Locks the sidnos of all the GTIDs of the commit group starting on the transaction passed as parameter...
Definition: rpl_gtid_state.cc:833
int32 get_anonymous_ownership_count()
Return the number of clients that hold anonymous ownership.
Definition: rpl_gtid.h:2864
void update_gtids_impl_end(THD *thd, bool more_trx)
Handle the final part of update_gtids_impl.
Definition: rpl_gtid_state.cc:952
int save(THD *thd)
Save gtid owned by the thd into executed_gtids variable and gtid_executed table.
Definition: rpl_gtid_state.cc:674
bool update_gtids_impl_begin(THD *thd)
This is a sub task of update_gtids_impl responsible only to evaluate if the thread is committing in t...
Definition: rpl_gtid_state.cc:789
void broadcast_sidno(rpl_sidno sidno)
Broadcasts updates for the given SIDNO.
Definition: rpl_gtid.h:3082
void release_anonymous_ownership()
Release anonymous ownership.
Definition: rpl_gtid.h:2849
void begin_gtid_wait()
Increase the global counter when starting a call to WAIT_FOR_EXECUTED_GTID_SET or WAIT_UNTIL_SQL_THRE...
Definition: rpl_gtid.h:2970
void update_gtids_impl(THD *thd, bool is_commit)
Remove the GTID owned by thread from owned GTIDs.
Definition: rpl_gtid_state.cc:216
Represents a growable array where each element contains a mutex and a condition variable.
Definition: rpl_gtid.h:912
Prealloced_array< Mutex_cond *, 8 > m_array
Definition: rpl_gtid.h:1035
bool is_thd_killed(const THD *thd) const
Return true if the given THD is killed.
Definition: rpl_gtid_mutex_cond_array.cc:95
void enter_cond(THD *thd, int n, PSI_stage_info *stage, PSI_stage_info *old_stage) const
Execute THD::enter_cond for the n'th condition variable.
Definition: rpl_gtid_mutex_cond_array.cc:65
Checkable_rwlock * global_lock
Read-write lock that protects updates to the number of elements.
Definition: rpl_gtid.h:1034
bool wait(const THD *thd, int sidno, struct timespec *abstime) const
Wait for signal on the n'th condition variable.
Definition: rpl_gtid.h:974
Mutex_cond_array(Checkable_rwlock *global_lock)
Create a new Mutex_cond_array.
Definition: rpl_gtid_mutex_cond_array.cc:41
void broadcast(int n) const
Broadcast the n'th condition.
Definition: rpl_gtid.h:934
void assert_not_owner(int n) const
Assert that this thread does not own the n'th mutex.
Definition: rpl_gtid.h:950
~Mutex_cond_array()
Destroy this object.
Definition: rpl_gtid_mutex_cond_array.cc:47
void assert_owner(int n) const
Assert that this thread owns the n'th mutex.
Definition: rpl_gtid.h:941
void unlock(int n) const
Unlock the n'th mutex.
Definition: rpl_gtid.h:929
void lock(int n) const
Lock the n'th mutex.
Definition: rpl_gtid.h:924
Mutex_cond * get_mutex_cond(int n) const
Return the Nth Mutex_cond object.
Definition: rpl_gtid.h:1026
Iterator over all gtids in a Owned_gtids set.
Definition: rpl_gtid.h:2605
rpl_sidno max_sidno
Max SIDNO of the current iterator.
Definition: rpl_gtid.h:2660
Node * node
Current node on current SIDNO hash.
Definition: rpl_gtid.h:2667
malloc_unordered_multimap< rpl_gno, unique_ptr_my_free< Node > >::const_iterator node_it
Current node iterator on current SIDNO hash.
Definition: rpl_gtid.h:2665
const Owned_gtids * owned_gtids
The Owned_gtids set we iterate over.
Definition: rpl_gtid.h:2656
Node * get_node() const
Return the current GTID Node, or NULL if we reached the end.
Definition: rpl_gtid.h:2652
Gtid_iterator(const Owned_gtids *og)
Definition: rpl_gtid.h:2607
Gtid get() const
Return next GTID, or {0,0} if we reached the end.
Definition: rpl_gtid.h:2643
void next()
Advance to next GTID.
Definition: rpl_gtid.h:2617
rpl_sidno sidno
The SIDNO of the current element, or 1 in the initial iteration.
Definition: rpl_gtid.h:2658
malloc_unordered_multimap< rpl_gno, unique_ptr_my_free< Node > > * hash
Current SIDNO hash.
Definition: rpl_gtid.h:2662
Represents the set of GTIDs that are owned by some thread.
Definition: rpl_gtid.h:2416
size_t get_max_string_length() const
Return an upper bound on the length of the string representation of this Owned_gtids.
Definition: rpl_gtid.h:2511
char * to_string() const
Debug only: return a newly allocated string representation of this Owned_gtids.
Definition: rpl_gtid.h:2543
bool thread_owns_anything(my_thread_id thd_id) const
Return true if the given thread is the owner of any gtids.
Definition: rpl_gtid.h:2527
enum_return_status add_gtid_owner(const Gtid &gtid, my_thread_id owner)
Add a GTID to this Owned_gtids.
Definition: rpl_gtid_owned.cc:69
bool is_intersection_nonempty(const Gtid_set *other) const
Returns true if there is a least one element of this Owned_gtids set in the other Gtid_set.
Definition: rpl_gtid_owned.cc:103
bool is_owned_by(const Gtid &gtid, const my_thread_id thd_id) const
If thd_id==0, returns true when gtid is not owned by any thread.
Definition: rpl_gtid_owned.cc:137
bool is_empty() const
Returns true if this Owned_gtids is empty.
Definition: rpl_gtid.h:2468
int to_string(char *out) const
Write a string representation of this Owned_gtids to the given buffer.
Definition: rpl_gtid.h:2484
Owned_gtids(Checkable_rwlock *sid_lock)
Constructs a new, empty Owned_gtids object.
Definition: rpl_gtid_owned.cc:38
rpl_sidno get_max_sidno() const
Returns the maximal sidno that this Owned_gtids currently has space for.
Definition: rpl_gtid.h:2473
malloc_unordered_multimap< rpl_gno, unique_ptr_my_free< Node > > * get_hash(rpl_sidno sidno) const
Returns the hash for the given SIDNO.
Definition: rpl_gtid.h:2586
Prealloced_array< malloc_unordered_multimap< rpl_gno, unique_ptr_my_free< Node > > *, 8 > sidno_to_hash
Growable array of hashes.
Definition: rpl_gtid.h:2598
void dbug_print(const char *text="") const
Print this Owned_gtids to the trace file if debug is enabled; no-op otherwise.
Definition: rpl_gtid.h:2561
void get_gtids(Gtid_set &gtid_set) const
Definition: rpl_gtid_owned.cc:116
bool contains_gtid(const Gtid &gtid) const
Return true iff this Owned_gtids object contains the given gtid.
Definition: rpl_gtid_owned.cc:130
Checkable_rwlock * sid_lock
Read-write lock that protects updates to the number of SIDs.
Definition: rpl_gtid.h:2584
~Owned_gtids()
Destroys this Owned_gtids.
Definition: rpl_gtid_owned.cc:42
void print() const
Debug only: print this Owned_gtids to stdout.
Definition: rpl_gtid.h:2551
enum_return_status ensure_sidno(rpl_sidno sidno)
Ensures that this Owned_gtids object can accommodate SIDNOs up to the given SIDNO.
Definition: rpl_gtid_owned.cc:55
void remove_gtid(const Gtid &gtid, const my_thread_id owner)
Removes the given GTID.
Definition: rpl_gtid_owned.cc:88
A typesafe replacement for DYNAMIC_ARRAY.
Definition: prealloced_array.h:70
Represents a bidirectional map between SID and SIDNO.
Definition: rpl_gtid.h:723
~Sid_map()
Destroy this Sid_map.
Definition: rpl_gtid_sid_map.cc:52
malloc_unordered_map< rpl_sid, unique_ptr_my_free< Node >, binary_log::Hash_Uuid > _sid_to_sidno
Hash that maps SID to SIDNO.
Definition: rpl_gtid.h:880
Checkable_rwlock * sid_lock
Read-write lock that protects updates to the number of SIDNOs.
Definition: rpl_gtid.h:869
rpl_sidno get_sorted_sidno(rpl_sidno n) const
Return the n'th smallest sidno, in the order of the SID's UUID.
Definition: rpl_gtid.h:810
rpl_sidno sid_to_sidno(const rpl_sid &sid) const
Get the SIDNO for a given SID.
Definition: rpl_gtid.h:764
rpl_sidno add_sid(const rpl_sid &sid)
Add the given SID to this map if it does not already exist.
Definition: rpl_gtid_sid_map.cc:62
enum_return_status add_node(rpl_sidno sidno, const rpl_sid &sid)
Create a Node from the given SIDNO and SID and add it to _sidno_to_sid, _sid_to_sidno,...
Definition: rpl_gtid_sid_map.cc:103
static const uchar * sid_map_get_key(const uchar *ptr, size_t *length)
Definition: rpl_gtid.h:849
rpl_sidno get_max_sidno() const
Return the biggest sidno in this Sid_map.
Definition: rpl_gtid.h:820
Prealloced_array< Node *, 8 > _sidno_to_sid
Array that maps SIDNO to SID; the element at index N points to a Node with SIDNO N-1.
Definition: rpl_gtid.h:875
Prealloced_array< rpl_sidno, 8 > _sorted
Array that maps numbers in the interval [0, get_max_sidno()-1] to SIDNOs, in order of increasing SID.
Definition: rpl_gtid.h:887
Checkable_rwlock * get_sid_lock() const
Return the sid_lock.
Definition: rpl_gtid.h:826
enum_return_status copy(Sid_map *dest)
Deep copy this Sid_map to dest.
Definition: rpl_gtid_sid_map.cc:152
enum_return_status clear()
Clears this Sid_map (for RESET SLAVE)
Definition: rpl_gtid_sid_map.cc:54
const rpl_sid & sidno_to_sid(rpl_sidno sidno, bool need_lock=false) const
Get the SID for a given SIDNO.
Definition: rpl_gtid.h:790
Sid_map(Checkable_rwlock *sid_lock)
Create this Sid_map.
Definition: rpl_gtid_sid_map.cc:45
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:166
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:922
std::unordered_map, but with my_malloc, so that you can track the memory used using PSI memory keys.
Definition: map_helpers.h:147
std::unordered_multimap, but with my_malloc, so that you can track the memory used using PSI memory k...
Definition: map_helpers.h:188
#define mysql_cond_wait(C, M)
Definition: mysql_cond.h:47
#define mysql_cond_timedwait(C, M, T)
Definition: mysql_cond.h:50
#define mysql_mutex_lock(M)
Definition: mysql_mutex.h:49
#define mysql_mutex_unlock(M)
Definition: mysql_mutex.h:56
#define mysql_rwlock_rdlock(T)
Definition: mysql_rwlock.h:60
#define mysql_rwlock_unlock(T)
Definition: mysql_rwlock.h:90
#define mysql_rwlock_init(K, T)
Definition: mysql_rwlock.h:40
#define mysql_rwlock_tryrdlock(T)
Definition: mysql_rwlock.h:80
#define mysql_rwlock_destroy(T)
Definition: mysql_rwlock.h:50
#define mysql_rwlock_trywrlock(T)
Definition: mysql_rwlock.h:85
#define mysql_rwlock_wrlock(T)
Definition: mysql_rwlock.h:70
const char * p
Definition: ctype-mb.cc:1236
DBUG_TRACE
Definition: do_ctype.cc:46
Fido Client Authentication nullptr
Definition: fido_client_plugin.cc:221
#define MY_WME
Definition: my_sys.h:122
unsigned int PSI_memory_key
Instrumented memory key.
Definition: psi_memory_bits.h:48
unsigned int PSI_mutex_key
Instrumented mutex key.
Definition: psi_mutex_bits.h:51
unsigned int PSI_rwlock_key
Instrumented rwlock key.
Definition: psi_rwlock_bits.h:43
#define mysql_mutex_assert_not_owner(M)
Wrapper, to use safe_mutex_assert_not_owner with instrumented mutexes.
Definition: mysql_mutex.h:125
#define mysql_mutex_assert_owner(M)
Wrapper, to use safe_mutex_assert_owner with instrumented mutexes.
Definition: mysql_mutex.h:111
static void start(mysql_harness::PluginFuncEnv *env)
Definition: http_auth_backend_plugin.cc:168
#define DBUG_PRINT(keyword, arglist)
Definition: my_dbug.h:180
unsigned long long int ulonglong
Definition: my_inttypes.h:55
unsigned char uchar
Definition: my_inttypes.h:51
int64_t int64
Definition: my_inttypes.h:67
#define MYF(v)
Definition: my_inttypes.h:96
int32_t int32
Definition: my_inttypes.h:65
void * my_malloc(PSI_memory_key key, size_t size, int flags)
Allocates size bytes of memory.
Definition: my_memory.cc:56
void my_free(void *ptr)
Frees the memory pointed by the ptr.
Definition: my_memory.cc:80
#define HAVE_PSI_INTERFACE
Definition: my_psi_config.h:38
static int is_timeout(int e)
Definition: my_thread.h:56
uint32 my_thread_id
Definition: my_thread_local.h:33
int(* mysql_cond_broadcast)(mysql_cond_t *that, const char *src_file, unsigned int src_line)
Definition: mysql_cond_service.h:51
Log info(cout, "NOTE")
void copy(Shards< COUNT > &dst, const Shards< COUNT > &src) noexcept
Copy the counters, overwrite destination.
Definition: ut0counter.h:353
Type sub(Shards< COUNT > &shards, size_t id, size_t n)
Decrement the counter for a shard by n.
Definition: ut0counter.h:279
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1055
std::int64_t gno_t
Definition: global.h:32
Definition: buf0block_hint.cc:29
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:75
Provides atomic access in shared-exclusive modes.
Definition: shared_spin_lock.h:78
static bool timeout(bool(*wait_condition)())
Timeout function.
Definition: log0meb.cc:495
HARNESS_EXPORT std::string string_format(const char *format,...)
Definition: utilities.cc:63
static mysql_service_status_t flush(reference_caching_cache cache) noexcept
Definition: component.cc:121
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:191
mode
Definition: file_handle.h:59
std::set< Key, Compare, ut::allocator< Key > > set
Specialization of set which uses ut_allocator.
Definition: ut0new.h:2863
static std::mutex lock
Definition: net_ns.cc:55
Instrumentation helpers for conditions.
Instrumentation helpers for rwlock.
PSI_memory_key key_memory_Sid_map_Node
Definition: rpl_gtid_sid_map.cc:43
required uint32 status
Definition: replication_asynchronous_connection_failover.proto:60
repeated Action action
Definition: replication_group_member_actions.proto:42
Sid_map * global_sid_map
Definition: mysqld.cc:1804
rpl_gno get_last_executed_gno(rpl_sidno sidno)
Return last gno for a given sidno, see Gtid_state::get_last_executed_gno() for details.
Definition: rpl_gtid_misc.cc:226
const int MAX_THREAD_ID_TEXT_LENGTH
The maximal possible length of thread_id when printed in decimal.
Definition: rpl_gtid.h:272
const rpl_gno GNO_WARNING_THRESHOLD
If the GNO goes above the number, generate a warning.
Definition: rpl_gtid.h:268
ulong _gtid_consistency_mode
Current value for ENFORCE_GTID_CONSISTENCY.
Definition: rpl_gtid_misc.cc:39
const rpl_gno GNO_END
One-past-the-max value of GNO.
Definition: rpl_gtid.h:266
enum_return_status map_macro_enum(int status)
enum to map the result of Uuid::parse to the above Macros
Definition: rpl_gtid.h:218
enum_gtid_consistency_mode get_gtid_consistency_mode()
Return the current value of ENFORCE_GTID_CONSISTENCY.
Definition: rpl_gtid_misc.cc:63
void gtid_state_commit_or_rollback(THD *thd, bool needs_to, bool do_commit)
The function commits or rolls back the gtid state if it needs to.
Definition: rpl_gtid.h:4034
PSI_memory_key key_memory_Gtid_cache_to_string
enum_return_status
Generic return type for many functions that can succeed or fail.
Definition: rpl_gtid.h:121
@ RETURN_STATUS_OK
The function completed successfully.
Definition: rpl_gtid.h:123
@ RETURN_STATUS_UNREPORTED_ERROR
The function completed with error but did not report it.
Definition: rpl_gtid.h:125
@ RETURN_STATUS_REPORTED_ERROR
The function completed with error and has called my_error.
Definition: rpl_gtid.h:127
bool set_gtid_next(THD *thd, const Gtid_specification &spec)
Acquire ownership of the given Gtid_specification.
Definition: rpl_gtid_execution.cc:45
const char * gtid_consistency_mode_names[]
Strings holding the enumeration values for gtid_consistency_mode_names.
Definition: rpl_gtid_misc.cc:57
int rpl_sidno
Type of SIDNO (source ID number, first component of GTID)
Definition: rpl_gtid.h:95
int format_gno(char *s, rpl_gno gno)
Formats a GNO as a string.
Definition: rpl_gtid_set.cc:419
Gtid_mode global_gtid_mode
The one and only instance of Gtid_mode.
Definition: rpl_gtid_mode.cc:29
const int MAX_GNO_TEXT_LENGTH
The length of MAX_GNO when printed in decimal.
Definition: rpl_gtid.h:270
PSI_memory_key key_memory_Gtid_state_group_commit_sidno
Definition: rpl_gtid_state.cc:51
bool is_already_logged_transaction(const THD *thd)
Check if current transaction should be skipped, that is, if GTID_NEXT was already logged.
Definition: rpl_gtid_execution.cc:305
void gtid_set_performance_schema_values(const THD *thd)
Definition: rpl_gtid_execution.cc:574
bool gtid_reacquire_ownership_if_anonymous(THD *thd)
If gtid_next=ANONYMOUS or NOT_YET_DETERMINED, but the thread does not hold anonymous ownership,...
Definition: rpl_gtid_execution.cc:358
enum_gtid_statement_status
Indicates if a statement should be skipped or not.
Definition: rpl_gtid.h:3891
@ GTID_STATEMENT_CANCEL
Statement should be cancelled.
Definition: rpl_gtid.h:3895
@ GTID_STATEMENT_EXECUTE
Statement can execute.
Definition: rpl_gtid.h:3893
@ GTID_STATEMENT_SKIP
Statement should be skipped, but there may be an implicit commit after the statement if gtid_commit i...
Definition: rpl_gtid.h:3900
bool gtid_pre_statement_post_implicit_commit_checks(THD *thd)
Perform GTID-related checks before executing a statement, but after executing an implicit commit befo...
Definition: rpl_gtid_execution.cc:544
int64 rpl_binlog_pos
Definition: rpl_gtid.h:103
binary_log::gtids::gno_t rpl_gno
GNO, the second (numeric) component of a GTID, is an alias of binary_log::gtids::gno_t.
Definition: rpl_gtid.h:102
rpl_gno parse_gno(const char **s)
Parse a GNO from a string.
Definition: rpl_gtid_set.cc:411
PSI_memory_key key_memory_Gtid_set_Interval_chunk
Definition: rpl_gtid_set.cc:65
const char * get_gtid_consistency_mode_string(enum_gtid_consistency_mode mode)
Return the given GTID_CONSISTENCY_MODE as a string.
Definition: rpl_gtid.h:252
Gtid_state * gtid_state
Global state of GTIDs.
Definition: mysqld.cc:1805
rpl_sidno get_sidno_from_global_sid_map(rpl_sid sid)
Return sidno for a given sid, see Sid_map::add_sid() for details.
Definition: rpl_gtid_misc.cc:216
Checkable_rwlock * global_sid_lock
Protects Gtid_state. See comment above gtid_state for details.
Definition: mysqld.cc:1803
PSI_memory_key key_memory_Gtid_set_to_string
Definition: rpl_gtid_set.cc:64
#define RETURN_OK
Returns RETURN_STATUS_OK.
Definition: rpl_gtid.h:209
std::ostream & operator<<(std::ostream &oss, Gtid_mode::value_type const &mode)
Definition: rpl_gtid_mode.cc:70
enum_gtid_consistency_mode
Possible values for ENFORCE_GTID_CONSISTENCY.
Definition: rpl_gtid.h:229
@ GTID_CONSISTENCY_MODE_ON
Definition: rpl_gtid.h:231
@ GTID_CONSISTENCY_MODE_WARN
Definition: rpl_gtid.h:232
@ GTID_CONSISTENCY_MODE_OFF
Definition: rpl_gtid.h:230
PSI_memory_key key_memory_Owned_gtids_to_string
Definition: psi_memory_key.cc:66
enum_gtid_type
Enumeration of different types of values for Gtid_specification, i.e, the different internal states t...
Definition: rpl_gtid.h:3676
@ UNDEFINED_GTID
GTID_NEXT is set to this state after a transaction with GTID_NEXT=='UUID:NUMBER' is committed.
Definition: rpl_gtid.h:3742
@ ANONYMOUS_GTID
Specifies that the transaction is anonymous, i.e., it does not have a GTID and will never be assigned...
Definition: rpl_gtid.h:3708
@ ASSIGNED_GTID
Specifies that the transaction has been assigned a GTID (UUID:NUMBER).
Definition: rpl_gtid.h:3698
@ PRE_GENERATE_GTID
The applier sets GTID_NEXT this state internally, when it processes an Anonymous_gtid_log_event on a ...
Definition: rpl_gtid.h:3779
@ NOT_YET_DETERMINED_GTID
Definition: rpl_gtid.h:3769
@ AUTOMATIC_GTID
Specifies that the GTID has not been generated yet; it will be generated on commit.
Definition: rpl_gtid.h:3690
void check_return_status(enum_return_status status, const char *action, const char *status_name, int allow_unreported)
Definition: rpl_gtid_misc.cc:190
binary_log::Uuid rpl_sid
Definition: rpl_gtid.h:292
enum_gtid_statement_status gtid_pre_statement_checks(THD *thd)
Perform GTID-related checks before executing a statement:
Definition: rpl_gtid_execution.cc:436
#define RETURN_UNREPORTED_ERROR
Does a DBUG_PRINT and returns RETURN_STATUS_UNREPORTED_ERROR.
Definition: rpl_gtid.h:213
PSI_memory_key key_memory_Gtid_state_to_string
Definition: psi_memory_key.cc:49
#define MAX_SLAVE_ERRMSG
Maximum size of an error message from a slave thread.
Definition: rpl_reporting.h:41
Holds information about a GTID interval: the sidno, the first gno and the last gno of this interval.
Definition: rpl_gtid.h:1042
rpl_gno gno_start
Definition: rpl_gtid.h:1046
rpl_gno gno_end
Definition: rpl_gtid.h:1048
void set(rpl_sidno sid_no, rpl_gno start, rpl_gno end)
Definition: rpl_gtid.h:1049
rpl_sidno sidno
Definition: rpl_gtid.h:1044
Contains a list of intervals allocated by this Gtid_set.
Definition: rpl_gtid.h:2112
Interval intervals[1]
Definition: rpl_gtid.h:2114
Interval_chunk * next
Definition: rpl_gtid.h:2113
Represents one element in the linked list of intervals associated with a SIDNO.
Definition: rpl_gtid.h:1892
rpl_gno start
The first GNO of this interval.
Definition: rpl_gtid.h:1895
rpl_gno end
The first GNO after this interval.
Definition: rpl_gtid.h:1897
bool equals(const Interval &other) const
Return true iff this interval is equal to the given interval.
Definition: rpl_gtid.h:1899
Interval * next
Pointer to next interval in list.
Definition: rpl_gtid.h:1903
Class Gtid_set::String_format defines the separators used by Gtid_set::to_string.
Definition: rpl_gtid.h:1762
const int sid_gno_separator_length
Definition: rpl_gtid.h:1780
const char * end
The generated string begins with this.
Definition: rpl_gtid.h:1766
const int begin_length
The following fields are the lengths of each field above.
Definition: rpl_gtid.h:1778
const int gno_start_end_separator_length
Definition: rpl_gtid.h:1781
const char * gno_sid_separator
In 'SID:GNO,SID:GNO', this is the ','.
Definition: rpl_gtid.h:1774
const char * sid_gno_separator
In 'SID:GNO', this is the ':'.
Definition: rpl_gtid.h:1768
const int empty_set_string_length
Definition: rpl_gtid.h:1784
const int gno_gno_separator_length
Definition: rpl_gtid.h:1782
const char * begin
The generated string begins with this.
Definition: rpl_gtid.h:1764
const char * empty_set_string
If the set is empty and this is not NULL, then this string is generated.
Definition: rpl_gtid.h:1776
const char * gno_gno_separator
In 'SID:GNO:GNO', this is the second ':'.
Definition: rpl_gtid.h:1772
const char * gno_start_end_separator
In 'SID:GNO-GNO', this is the '-'.
Definition: rpl_gtid.h:1770
const int gno_sid_separator_length
Definition: rpl_gtid.h:1783
const int end_length
Definition: rpl_gtid.h:1779
Holds information about a Gtid_set.
Definition: rpl_gtid.h:2369
Gtid_set * gtid_set
Pointer to the Gtid_set.
Definition: rpl_gtid.h:2371
Gtid_set * set_non_null(Sid_map *sm)
Do nothing if this object is non-null; set to empty set otherwise.
Definition: rpl_gtid.h:2384
Gtid_set * get_gtid_set() const
Return NULL if this is NULL, otherwise return the Gtid_set.
Definition: rpl_gtid.h:2375
void set_null()
Set this Gtid_set to NULL.
Definition: rpl_gtid.h:2395
bool is_non_null
True if this Gtid_set is NULL.
Definition: rpl_gtid.h:2373
This struct represents a specification of a GTID for a statement to be executed: either "AUTOMATIC",...
Definition: rpl_gtid.h:3790
void set_not_yet_determined()
Set the type to NOT_YET_DETERMINED_GTID.
Definition: rpl_gtid.h:3811
enum_gtid_type type
The type of this GTID.
Definition: rpl_gtid.h:3792
static bool is_valid(const char *text)
Returns true if the given string is a valid Gtid_specification.
Definition: rpl_gtid_specification.cc:52
Gtid gtid
The GTID: { SIDNO, GNO } if type == GTID; { 0, 0 } if type == AUTOMATIC or ANONYMOUS.
Definition: rpl_gtid.h:3798
bool equals(const Gtid_specification &other) const
Return true if this Gtid_specification is equal to 'other'.
Definition: rpl_gtid.h:3818
int to_string(const Sid_map *sid_map, char *buf, bool need_lock=false) const
Writes this Gtid_specification to the given string buffer.
Definition: rpl_gtid_specification.cc:97
void set(const Gtid &gtid_param)
Set the type to ASSIGNED_GTID and SID, GNO to the given Gtid.
Definition: rpl_gtid.h:3805
static const int MAX_TEXT_LENGTH
Definition: rpl_gtid.h:3841
void dbug_print(const char *text="", bool need_lock=false) const
Print this Gtid_specification to the trace file if debug is enabled; no-op otherwise.
Definition: rpl_gtid.h:3877
enum_return_status parse(Sid_map *sid_map, const char *text)
Parses the given string and stores in this Gtid_specification.
Definition: rpl_gtid_specification.cc:33
void set_anonymous()
Set the type to ANONYMOUS_GTID.
Definition: rpl_gtid.h:3809
void set_undefined()
Set to undefined. Must only be called if the type is ASSIGNED_GTID.
Definition: rpl_gtid.h:3813
void set_automatic()
Set the type to AUTOMATIC_GTID.
Definition: rpl_gtid.h:3807
void set(rpl_sidno sidno, rpl_gno gno)
Set the type to ASSIGNED_GTID and SID, GNO to the given values.
Definition: rpl_gtid.h:3800
bool equals(const Gtid &other_gtid) const
Return true if this Gtid_specification is a ASSIGNED_GTID with the same SID, GNO as 'other_gtid'.
Definition: rpl_gtid.h:3826
void print() const
Debug only: print this Gtid_specification to stdout.
Definition: rpl_gtid.h:3867
TODO: Move this structure to libbinlogevents/include/control_events.h when we start using C++11.
Definition: rpl_gtid.h:1065
static const int MAX_TEXT_LENGTH
The maximal length of the textual representation of a SID, not including the terminating '\0'.
Definition: rpl_gtid.h:1100
void print(const Sid_map *sid_map) const
Debug only: print this Gtid to stdout.
Definition: rpl_gtid.h:1141
bool is_empty() const
Return true if sidno is zero (and assert that gno is zero too in this case).
Definition: rpl_gtid.h:1088
void dbug_print(const Sid_map *sid_map, const char *text="", bool need_lock=false) const
Print this Gtid to the trace file if debug is enabled; no-op otherwise.
Definition: rpl_gtid.h:1148
void set(rpl_sidno sidno_arg, rpl_gno gno_arg)
Set both components to the given, positive values.
Definition: rpl_gtid.h:1077
void clear()
Set both components to 0.
Definition: rpl_gtid.h:1072
rpl_gno gno
GNO of this Gtid.
Definition: rpl_gtid.h:1069
enum_return_status parse(Sid_map *sid_map, const char *text)
Parses the given string and stores in this Gtid.
Definition: rpl_gtid_misc.cc:69
rpl_sidno sidno
SIDNO of this Gtid.
Definition: rpl_gtid.h:1067
bool equals(const Gtid &other) const
Returns true if this Gtid has the same sid and gno as 'other'.
Definition: rpl_gtid.h:1127
static bool is_valid(const char *text)
Return true if parse() would succeed, but don't store the result anywhere.
Definition: rpl_gtid_misc.cc:156
int to_string(const rpl_sid &sid, char *buf) const
Convert a Gtid to a string.
Definition: rpl_gtid_misc.cc:117
Struct representing a duration.
Definition: my_time.h:225
A mutex/cond pair.
Definition: rpl_gtid.h:1021
mysql_mutex_t mutex
Definition: rpl_gtid.h:1022
mysql_cond_t cond
Definition: rpl_gtid.h:1023
Represents one owned GTID.
Definition: rpl_gtid.h:2577
my_thread_id owner
Owner of the GTID.
Definition: rpl_gtid.h:2581