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