MySQL 8.0.40
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 /**
1496 Claim ownership of memory.
1497
1498 @param claim claim ownership of memory.
1499 */
1500 void claim_memory_ownership(bool claim);
1501
1502 /**
1503 Removes all gtids from this Gtid_set.
1504
1505 This does not deallocate anything: if gtids are added later,
1506 existing allocated memory will be re-used.
1507 */
1508 void clear();
1509 /**
1510 Removes all gtids from this Gtid_set and clear all the sidnos
1511 used by the Gtid_set and it's SID map.
1512
1513 This does not deallocate anything: if gtids are added later,
1514 existing allocated memory will be re-used.
1515 */
1516 void clear_set_and_sid_map();
1517 /**
1518 Adds the given GTID to this Gtid_set.
1519
1520 The SIDNO must exist in the Gtid_set before this function is called.
1521
1522 @param sidno SIDNO of the GTID to add.
1523 @param gno GNO of the GTID to add.
1524 */
1525 void _add_gtid(rpl_sidno sidno, rpl_gno gno) {
1526 DBUG_TRACE;
1527 assert(sidno > 0);
1528 assert(gno > 0);
1529 assert(gno < GNO_END);
1530 Interval_iterator ivit(this, sidno);
1532 add_gno_interval(&ivit, gno, gno + 1, &lock);
1533 return;
1534 }
1535 /**
1536 Removes the given GTID from this Gtid_set.
1537
1538 @param sidno SIDNO of the GTID to remove.
1539 @param gno GNO of the GTID to remove.
1540 */
1541 void _remove_gtid(rpl_sidno sidno, rpl_gno gno) {
1542 DBUG_TRACE;
1543 if (sidno <= get_max_sidno()) {
1544 Interval_iterator ivit(this, sidno);
1546 remove_gno_interval(&ivit, gno, gno + 1, &lock);
1547 }
1548 return;
1549 }
1550 /**
1551 Adds the given GTID to this Gtid_set.
1552
1553 The SIDNO must exist in the Gtid_set before this function is called.
1554
1555 @param gtid Gtid to add.
1556 */
1557 void _add_gtid(const Gtid &gtid) { _add_gtid(gtid.sidno, gtid.gno); }
1558 /**
1559 Removes the given GTID from this Gtid_set.
1560
1561 @param gtid Gtid to remove.
1562 */
1563 void _remove_gtid(const Gtid &gtid) { _remove_gtid(gtid.sidno, gtid.gno); }
1564 /**
1565 Adds all gtids from the given Gtid_set to this Gtid_set.
1566
1567 If sid_lock != NULL, then the read lock must be held before
1568 calling this function. If a new sidno is added so that the array
1569 of lists of intervals is grown, sid_lock is temporarily upgraded
1570 to a write lock and then degraded again; there will be a short
1571 period when the lock is not held at all.
1572
1573 @param other The Gtid_set to add.
1574 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
1575 */
1577 /**
1578 Removes all gtids in the given Gtid_set from this Gtid_set.
1579
1580 @param other The Gtid_set to remove.
1581 */
1582 void remove_gtid_set(const Gtid_set *other);
1583 /**
1584 Removes all intervals of 'other' for a given SIDNO, from 'this'.
1585
1586 Example:
1587 this = A:1-100, B:1-100
1588 other = A:1-100, B:1-50, C:1-100
1589 this.remove_intervals_for_sidno(other, B) = A:1-100, B:51-100
1590
1591 It is not required that the intervals exist in this Gtid_set.
1592
1593 @param other The set to remove.
1594 @param sidno The sidno to remove.
1595 */
1596 void remove_intervals_for_sidno(Gtid_set *other, rpl_sidno sidno);
1597 /**
1598 Adds the set of GTIDs represented by the given string to this Gtid_set.
1599
1600 The string must have the format of a comma-separated list of zero
1601 or more of the following items:
1602
1603 XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX(:NUMBER+(-NUMBER)?)*
1604 | ANONYMOUS
1605
1606 Each X is a hexadecimal digit (upper- or lowercase).
1607 NUMBER is a decimal, 0xhex, or 0oct number.
1608
1609 The start of an interval must be greater than 0. The end of an
1610 interval may be 0, but any interval that has an endpoint that
1611 is smaller than the start is discarded.
1612
1613 The string can start with an optional '+' appender qualifier
1614 which triggers @c executed_gtids and @c lost_gtids set examination
1615 on the matter of disjointness with the one being added.
1616
1617 If sid_lock != NULL, then the read lock on sid_lock must be held
1618 before calling this function. If a new sidno is added so that the
1619 array of lists of intervals is grown, sid_lock is temporarily
1620 upgraded to a write lock and then degraded again; there will be a
1621 short period when the lock is not held at all.
1622
1623 @param text The string to parse.
1624 @param [in,out] anonymous If this is NULL, ANONYMOUS is not
1625 allowed. If this is not NULL, it will be set to true if the
1626 anonymous GTID was found; false otherwise.
1627 @param[in,out] starts_with_plus If this is not NULL, the string may
1628 optionally begin with a '+' character, and *starts_with_plus will
1629 be set to true if the plus character is present. If this is NULL,
1630 no plus is allowed at the begin of the string.
1631
1632 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
1633 */
1634 enum_return_status add_gtid_text(const char *text, bool *anonymous = nullptr,
1635 bool *starts_with_plus = nullptr);
1636 /**
1637 Decodes a Gtid_set from the given string.
1638
1639 @param encoded The string to parse.
1640 @param length The number of bytes.
1641 @param actual_length If this is not NULL, it is set to the number
1642 of bytes used by the encoding (which may be less than 'length').
1643 If this is NULL, an error is generated if the encoding is shorter
1644 than the given 'length'.
1645 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
1646 */
1647 enum_return_status add_gtid_encoding(const uchar *encoded, size_t length,
1648 size_t *actual_length = nullptr);
1649 /// Return true iff the given GTID exists in this set.
1650 bool contains_gtid(rpl_sidno sidno, rpl_gno gno) const;
1651 /// Return true iff the given GTID exists in this set.
1652 bool contains_gtid(const Gtid &gtid) const {
1653 return contains_gtid(gtid.sidno, gtid.gno);
1654 }
1655 // Get last gno or 0 if this set is empty.
1656 rpl_gno get_last_gno(rpl_sidno sidno) const;
1657 /// Returns the maximal sidno that this Gtid_set currently has space for.
1660 return static_cast<rpl_sidno>(m_intervals.size());
1661 }
1662 /**
1663 Allocates space for all sidnos up to the given sidno in the array of
1664 intervals. The sidno must exist in the Sid_map associated with this
1665 Gtid_set.
1666
1667 If sid_lock != NULL, then the read lock on sid_lock must be held
1668 before calling this function. If the array is grown, sid_lock is
1669 temporarily upgraded to a write lock and then degraded again;
1670 there will be a short period when the lock is not held at all.
1671
1672 @param sidno The SIDNO.
1673 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
1674 */
1676 /// Returns true if this Gtid_set is a subset of the other Gtid_set.
1677 bool is_subset(const Gtid_set *super) const;
1678 /// Returns true if this Gtid_set is a non equal subset of the other Gtid_set.
1679 bool is_subset_not_equals(const Gtid_set *super) const {
1680 return (is_subset(super) && !equals(super));
1681 }
1682
1683 /**
1684 Returns true if this Gtid_set is a subset of the given gtid_set
1685 on the given superset_sidno and subset_sidno.
1686
1687 @param super Gtid_set with which this->gtid_set needs to be
1688 compared
1689 @param superset_sidno The sidno that will be compared, relative to
1690 super->sid_map.
1691 @param subset_sidno The sidno that will be compared, relative to
1692 this->sid_map.
1693 @return true If 'this' Gtid_set is subset of given
1694 'super' Gtid_set.
1695 false If 'this' Gtid_set is *not* subset of given
1696 'super' Gtid_set.
1697 */
1698 bool is_subset_for_sid(const Gtid_set *super, rpl_sidno superset_sidno,
1699 rpl_sidno subset_sidno) const;
1700 /// Returns true if there is a least one element of this Gtid_set in
1701 /// the other Gtid_set.
1702 bool is_intersection_nonempty(const Gtid_set *other) const;
1703 /**
1704 Add the intersection of this Gtid_set and the other Gtid_set to result.
1705
1706 @param other The Gtid_set to intersect with this Gtid_set
1707 @param result Gtid_set where the result will be stored.
1708 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
1709 */
1711 /// Returns true if this Gtid_set is empty.
1712 bool is_empty() const {
1713 Gtid_iterator git(this);
1714 return git.get().sidno == 0;
1715 }
1716
1717 /**
1718 Return true if the size of the set is greater than or equal to the given
1719 number. The size is measure in number of GTIDs, i.e., total length of all
1720 intervals.
1721
1722 @param num Number to compare with
1723 @retval true if the set contains >= num GTIDs.
1724 @retval false if the set contains < num GTIDs.
1725 */
1727
1728 /**
1729 What is the count of all the GTIDs in all intervals for a sidno
1730
1731 @param sidno The sidno that contains the intervals
1732
1733 @return the number of all GTIDs in all intervals
1734 */
1736 Const_interval_iterator ivit(this, sidno);
1737 ulonglong ret = 0;
1738 while (ivit.get() != nullptr) {
1739 ret += ivit.get()->end - ivit.get()->start;
1740 ivit.next();
1741 }
1742 return ret;
1743 }
1744
1745 /**
1746 Returns true if this Gtid_set contains at least one GTID with
1747 the given SIDNO.
1748
1749 @param sidno The SIDNO to test.
1750 @retval true The SIDNO is less than or equal to the max SIDNO, and
1751 there is at least one GTID with this SIDNO.
1752 @retval false The SIDNO is greater than the max SIDNO, or there is
1753 no GTID with this SIDNO.
1754 */
1755 bool contains_sidno(rpl_sidno sidno) const {
1756 assert(sidno >= 1);
1757 if (sidno > get_max_sidno()) return false;
1758 Const_interval_iterator ivit(this, sidno);
1759 return ivit.get() != nullptr;
1760 }
1761 /**
1762 Returns true if the given string is a valid specification of a
1763 Gtid_set, false otherwise.
1764 */
1765 static bool is_valid(const char *text);
1766
1767 /**
1768 Class Gtid_set::String_format defines the separators used by
1769 Gtid_set::to_string.
1770 */
1772 /// The generated string begins with this.
1773 const char *begin;
1774 /// The generated string begins with this.
1775 const char *end;
1776 /// In 'SID:GNO', this is the ':'
1778 /// In 'SID:GNO-GNO', this is the '-'
1780 /// In 'SID:GNO:GNO', this is the second ':'
1782 /// In 'SID:GNO,SID:GNO', this is the ','
1784 /// If the set is empty and this is not NULL, then this string is generated.
1785 const char *empty_set_string;
1786 /// The following fields are the lengths of each field above.
1787 const int begin_length;
1788 const int end_length;
1794 };
1795 /**
1796 Returns the length of the output from to_string.
1797
1798 @warning This does not include the trailing '\0', so your buffer
1799 needs space for get_string_length() + 1 characters.
1800
1801 @param string_format String_format object that specifies
1802 separators in the resulting text.
1803 @return The length.
1804 */
1805 size_t get_string_length(const String_format *string_format = nullptr) const;
1806 /**
1807 Formats this Gtid_set as a string and saves in a given buffer.
1808
1809 @param[out] buf Pointer to the buffer where the string should be
1810 stored. This should have size at least get_string_length()+1.
1811 @param need_lock If this Gtid_set has a sid_lock, then the write
1812 lock must be held while generating the string. If this parameter
1813 is true, then this function acquires and releases the lock;
1814 otherwise it asserts that the caller holds the lock.
1815 @param string_format String_format object that specifies
1816 separators in the resulting text.
1817 @return Length of the generated string.
1818 */
1819 size_t to_string(char *buf, bool need_lock = false,
1820 const String_format *string_format = nullptr) const;
1821
1822 /**
1823 Formats a Gtid_set as a string and saves in a newly allocated buffer.
1824 @param[out] buf Pointer to pointer to string. The function will
1825 set it to point to the newly allocated buffer, or NULL on out of memory.
1826 @param need_lock If this Gtid_set has a sid_lock, then the write
1827 lock must be held while generating the string. If this parameter
1828 is true, then this function acquires and releases the lock;
1829 otherwise it asserts that the caller holds the lock.
1830 @param string_format Specifies how to format the string.
1831 @retval Length of the generated string, or -1 on out of memory.
1832 */
1833 long to_string(char **buf, bool need_lock = false,
1834 const String_format *string_format = nullptr) const;
1835#ifndef NDEBUG
1836 /// Debug only: Print this Gtid_set to stdout.
1837
1838 /// For use with C `printf`
1839 void print(bool need_lock = false,
1840 const Gtid_set::String_format *sf = nullptr) const {
1841 char *str;
1842 to_string(&str, need_lock, sf);
1843 printf("%s\n", str ? str : "out of memory in Gtid_set::print");
1844 my_free(str);
1845 }
1846
1847 /// For use with C++ `std::ostream`
1848 inline friend std::ostream &operator<<(std::ostream &os, const Gtid_set &in) {
1849 char *str;
1850 in.to_string(&str, true, nullptr);
1851 os << std::string(str) << std::flush;
1852 my_free(str);
1853 return os;
1854 }
1855#endif
1856 /**
1857 Print this Gtid_set to the trace file if debug is enabled; no-op
1858 otherwise.
1859 */
1860 void dbug_print(const char *text [[maybe_unused]] = "",
1861 bool need_lock [[maybe_unused]] = false,
1862 const Gtid_set::String_format *sf
1863 [[maybe_unused]] = nullptr) const {
1864#ifndef NDEBUG
1865 char *str;
1866 to_string(&str, need_lock, sf);
1867 DBUG_PRINT("info", ("%s%s'%s'", text, *text ? ": " : "",
1868 str ? str : "out of memory in Gtid_set::dbug_print"));
1869 my_free(str);
1870#endif
1871 }
1872 /**
1873 Gets all gtid intervals from this Gtid_set.
1874
1875 @param[out] gtid_intervals Store all gtid intervals from this Gtid_set.
1876 */
1877 void get_gtid_intervals(std::list<Gtid_interval> *gtid_intervals) const;
1878 /**
1879 The default String_format: the format understood by
1880 add_gtid_text(const char *).
1881 */
1883 /**
1884 String_format useful to generate an SQL string: the string is
1885 wrapped in single quotes and there is a newline between SIDs.
1886 */
1888 /**
1889 String_format for printing the Gtid_set commented: the string is
1890 not quote-wrapped, and every SID is on a new line with a leading '# '.
1891 */
1893
1894 /// Return the Sid_map associated with this Gtid_set.
1895 Sid_map *get_sid_map() const { return sid_map; }
1896
1897 /**
1898 Represents one element in the linked list of intervals associated
1899 with a SIDNO.
1900 */
1901 struct Interval {
1902 public:
1903 /// The first GNO of this interval.
1905 /// The first GNO after this interval.
1907 /// Return true iff this interval is equal to the given interval.
1908 bool equals(const Interval &other) const {
1909 return start == other.start && end == other.end;
1910 }
1911 /// Pointer to next interval in list.
1913 };
1914
1915 /**
1916 Provides an array of Intervals that this Gtid_set can use when
1917 gtids are subsequently added. This can be used as an
1918 optimization, to reduce allocation for sets that have a known
1919 number of intervals.
1920
1921 @param n_intervals The number of intervals to add.
1922 @param intervals_param Array of n_intervals intervals.
1923 */
1924 void add_interval_memory(int n_intervals, Interval *intervals_param) {
1926 add_interval_memory_lock_taken(n_intervals, intervals_param);
1928 }
1929
1930 /**
1931 Iterator over intervals for a given SIDNO.
1932
1933 This is an abstract template class, used as a common base class
1934 for Const_interval_iterator and Interval_iterator.
1935
1936 The iterator always points to an interval pointer. The interval
1937 pointer is either the initial pointer into the list, or the next
1938 pointer of one of the intervals in the list.
1939 */
1940 template <typename Gtid_set_p, typename Interval_p>
1942 public:
1943 /**
1944 Construct a new iterator over the GNO intervals for a given Gtid_set.
1945
1946 @param gtid_set The Gtid_set.
1947 @param sidno The SIDNO.
1948 */
1949 Interval_iterator_base(Gtid_set_p gtid_set, rpl_sidno sidno) {
1950 assert(sidno >= 1 && sidno <= gtid_set->get_max_sidno());
1951 init(gtid_set, sidno);
1952 }
1953 /// Construct a new iterator over the free intervals of a Gtid_set.
1954 Interval_iterator_base(Gtid_set_p gtid_set) {
1955 p = const_cast<Interval_p *>(&gtid_set->free_intervals);
1956 }
1957 /// Reset this iterator.
1958 inline void init(Gtid_set_p gtid_set, rpl_sidno sidno) {
1959 p = const_cast<Interval_p *>(&gtid_set->m_intervals[sidno - 1]);
1960 }
1961 /// Advance current_elem one step.
1962 inline void next() {
1963 assert(*p != nullptr);
1964 p = const_cast<Interval_p *>(&(*p)->next);
1965 }
1966 /// Return current_elem.
1967 inline Interval_p get() const { return *p; }
1968
1969 protected:
1970 /**
1971 Holds the address of the 'next' pointer of the previous element,
1972 or the address of the initial pointer into the list, if the
1973 current element is the first element.
1974 */
1975 Interval_p *p;
1976 };
1977
1978 /**
1979 Iterator over intervals of a const Gtid_set.
1980 */
1982 : public Interval_iterator_base<const Gtid_set *, const Interval *> {
1983 public:
1984 /// Create this Const_interval_iterator.
1986 : Interval_iterator_base<const Gtid_set *, const Interval *>(gtid_set,
1987 sidno) {}
1988 /// Create this Const_interval_iterator.
1990 : Interval_iterator_base<const Gtid_set *, const Interval *>(gtid_set) {
1991 }
1992 };
1993
1994 /**
1995 Iterator over intervals of a non-const Gtid_set, with additional
1996 methods to modify the Gtid_set.
1997 */
1999 : public Interval_iterator_base<Gtid_set *, Interval *> {
2000 public:
2001 /// Create this Interval_iterator.
2003 : Interval_iterator_base<Gtid_set *, Interval *>(gtid_set, sidno) {}
2004 /// Destroy this Interval_iterator.
2006 : Interval_iterator_base<Gtid_set *, Interval *>(gtid_set) {}
2007
2008 private:
2009 /**
2010 Set current_elem to the given Interval but do not touch the
2011 next pointer of the given Interval.
2012 */
2013 inline void set(Interval *iv) { *p = iv; }
2014 /// Insert the given element before current_elem.
2015 inline void insert(Interval *iv) {
2016 iv->next = *p;
2017 set(iv);
2018 }
2019 /// Remove current_elem.
2020 inline void remove(Gtid_set *gtid_set) {
2021 assert(get() != nullptr);
2022 Interval *next = (*p)->next;
2023 gtid_set->put_free_interval(*p);
2024 set(next);
2025 }
2026 /**
2027 Only Gtid_set is allowed to use set/insert/remove.
2028
2029 They are not safe to use from other code because: (1) very easy
2030 to make a mistakes (2) they don't clear cached_string_format or
2031 cached_string_length.
2032 */
2033 friend class Gtid_set;
2034 };
2035
2036 /**
2037 Iterator over all gtids in a Gtid_set. This is a const
2038 iterator; it does not allow modification of the Gtid_set.
2039 */
2041 public:
2042 Gtid_iterator(const Gtid_set *gs) : gtid_set(gs), sidno(0), ivit(gs) {
2043 if (gs->sid_lock != nullptr) gs->sid_lock->assert_some_wrlock();
2044 next_sidno();
2045 }
2046 /// Advance to next gtid.
2047 inline void next() {
2048 assert(gno > 0 && sidno > 0);
2049 // go to next GTID in current interval
2050 gno++;
2051 // end of interval? then go to next interval for this sidno
2052 if (gno == ivit.get()->end) {
2053 ivit.next();
2054 const Interval *iv = ivit.get();
2055 // last interval for this sidno? then go to next sidno
2056 if (iv == nullptr) {
2057 next_sidno();
2058 // last sidno? then don't try more
2059 if (sidno == 0) return;
2060 iv = ivit.get();
2061 }
2062 gno = iv->start;
2063 }
2064 }
2065 /// Return next gtid, or {0,0} if we reached the end.
2066 inline Gtid get() const {
2067 Gtid ret = {sidno, gno};
2068 return ret;
2069 }
2070
2071 private:
2072 /// Find the next sidno that has one or more intervals.
2073 inline void next_sidno() {
2074 const Interval *iv;
2075 do {
2076 sidno++;
2077 if (sidno > gtid_set->get_max_sidno()) {
2078 sidno = 0;
2079 gno = 0;
2080 return;
2081 }
2083 iv = ivit.get();
2084 } while (iv == nullptr);
2085 gno = iv->start;
2086 }
2087 /// The Gtid_set we iterate over.
2089 /**
2090 The SIDNO of the current element, or 0 if the iterator is past
2091 the last element.
2092 */
2094 /**
2095 The GNO of the current element, or 0 if the iterator is past the
2096 last element.
2097 */
2099 /// Iterator over the intervals for the current SIDNO.
2101 };
2102
2103 public:
2104 /**
2105 Encodes this Gtid_set as a binary string.
2106 */
2107 void encode(uchar *buf) const;
2108 /**
2109 Returns the length of this Gtid_set when encoded using the
2110 encode() function.
2111 */
2112 size_t get_encoded_length() const;
2113
2114 private:
2115 /**
2116 Contains a list of intervals allocated by this Gtid_set. When a
2117 method of this class needs a new interval and there are no more
2118 free intervals, a new Interval_chunk is allocated and the
2119 intervals of it are added to the list of free intervals.
2120 */
2124 };
2125 /// The default number of intervals in an Interval_chunk.
2126 static const int CHUNK_GROW_SIZE = 8;
2127
2128 /**
2129 Return true if the given sidno of this Gtid_set contains the same
2130 intervals as the given sidno of the other Gtid_set.
2131
2132 @param sidno SIDNO to check for this Gtid_set.
2133 @param other Other Gtid_set
2134 @param other_sidno SIDNO to check in other.
2135 @return true if equal, false is not equal.
2136 */
2137 bool sidno_equals(rpl_sidno sidno, const Gtid_set *other,
2138 rpl_sidno other_sidno) const;
2139 /// Returns true if this Gtid_set is equal to the other Gtid_set.
2140 bool equals(const Gtid_set *other) const;
2141
2142 /// Return the number of intervals for the given sidno.
2143 int get_n_intervals(rpl_sidno sidno) const {
2144 Const_interval_iterator ivit(this, sidno);
2145 int ret = 0;
2146 while (ivit.get() != nullptr) {
2147 ret++;
2148 ivit.next();
2149 }
2150 return ret;
2151 }
2152 /// Return the number of intervals in this Gtid_set.
2153 int get_n_intervals() const {
2154 if (sid_lock != nullptr) sid_lock->assert_some_wrlock();
2155 rpl_sidno max_sidno = get_max_sidno();
2156 int ret = 0;
2157 for (rpl_sidno sidno = 1; sidno < max_sidno; sidno++)
2158 ret += get_n_intervals(sidno);
2159 return ret;
2160 }
2161 /**
2162 Allocates a new chunk of Intervals and adds them to the list of
2163 unused intervals.
2164
2165 @param size The number of intervals in this chunk
2166 */
2167 void create_new_chunk(int size);
2168 /**
2169 Returns a fresh new Interval object.
2170
2171 This usually does not require any real allocation, it only pops
2172 the first interval from the list of free intervals. If there are
2173 no free intervals, it calls create_new_chunk.
2174
2175 @param out The resulting Interval* will be stored here.
2176 */
2177 void get_free_interval(Interval **out);
2178 /**
2179 Puts the given interval in the list of free intervals. Does not
2180 unlink it from its place in any other list.
2181 */
2182 void put_free_interval(Interval *iv);
2183 /**
2184 Like add_interval_memory, but does not acquire
2185 free_intervals_mutex.
2186 @see Gtid_set::add_interval_memory
2187 */
2188 void add_interval_memory_lock_taken(int n_ivs, Interval *ivs);
2189
2190 /// Read-write lock that protects updates to the number of SIDs.
2192 /**
2193 Lock protecting the list of free intervals. This lock is only
2194 used if sid_lock is not NULL.
2195 */
2197 /**
2198 Class representing a lock on free_intervals_mutex.
2199
2200 This is used by the add_* and remove_* functions. The lock is
2201 declared by the top-level function and a pointer to the lock is
2202 passed down to low-level functions. If the low-level function
2203 decides to access the free intervals list, then it acquires the
2204 lock. The lock is then automatically released by the destructor
2205 when the top-level function returns.
2206
2207 The lock is not taken if Gtid_set->sid_lock == NULL; such
2208 Gtid_sets are assumed to be thread-local.
2209 */
2211 public:
2212 /// Create a new lock, but do not acquire it.
2214 : gtid_set(_gtid_set), locked(false) {}
2215 /// Lock the lock if it is not already locked.
2217 if (gtid_set->sid_lock && !locked) {
2219 locked = true;
2220 }
2221 }
2222 /// Lock the lock if it is locked.
2224 if (gtid_set->sid_lock && locked) {
2226 locked = false;
2227 }
2228 }
2229 /// Destroy this object and unlock the lock if it is locked.
2231
2232 private:
2235 };
2238 }
2239
2240 /**
2241 Adds the interval (start, end) to the given Interval_iterator.
2242
2243 This is the lowest-level function that adds gtids; this is where
2244 Interval objects are added, grown, or merged.
2245
2246 @param ivitp Pointer to iterator. After this function returns,
2247 the current_element of the iterator will be the interval that
2248 contains start and end.
2249 @param start The first GNO in the interval.
2250 @param end The first GNO after the interval.
2251 @param lock If this function has to add or remove an interval,
2252 then this lock will be taken unless it is already taken. This
2253 mechanism means that the lock will be taken lazily by
2254 e.g. add_gtid_set() the first time that the list of free intervals
2255 is accessed, and automatically released when add_gtid_set()
2256 returns.
2257 */
2258 void add_gno_interval(Interval_iterator *ivitp, rpl_gno start, rpl_gno end,
2259 Free_intervals_lock *lock);
2260 /**
2261 Removes the interval (start, end) from the given
2262 Interval_iterator. This is the lowest-level function that removes
2263 gtids; this is where Interval objects are removed, truncated, or
2264 split.
2265
2266 It is not required that the gtids in the interval exist in this
2267 Gtid_set.
2268
2269 @param ivitp Pointer to iterator. After this function returns,
2270 the current_element of the iterator will be the next interval
2271 after end.
2272 @param start The first GNO in the interval.
2273 @param end The first GNO after the interval.
2274 @param lock If this function has to add or remove an interval,
2275 then this lock will be taken unless it is already taken. This
2276 mechanism means that the lock will be taken lazily by
2277 e.g. add_gtid_set() the first time that the list of free intervals
2278 is accessed, and automatically released when add_gtid_set()
2279 returns.
2280 */
2281 void remove_gno_interval(Interval_iterator *ivitp, rpl_gno start, rpl_gno end,
2282 Free_intervals_lock *lock);
2283 /**
2284 Adds a list of intervals to the given SIDNO.
2285
2286 The SIDNO must exist in the Gtid_set before this function is called.
2287
2288 @param sidno The SIDNO to which intervals will be added.
2289 @param ivit Iterator over the intervals to add. This is typically
2290 an iterator over some other Gtid_set.
2291 @param lock If this function has to add or remove an interval,
2292 then this lock will be taken unless it is already taken. This
2293 mechanism means that the lock will be taken lazily by
2294 e.g. add_gtid_set() the first time that the list of free intervals
2295 is accessed, and automatically released when add_gtid_set()
2296 returns.
2297 */
2298 void add_gno_intervals(rpl_sidno sidno, Const_interval_iterator ivit,
2299 Free_intervals_lock *lock);
2300 /**
2301 Removes a list of intervals from the given SIDNO.
2302
2303 It is not required that the intervals exist in this Gtid_set.
2304
2305 @param sidno The SIDNO from which intervals will be removed.
2306 @param ivit Iterator over the intervals to remove. This is typically
2307 an iterator over some other Gtid_set.
2308 @param lock If this function has to add or remove an interval,
2309 then this lock will be taken unless it is already taken. This
2310 mechanism means that the lock will be taken lazily by
2311 e.g. add_gtid_set() the first time that the list of free intervals
2312 is accessed, and automatically released when add_gtid_set()
2313 returns.
2314 */
2315 void remove_gno_intervals(rpl_sidno sidno, Const_interval_iterator ivit,
2316 Free_intervals_lock *lock);
2317
2318 /// Returns true if every interval of sub is a subset of some
2319 /// interval of super.
2320 static bool is_interval_subset(Const_interval_iterator *sub,
2321 Const_interval_iterator *super);
2322 /// Returns true if at least one sidno in ivit1 is also in ivit2.
2323 static bool is_interval_intersection_nonempty(Const_interval_iterator *ivit1,
2324 Const_interval_iterator *ivit2);
2325
2326 /// Sid_map associated with this Gtid_set.
2328 /**
2329 Array where the N'th element contains the head pointer to the
2330 intervals of SIDNO N+1.
2331 */
2333 /// Linked list of free intervals.
2335 /// Linked list of chunks.
2337 /// If the string is cached.
2339 /// The string length.
2340 mutable size_t cached_string_length;
2341 /// The String_format that was used when cached_string_length was computed.
2343#ifndef NDEBUG
2344 /**
2345 The number of chunks. Used only to check some invariants when
2346 DBUG is on.
2347 */
2349#endif
2350 /// Used by unit tests that need to access private members.
2351#ifdef FRIEND_OF_GTID_SET
2352 friend FRIEND_OF_GTID_SET;
2353#endif
2354 /// Only Free_intervals_lock is allowed to access free_intervals_mutex.
2356};
2357
2358/**
2359 Holds information about a Gtid_set. Can also be NULL.
2360
2361 This is used as backend storage for @@session.gtid_next_list. The
2362 idea is that we allow the user to set this to NULL, but we keep the
2363 Gtid_set object so that we can re-use the allocated memory and
2364 avoid costly allocations later.
2365
2366 This is stored in struct system_variables (defined in sql_class.h),
2367 which is cleared using memset(0); hence the negated form of
2368 is_non_null.
2369
2370 The convention is: if is_non_null is false, then the value of the
2371 session variable is NULL, and the field gtid_set may be NULL or
2372 non-NULL. If is_non_null is true, then the value of the session
2373 variable is not NULL, and the field gtid_set has to be non-NULL.
2374
2375 This is a POD. It has to be a POD because it is stored in
2376 THD::variables.
2377*/
2379 /// Pointer to the Gtid_set.
2381 /// True if this Gtid_set is NULL.
2383 /// Return NULL if this is NULL, otherwise return the Gtid_set.
2384 inline Gtid_set *get_gtid_set() const {
2385 assert(!(is_non_null && gtid_set == nullptr));
2386 return is_non_null ? gtid_set : nullptr;
2387 }
2388 /**
2389 Do nothing if this object is non-null; set to empty set otherwise.
2390
2391 @return NULL if out of memory; Gtid_set otherwise.
2392 */
2394 if (!is_non_null) {
2395 if (gtid_set == nullptr)
2396 gtid_set = new Gtid_set(sm);
2397 else
2398 gtid_set->clear();
2399 }
2400 is_non_null = (gtid_set != nullptr);
2401 return gtid_set;
2402 }
2403 /// Set this Gtid_set to NULL.
2404 inline void set_null() { is_non_null = false; }
2405};
2406
2407/**
2408 Represents the set of GTIDs that are owned by some thread.
2409
2410 This data structure has a read-write lock that protects the number
2411 of SIDNOs. The lock is provided by the invoker of the constructor
2412 and it is generally the caller's responsibility to acquire the read
2413 lock. Access methods assert that the caller already holds the read
2414 (or write) lock. If a method of this class grows the number of
2415 SIDNOs, then the method temporarily upgrades this lock to a write
2416 lock and then degrades it to a read lock again; there will be a
2417 short period when the lock is not held at all.
2418
2419 The internal representation is a multi-valued map from GTIDs to
2420 threads, mapping GTIDs to one or more threads that owns it.
2421
2422 In Group Replication multiple threads can own a GTID whereas if GR
2423 is disabeld there is at most one owner per GTID.
2424*/
2426 public:
2427 /**
2428 Constructs a new, empty Owned_gtids object.
2429
2430 @param sid_lock Read-write lock that protects updates to the
2431 number of SIDs.
2432 */
2434 /// Destroys this Owned_gtids.
2435 ~Owned_gtids();
2436 /**
2437 Add a GTID to this Owned_gtids.
2438
2439 @param gtid The Gtid to add.
2440 @param owner The my_thread_id of the gtid to add.
2441 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
2442 */
2444
2445 /*
2446 Fill all gtids into the given Gtid_set object. It doesn't clear the given
2447 gtid set before filling its owned gtids into it.
2448 */
2449 void get_gtids(Gtid_set &gtid_set) const;
2450 /**
2451 Removes the given GTID.
2452
2453 If the gtid does not exist in this Owned_gtids object, does
2454 nothing.
2455
2456 @param gtid The Gtid.
2457 @param owner thread_id of the owner thread
2458 */
2459 void remove_gtid(const Gtid &gtid, const my_thread_id owner);
2460 /**
2461 Ensures that this Owned_gtids object can accommodate SIDNOs up to
2462 the given SIDNO.
2463
2464 If this Owned_gtids object needs to be resized, then the lock
2465 will be temporarily upgraded to a write lock and then degraded to
2466 a read lock again; there will be a short period when the lock is
2467 not held at all.
2468
2469 @param sidno The SIDNO.
2470 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
2471 */
2473 /// Returns true if there is a least one element of this Owned_gtids
2474 /// set in the other Gtid_set.
2475 bool is_intersection_nonempty(const Gtid_set *other) const;
2476 /// Returns true if this Owned_gtids is empty.
2477 bool is_empty() const {
2478 Gtid_iterator git(this);
2479 return git.get().sidno == 0;
2480 }
2481 /// Returns the maximal sidno that this Owned_gtids currently has space for.
2484 return static_cast<rpl_sidno>(sidno_to_hash.size());
2485 }
2486
2487 /**
2488 Write a string representation of this Owned_gtids to the given buffer.
2489
2490 @param out Buffer to write to.
2491 @return Number of characters written.
2492 */
2493 int to_string(char *out) const {
2494 char *p = out;
2495 rpl_sidno max_sidno = get_max_sidno();
2496 rpl_sidno sid_map_max_sidno = global_sid_map->get_max_sidno();
2497 for (rpl_sidno sid_i = 0; sid_i < sid_map_max_sidno; sid_i++) {
2499 if (sidno > max_sidno) continue;
2500 bool printed_sid = false;
2501 for (const auto &key_and_value : *get_hash(sidno)) {
2502 Node *node = key_and_value.second.get();
2503 assert(node != nullptr);
2504 if (!printed_sid) {
2506 printed_sid = true;
2507 }
2508 p += sprintf(p, ":%" PRId64 "#%u", node->gno, node->owner);
2509 }
2510 }
2511 *p = 0;
2512 return (int)(p - out);
2513 }
2514
2515 /**
2516 Return an upper bound on the length of the string representation
2517 of this Owned_gtids. The actual length may be smaller. This
2518 includes the trailing '\0'.
2519 */
2520 size_t get_max_string_length() const {
2521 rpl_sidno max_sidno = get_max_sidno();
2522 size_t ret = 0;
2523 for (rpl_sidno sidno = 1; sidno <= max_sidno; sidno++) {
2524 size_t records = get_hash(sidno)->size();
2525 if (records > 0)
2526 ret +=
2528 records * (1 + MAX_GNO_TEXT_LENGTH + 1 + MAX_THREAD_ID_TEXT_LENGTH);
2529 }
2530 return 1 + ret;
2531 }
2532
2533 /**
2534 Return true if the given thread is the owner of any gtids.
2535 */
2537 Gtid_iterator git(this);
2538 Node *node = git.get_node();
2539 while (node != nullptr) {
2540 if (node->owner == thd_id) return true;
2541 git.next();
2542 node = git.get_node();
2543 }
2544 return false;
2545 }
2546
2547#ifndef NDEBUG
2548 /**
2549 Debug only: return a newly allocated string representation of
2550 this Owned_gtids.
2551 */
2552 char *to_string() const {
2555 assert(str != nullptr);
2556 to_string(str);
2557 return str;
2558 }
2559 /// Debug only: print this Owned_gtids to stdout.
2560 void print() const {
2561 char *str = to_string();
2562 printf("%s\n", str);
2563 my_free(str);
2564 }
2565#endif
2566 /**
2567 Print this Owned_gtids to the trace file if debug is enabled; no-op
2568 otherwise.
2569 */
2570 void dbug_print(const char *text [[maybe_unused]] = "") const {
2571#ifndef NDEBUG
2572 char *str = to_string();
2573 DBUG_PRINT("info", ("%s%s%s", text, *text ? ": " : "", str));
2574 my_free(str);
2575#endif
2576 }
2577
2578 /**
2579 If thd_id==0, returns true when gtid is not owned by any thread.
2580 If thd_id!=0, returns true when gtid is owned by that thread.
2581 */
2582 bool is_owned_by(const Gtid &gtid, const my_thread_id thd_id) const;
2583
2584 private:
2585 /// Represents one owned GTID.
2586 struct Node {
2587 /// GNO of the GTID.
2589 /// Owner of the GTID.
2591 };
2592 /// Read-write lock that protects updates to the number of SIDs.
2594 /// Returns the hash for the given SIDNO.
2596 rpl_sidno sidno) const {
2597 assert(sidno >= 1 && sidno <= get_max_sidno());
2599 return sidno_to_hash[sidno - 1];
2600 }
2601 /// Return true iff this Owned_gtids object contains the given gtid.
2602 bool contains_gtid(const Gtid &gtid) const;
2603
2604 /// Growable array of hashes.
2608
2609 public:
2610 /**
2611 Iterator over all gtids in a Owned_gtids set. This is a const
2612 iterator; it does not allow modification of the set.
2613 */
2615 public:
2617 : owned_gtids(og), sidno(1), hash(nullptr), node(nullptr) {
2619 if (sidno <= max_sidno) {
2621 node_it = hash->begin();
2622 }
2623 next();
2624 }
2625 /// Advance to next GTID.
2626 inline void next() {
2627#ifndef NDEBUG
2629#endif
2630
2631 while (sidno <= max_sidno) {
2632 assert(hash != nullptr);
2633 if (node_it != hash->end()) {
2634 node = node_it->second.get();
2635 assert(node != nullptr);
2636 // Jump to next node on next iteration.
2637 ++node_it;
2638 return;
2639 }
2640
2641 // hash is initialized on constructor or in previous iteration
2642 // for current SIDNO, so we must increment for next iteration.
2643 sidno++;
2644 if (sidno <= max_sidno) {
2646 node_it = hash->begin();
2647 }
2648 }
2649 node = nullptr;
2650 }
2651 /// Return next GTID, or {0,0} if we reached the end.
2652 inline Gtid get() const {
2653 Gtid ret = {0, 0};
2654 if (node) {
2655 ret.sidno = sidno;
2656 ret.gno = node->gno;
2657 }
2658 return ret;
2659 }
2660 /// Return the current GTID Node, or NULL if we reached the end.
2661 inline Node *get_node() const { return node; }
2662
2663 private:
2664 /// The Owned_gtids set we iterate over.
2666 /// The SIDNO of the current element, or 1 in the initial iteration.
2668 /// Max SIDNO of the current iterator.
2670 /// Current SIDNO hash.
2672 /// Current node iterator on current SIDNO hash.
2675 /// Current node on current SIDNO hash.
2677 };
2678};
2679
2680/**
2681 Represents the server's GTID state: the set of committed GTIDs, the
2682 set of lost gtids, the set of owned gtids, the owner of each owned
2683 gtid, and a Mutex_cond_array that protects updates to gtids of
2684 each SIDNO.
2685
2686 Locking:
2687
2688 This data structure has a read-write lock that protects the number
2689 of SIDNOs, and a Mutex_cond_array that contains one mutex per SIDNO.
2690 The rwlock is always the global_sid_lock.
2691
2692 Access methods generally assert that the caller already holds the
2693 appropriate lock:
2694
2695 - before accessing any global data, hold at least the rdlock.
2696
2697 - before accessing a specific SIDNO in a Gtid_set or Owned_gtids
2698 (e.g., calling Gtid_set::_add_gtid(Gtid)), hold either the rdlock
2699 and the SIDNO's mutex lock; or the wrlock. If you need to hold
2700 multiple mutexes, they must be acquired in order of increasing
2701 SIDNO.
2702
2703 - before starting an operation that needs to access all SIDs
2704 (e.g. Gtid_set::to_string()), hold the wrlock.
2705
2706 The access type (read/write) does not matter; the write lock only
2707 implies that the entire data structure is locked whereas the read
2708 lock implies that everything except SID-specific data is locked.
2709*/
2711 public:
2712 /**
2713 Constructs a new Gtid_state object.
2714
2715 @param _sid_lock Read-write lock that protects updates to the
2716 number of SIDs.
2717 @param _sid_map Sid_map used by this Gtid_state.
2718 */
2719 Gtid_state(Checkable_rwlock *_sid_lock, Sid_map *_sid_map)
2720 : sid_lock(_sid_lock),
2721 sid_map(_sid_map),
2729 /**
2730 Add @@GLOBAL.SERVER_UUID to this binlog's Sid_map.
2731
2732 This can't be done in the constructor because the constructor is
2733 invoked at server startup before SERVER_UUID is initialized.
2734
2735 The caller must hold the read lock or write lock on sid_locks
2736 before invoking this function.
2737
2738 @retval 0 Success
2739 @retval 1 Error (out of memory or IO error).
2740 */
2741 int init();
2742 /**
2743 Reset the state and persistor after RESET MASTER: remove all logged
2744 and lost gtids, but keep owned gtids as they are.
2745
2746 The caller must hold the write lock on sid_lock before calling
2747 this function.
2748
2749 @param thd Thread requesting to reset the persistor
2750
2751 @retval 0 Success
2752 @retval -1 Error
2753 */
2754 int clear(THD *thd);
2755 /**
2756 Returns true if the given GTID is logged.
2757
2758 @param gtid The Gtid to check.
2759
2760 @retval true The gtid is logged in the binary log.
2761 @retval false The gtid is not logged in the binary log.
2762 */
2763 bool is_executed(const Gtid &gtid) const {
2764 DBUG_TRACE;
2766 bool ret = executed_gtids.contains_gtid(gtid);
2767 return ret;
2768 }
2769 /**
2770 Returns true if GTID is owned, otherwise returns 0.
2771
2772 @param gtid The Gtid to check.
2773 @return true if some thread owns the gtid, false if the gtid is
2774 not owned
2775 */
2776 bool is_owned(const Gtid &gtid) const {
2777 return !owned_gtids.is_owned_by(gtid, 0);
2778 }
2779#ifdef MYSQL_SERVER
2780 /**
2781 Acquires ownership of the given GTID, on behalf of the given thread.
2782
2783 The caller must lock the SIDNO before invoking this function.
2784
2785 @param thd The thread that will own the GTID.
2786 @param gtid The Gtid to acquire ownership of.
2787 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
2788 */
2789 enum_return_status acquire_ownership(THD *thd, const Gtid &gtid);
2790 /**
2791 This function updates both the THD and the Gtid_state to reflect that
2792 the transaction set of transactions has ended, and it does this for the
2793 whole commit group (by following the thd->next_to_commit pointer).
2794
2795 It will:
2796
2797 - Clean up the thread state when a thread owned GTIDs is empty.
2798 - Release ownership of all GTIDs owned by the THDs. This removes
2799 the GTIDs from Owned_gtids and clears the ownership status in the
2800 THDs object.
2801 - Add the owned GTIDs to executed_gtids when the thread is committing.
2802 - Decrease counters of GTID-violating transactions.
2803 - Send a broadcast on the condition variable for every sidno for
2804 which we released ownership.
2805
2806 @param first_thd The first thread of the group commit that needs GTIDs to
2807 be updated.
2808 */
2809 void update_commit_group(THD *first_thd);
2810 /**
2811 Remove the GTID owned by thread from owned GTIDs, stating that
2812 thd->owned_gtid was committed.
2813
2814 This will:
2815 - remove owned GTID from owned_gtids;
2816 - remove all owned GTIDS from thd->owned_gtid and thd->owned_gtid_set;
2817
2818 @param thd Thread for which owned gtids are updated.
2819 */
2820 void update_on_commit(THD *thd);
2821 /**
2822 Update the state after the given thread has rollbacked.
2823
2824 This will:
2825 - release ownership of all GTIDs owned by the THD;
2826 - remove owned GTID from owned_gtids;
2827 - remove all owned GTIDS from thd->owned_gtid and thd->owned_gtid_set;
2828 - send a broadcast on the condition variable for every sidno for
2829 which we released ownership.
2830
2831 @param thd Thread for which owned gtids are updated.
2832 */
2833 void update_on_rollback(THD *thd);
2834
2835 /**
2836 Acquire anonymous ownership.
2837
2838 The caller must hold either sid_lock.rdlock or
2839 sid_lock.wrlock. (The caller must have taken the lock and checked
2840 that gtid_mode!=ON before calling this function, or else the
2841 gtid_mode could have changed to ON by a concurrent SET GTID_MODE.)
2842 */
2844 DBUG_TRACE;
2846 assert(global_gtid_mode.get() != Gtid_mode::ON);
2847#ifndef NDEBUG
2848 int32 new_value =
2849#endif
2851 DBUG_PRINT("info",
2852 ("atomic_anonymous_gtid_count increased to %d", new_value));
2853 assert(new_value >= 1);
2854 return;
2855 }
2856
2857 /// Release anonymous ownership.
2859 DBUG_TRACE;
2861 assert(global_gtid_mode.get() != Gtid_mode::ON);
2862#ifndef NDEBUG
2863 int32 new_value =
2864#endif
2866 DBUG_PRINT("info",
2867 ("atomic_anonymous_gtid_count decreased to %d", new_value));
2868 assert(new_value >= 0);
2869 return;
2870 }
2871
2872 /// Return the number of clients that hold anonymous ownership.
2874
2875 /**
2876 Increase the global counter when starting a GTID-violating
2877 transaction having GTID_NEXT=AUTOMATIC.
2878 */
2880 DBUG_TRACE;
2883#ifndef NDEBUG
2884 int32 new_value =
2885#endif
2887 DBUG_PRINT(
2888 "info",
2889 ("ongoing_automatic_gtid_violating_transaction_count increased to %d",
2890 new_value));
2891 assert(new_value >= 1);
2892 return;
2893 }
2894
2895 /**
2896 Decrease the global counter when ending a GTID-violating
2897 transaction having GTID_NEXT=AUTOMATIC.
2898 */
2900 DBUG_TRACE;
2901#ifndef NDEBUG
2906 int32 new_value =
2907#endif
2909 DBUG_PRINT(
2910 "info",
2911 ("ongoing_automatic_gtid_violating_transaction_count decreased to %d",
2912 new_value));
2913 assert(new_value >= 0);
2914 return;
2915 }
2916
2917 /**
2918 Return the number of ongoing GTID-violating transactions having
2919 GTID_NEXT=AUTOMATIC.
2920 */
2923 }
2924
2925 /**
2926 Increase the global counter when starting a GTID-violating
2927 transaction having GTID_NEXT=ANONYMOUS.
2928 */
2930 DBUG_TRACE;
2931 assert(global_gtid_mode.get() != Gtid_mode::ON);
2933#ifndef NDEBUG
2934 int32 new_value =
2935#endif
2937 DBUG_PRINT("info", ("atomic_anonymous_gtid_violation_count increased to %d",
2938 new_value));
2939 assert(new_value >= 1);
2940 return;
2941 }
2942
2943 /**
2944 Decrease the global counter when ending a GTID-violating
2945 transaction having GTID_NEXT=ANONYMOUS.
2946 */
2948 DBUG_TRACE;
2949#ifndef NDEBUG
2951 assert(global_gtid_mode.get() != Gtid_mode::ON);
2954 int32 new_value =
2955#endif
2957 DBUG_PRINT(
2958 "info",
2959 ("ongoing_anonymous_gtid_violating_transaction_count decreased to %d",
2960 new_value));
2961 assert(new_value >= 0);
2962 return;
2963 }
2964
2966
2967 /**
2968 Return the number of ongoing GTID-violating transactions having
2969 GTID_NEXT=AUTOMATIC.
2970 */
2973 }
2974
2975 /**
2976 Increase the global counter when starting a call to
2977 WAIT_FOR_EXECUTED_GTID_SET or WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS.
2978 */
2980 DBUG_TRACE;
2981 assert(global_gtid_mode.get() != Gtid_mode::OFF);
2982#ifndef NDEBUG
2983 int32 new_value =
2984#endif
2986 DBUG_PRINT("info", ("atomic_gtid_wait_count changed from %d to %d",
2987 new_value - 1, new_value));
2988 assert(new_value >= 1);
2989 return;
2990 }
2991
2992 /**
2993 Decrease the global counter when ending a call to
2994 WAIT_FOR_EXECUTED_GTID_SET or WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS.
2995 */
2997 DBUG_TRACE;
2998 assert(global_gtid_mode.get() != Gtid_mode::OFF);
2999#ifndef NDEBUG
3000 int32 new_value =
3001#endif
3003 DBUG_PRINT("info", ("atomic_gtid_wait_count changed from %d to %d",
3004 new_value + 1, new_value));
3005 assert(new_value >= 0);
3006 return;
3007 }
3008
3009 /**
3010 Return the number of clients that have an ongoing call to
3011 WAIT_FOR_EXECUTED_GTID_SET or WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS.
3012 */
3014
3015#endif // ifdef MYSQL_SERVER
3016 /**
3017 Computes the next available GNO.
3018
3019 @param sidno The GTID's SIDNO.
3020
3021 @retval -1 The range of GNOs was exhausted (i.e., more than 1<<63-1
3022 GTIDs with the same UUID have been generated).
3023 @retval >0 The GNO for the GTID.
3024 */
3025 rpl_gno get_automatic_gno(rpl_sidno sidno) const;
3026
3027 private:
3028 /**
3029 The next_free_gno variable will be set with the supposed next free GNO
3030 every time a new GNO is delivered automatically or when a transaction is
3031 rolled back, releasing a GNO smaller than the last one delivered.
3032 It was introduced in an optimization of Gtid_state::get_automatic_gno and
3033 Gtid_state::generate_automatic_gtid functions.
3034
3035 Locking scheme
3036
3037 This variable can be read and modified in four places:
3038 - During server startup, holding global_sid_lock.wrlock;
3039 - By a client thread holding global_sid_lock.wrlock (doing a RESET MASTER);
3040 - By a client thread calling MYSQL_BIN_LOG::write_transaction function
3041 (often the group commit FLUSH stage leader). It will call
3042 Gtid_state::generate_automatic_gtid, that will acquire
3043 global_sid_lock.rdlock and lock_sidno(get_server_sidno()) when getting a
3044 new automatically generated GTID;
3045 - By a client thread rolling back, holding global_sid_lock.rdlock
3046 and lock_sidno(get_server_sidno()).
3047 */
3049
3050 public:
3051 /**
3052 Return the last executed GNO for a given SIDNO, e.g.
3053 for the following set: UUID:1-10, UUID:12, UUID:15-20
3054 20 will be returned.
3055
3056 @param sidno The GTID's SIDNO.
3057
3058 @retval The GNO or 0 if set is empty.
3059 */
3061 /**
3062 Generates the GTID (or ANONYMOUS, if GTID_MODE = OFF or
3063 OFF_PERMISSIVE) for the THD, and acquires ownership.
3064
3065 @param thd The thread.
3066 @param specified_sidno Externally generated sidno.
3067 @param specified_gno Externally generated gno.
3068 @param[in,out] locked_sidno This parameter should be used when there is
3069 a need of generating many GTIDs without having
3070 to acquire/release a sidno_lock many times.
3071 The caller must hold global_sid_lock and unlock
3072 the locked_sidno after invocation when
3073 locked_sidno > 0 if locked_sidno!=NULL.
3074 The caller must not hold global_sid_lock when
3075 locked_sidno==NULL.
3076 See comments on function code to more details.
3077
3078 @return RETURN_STATUS_OK or RETURN_STATUS_ERROR. Error can happen
3079 in case of out of memory or if the range of GNOs was exhausted.
3080 */
3082 rpl_sidno specified_sidno = 0,
3083 rpl_gno specified_gno = 0,
3084 rpl_sidno *locked_sidno = nullptr);
3085
3086 /// Locks a mutex for the given SIDNO.
3087 void lock_sidno(rpl_sidno sidno) { sid_locks.lock(sidno); }
3088 /// Unlocks a mutex for the given SIDNO.
3089 void unlock_sidno(rpl_sidno sidno) { sid_locks.unlock(sidno); }
3090 /// Broadcasts updates for the given SIDNO.
3092 /// Assert that we own the given SIDNO.
3094 sid_locks.assert_owner(sidno);
3095 }
3096#ifdef MYSQL_SERVER
3097 /**
3098 Wait for a signal on the given SIDNO.
3099
3100 NOTE: This releases a lock!
3101
3102 This requires that the caller holds a read lock on sid_lock. It
3103 will release the lock before waiting; neither global_sid_lock nor
3104 the mutex lock on SIDNO will not be held when this function
3105 returns.
3106
3107 @param thd THD object of the caller.
3108 @param sidno Sidno to wait for.
3109 @param[in] abstime The absolute point in time when the wait times
3110 out and stops, or NULL to wait indefinitely.
3111 @param[in] update_thd_status when true updates the stage info with
3112 the new wait condition, when false keeps the current stage info.
3113
3114 @retval false Success.
3115 @retval true Failure: either timeout or thread was killed. If
3116 thread was killed, the error has been generated.
3117 */
3118 bool wait_for_sidno(THD *thd, rpl_sidno sidno, struct timespec *abstime,
3119 bool update_thd_status = true);
3120 /**
3121 This is only a shorthand for wait_for_sidno, which contains
3122 additional debug printouts and assertions for the case when the
3123 caller waits for one specific GTID.
3124 */
3125 bool wait_for_gtid(THD *thd, const Gtid &gtid,
3126 struct timespec *abstime = nullptr);
3127 /**
3128 Wait until the given Gtid_set is included in @@GLOBAL.GTID_EXECUTED.
3129
3130 @param thd The calling thread.
3131 @param gtid_set Gtid_set to wait for.
3132 @param[in] timeout The maximum number of milliseconds that the
3133 function should wait, or 0 to wait indefinitely.
3134 @param[in] update_thd_status when true updates the stage info with
3135 the new wait condition, when false keeps the current stage info.
3136
3137 @retval false Success.
3138 @retval true Failure: either timeout or thread was killed. If
3139 thread was killed, the error has been generated.
3140 */
3141 bool wait_for_gtid_set(THD *thd, Gtid_set *gtid_set, double timeout,
3142 bool update_thd_status = true);
3143#endif // ifdef MYSQL_SERVER
3144 /**
3145 Locks one mutex for each SIDNO where the given Gtid_set has at
3146 least one GTID. Locks are acquired in order of increasing SIDNO.
3147 */
3148 void lock_sidnos(const Gtid_set *set);
3149 /**
3150 Unlocks the mutex for each SIDNO where the given Gtid_set has at
3151 least one GTID.
3152 */
3153 void unlock_sidnos(const Gtid_set *set);
3154 /**
3155 Broadcasts the condition variable for each SIDNO where the given
3156 Gtid_set has at least one GTID.
3157 */
3158 void broadcast_sidnos(const Gtid_set *set);
3159 /**
3160 Ensure that owned_gtids, executed_gtids, lost_gtids, gtids_only_in_table,
3161 previous_gtids_logged and sid_locks have room for at least as many SIDNOs
3162 as sid_map.
3163
3164 This function must only be called in one place:
3165 Sid_map::add_sid().
3166
3167 Requires that the write lock on sid_locks is held. If any object
3168 needs to be resized, then the lock will be temporarily upgraded to
3169 a write lock and then degraded to a read lock again; there will be
3170 a short period when the lock is not held at all.
3171
3172 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
3173 */
3175
3176 /**
3177 Adds the given Gtid_set to lost_gtids and executed_gtids.
3178 lost_gtids must be a subset of executed_gtids.
3179 purged_gtid and executed_gtid sets are appended with the argument set
3180 provided the latter is disjoint with gtid_executed owned_gtids.
3181
3182 Requires that the caller holds global_sid_lock.wrlock.
3183
3184 @param[in,out] gtid_set The gtid_set to add. If the gtid_set
3185 does not start with a plus sign (starts_with_plus is false),
3186 @@GLOBAL.GTID_PURGED will be removed from the gtid_set.
3187 @param starts_with_plus If true, the gtid_set passed is required to
3188 be disjoint from @@GLOBAL.GTID_PURGED; if false, the gtid_set passed
3189 is required to be a superset of @@GLOBAL.GTID_PURGED.
3190 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
3191 */
3192 enum_return_status add_lost_gtids(Gtid_set *gtid_set, bool starts_with_plus);
3193
3194 /** Updates previously logged GTID set before writing to table. */
3195 void update_prev_gtids(Gtid_set *write_gtid_set);
3196
3197 /// Return a pointer to the Gtid_set that contains the lost gtids.
3198 const Gtid_set *get_lost_gtids() const { return &lost_gtids; }
3199 /*
3200 Return a pointer to the Gtid_set that contains the stored gtids
3201 in gtid_executed table.
3202 */
3203 const Gtid_set *get_executed_gtids() const { return &executed_gtids; }
3204 /*
3205 Return a pointer to the Gtid_set that contains the stored gtids
3206 only in gtid_executed table, not in binlog files.
3207 */
3209 return &gtids_only_in_table;
3210 }
3211 /*
3212 Return a pointer to the Gtid_set that contains the previous stored
3213 gtids in the last binlog file.
3214 */
3216 return &previous_gtids_logged;
3217 }
3218 /// Return a pointer to the Owned_gtids that contains the owned gtids.
3219 const Owned_gtids *get_owned_gtids() const { return &owned_gtids; }
3220 /// Return the server's SID's SIDNO
3222 /// Return the server's SID
3223 const rpl_sid &get_server_sid() const {
3225 }
3226#ifndef NDEBUG
3227 /**
3228 Debug only: Returns an upper bound on the length of the string
3229 generated by to_string(), not counting '\0'. The actual length
3230 may be shorter.
3231 */
3232 size_t get_max_string_length() const {
3237 }
3238 /// Debug only: Generate a string in the given buffer and return the length.
3239 int to_string(char *buf) const {
3240 char *p = buf;
3241 p += sprintf(p, "Executed GTIDs:\n");
3243 p += sprintf(p, "\nOwned GTIDs:\n");
3245 p += sprintf(p, "\nLost GTIDs:\n");
3246 p += lost_gtids.to_string(p);
3247 p += sprintf(p, "\nGTIDs only_in_table:\n");
3248 p += lost_gtids.to_string(p);
3249 return (int)(p - buf);
3250 }
3251 /// Debug only: return a newly allocated string, or NULL on out-of-memory.
3252 char *to_string() const {
3255 to_string(str);
3256 return str;
3257 }
3258 /// Debug only: print this Gtid_state to stdout.
3259 void print() const {
3260 char *str = to_string();
3261 printf("%s", str);
3262 my_free(str);
3263 }
3264#endif
3265 /**
3266 Print this Gtid_state to the trace file if debug is enabled; no-op
3267 otherwise.
3268 */
3269 void dbug_print(const char *text [[maybe_unused]] = "") const {
3270#ifndef NDEBUG
3272 char *str = to_string();
3273 DBUG_PRINT("info", ("%s%s%s", text, *text ? ": " : "", str));
3274 my_free(str);
3275#endif
3276 }
3277 /**
3278 Save gtid owned by the thd into executed_gtids variable
3279 and gtid_executed table.
3280
3281 @param thd Session to commit
3282 @retval
3283 0 OK
3284 @retval
3285 -1 Error
3286 */
3287 int save(THD *thd);
3288 /**
3289 Insert the gtid set into table.
3290
3291 @param gtid_set contains a set of gtid, which holds
3292 the sidno and the gno.
3293
3294 @retval
3295 0 OK
3296 @retval
3297 -1 Error
3298 */
3299 int save(const Gtid_set *gtid_set);
3300 /**
3301 Save the set of gtids logged in the last binlog into gtid_executed table.
3302
3303 @retval
3304 0 OK
3305 @retval
3306 -1 Error
3307 */
3309 /**
3310 Fetch gtids from gtid_executed table and store them into
3311 gtid_executed set.
3312
3313 @retval
3314 0 OK
3315 @retval
3316 1 The table was not found.
3317 @retval
3318 -1 Error
3319 */
3321 /**
3322 Compress the gtid_executed table, read each row by the PK(sid, gno_start)
3323 in increasing order, compress the first consecutive gtids range
3324 (delete consecutive gtids from the second consecutive gtid, then
3325 update the first gtid) within a single transaction.
3326
3327 @param thd Thread requesting to compress the table
3328
3329 @retval
3330 0 OK
3331 @retval
3332 1 The table was not found.
3333 @retval
3334 -1 Error
3335 */
3336 int compress(THD *thd);
3337#ifdef MYSQL_SERVER
3338 /**
3339 Push a warning to client if user is modifying the gtid_executed
3340 table explicitly by a non-XA transaction. Push an error to client
3341 if user is modifying it explicitly by a XA transaction.
3342
3343 @param thd Thread requesting to access the table
3344 @param table The table is being accessed.
3345
3346 @retval 0 No warning or error was pushed to the client.
3347 @retval 1 Push a warning to client.
3348 @retval 2 Push an error to client.
3349 */
3351#endif
3352
3353 private:
3354 /**
3355 Remove the GTID owned by thread from owned GTIDs.
3356
3357 This will:
3358
3359 - Clean up the thread state if the thread owned GTIDs is empty.
3360 - Release ownership of all GTIDs owned by the THD. This removes
3361 the GTID from Owned_gtids and clears the ownership status in the
3362 THD object.
3363 - Add the owned GTID to executed_gtids if the is_commit flag is
3364 set.
3365 - Decrease counters of GTID-violating transactions.
3366 - Send a broadcast on the condition variable for every sidno for
3367 which we released ownership.
3368
3369 @param[in] thd Thread for which owned gtids are updated.
3370 @param[in] is_commit If true, the update is for a commit (not a rollback).
3371 */
3372 void update_gtids_impl(THD *thd, bool is_commit);
3373#ifdef HAVE_GTID_NEXT_LIST
3374 /// Lock all SIDNOs owned by the given THD.
3375 void lock_owned_sidnos(const THD *thd);
3376#endif
3377 /// Unlock all SIDNOs owned by the given THD.
3378 void unlock_owned_sidnos(const THD *thd);
3379 /// Broadcast the condition for all SIDNOs owned by the given THD.
3380 void broadcast_owned_sidnos(const THD *thd);
3381 /// Read-write lock that protects updates to the number of SIDs.
3383 /// The Sid_map used by this Gtid_state.
3385 /// Contains one mutex/cond pair for every SIDNO.
3387 /**
3388 The set of GTIDs that existed in some previously purged binary log.
3389 This is always a subset of executed_gtids.
3390 */
3392 /*
3393 The set of GTIDs that has been executed and
3394 stored into gtid_executed table.
3395 */
3397 /*
3398 The set of GTIDs that exists only in gtid_executed table, not in
3399 binlog files.
3400 */
3402 /* The previous GTIDs in the last binlog. */
3404 /// The set of GTIDs that are owned by some thread.
3406 /// The SIDNO for this server.
3408
3409 /// The number of anonymous transactions owned by any client.
3410 std::atomic<int32> atomic_anonymous_gtid_count{0};
3411 /// The number of GTID-violating transactions that use GTID_NEXT=AUTOMATIC.
3413 /// The number of GTID-violating transactions that use GTID_NEXT=AUTOMATIC.
3415 /// The number of clients that are executing
3416 /// WAIT_FOR_EXECUTED_GTID_SET or WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS.
3417 std::atomic<int32> atomic_gtid_wait_count{0};
3418
3419 /// Used by unit tests that need to access private members.
3420#ifdef FRIEND_OF_GTID_STATE
3421 friend FRIEND_OF_GTID_STATE;
3422#endif
3423
3424 /**
3425 This is a sub task of update_on_rollback responsible only to handle
3426 the case of a thread that needs to skip GTID operations when it has
3427 "failed to commit".
3428
3429 Administrative commands [CHECK|REPAIR|OPTIMIZE|ANALYZE] TABLE
3430 are written to the binary log even when they fail. When the
3431 commands fail, they will call update_on_rollback; later they will
3432 write the binary log. But we must not do any of the things in
3433 update_gtids_impl if we are going to write the binary log. So
3434 these statements set the skip_gtid_rollback flag, which tells
3435 update_on_rollback to return early. When the statements are
3436 written to the binary log they will call update_on_commit as
3437 usual.
3438
3439 @param[in] thd - Thread to be evaluated.
3440
3441 @retval true The transaction should skip the rollback, false otherwise.
3442 */
3444 /**
3445 This is a sub task of update_gtids_impl responsible only to handle
3446 the case of a thread that owns nothing and does not violate GTID
3447 consistency.
3448
3449 If the THD does not own anything, there is nothing to do, so we can do an
3450 early return of the update process. Except if there is a GTID consistency
3451 violation; then we need to decrease the counter, so then we can continue
3452 executing inside update_gtids_impl.
3453
3454 @param[in] thd - Thread to be evaluated.
3455 @retval true The transaction can be skipped because it owns nothing and
3456 does not violate GTID consistency, false otherwise.
3457 */
3459 /**
3460 This is a sub task of update_gtids_impl responsible only to evaluate
3461 if the thread is committing in the middle of a statement by checking
3462 THD's is_commit_in_middle_of_statement flag.
3463
3464 This flag is true for anonymous transactions, when the
3465 'transaction' has been split into multiple transactions in the
3466 binlog, and the present transaction is not the last one.
3467
3468 This means two things:
3469
3470 - We should not release anonymous ownership in case
3471 gtid_next=anonymous. If we did, it would be possible for user
3472 to set GTID_MODE=ON from a concurrent transaction, making it
3473 impossible to commit the current transaction.
3474
3475 - We should not decrease the counters for GTID-violating
3476 statements. If we did, it would be possible for a concurrent
3477 client to set ENFORCE_GTID_CONSISTENCY=ON despite there is an
3478 ongoing transaction that violates GTID consistency.
3479
3480 The flag is set in two cases:
3481
3482 1. We are committing the statement cache when there are more
3483 changes in the transaction cache.
3484
3485 This happens either because a single statement in the
3486 beginning of a transaction updates both transactional and
3487 non-transactional tables, or because we are committing a
3488 non-transactional update in the middle of a transaction when
3489 binlog_direct_non_transactional_updates=1.
3490
3491 In this case, the flag is set further down in this function.
3492
3493 2. The statement is one of the special statements that may
3494 generate multiple transactions: CREATE...SELECT, DROP TABLE,
3495 DROP DATABASE. See comment for THD::owned_gtid in
3496 sql/sql_class.h.
3497
3498 In this case, the THD::is_commit_in_middle_of_statement flag
3499 is set by the caller and the flag becomes true here.
3500
3501 @param[in] thd - Thread to be evaluated.
3502 @return The value of thread's is_commit_in_middle_of_statement flag.
3503 */
3504 bool update_gtids_impl_begin(THD *thd);
3505 /**
3506 Handle the case that the thread own a set of GTIDs.
3507
3508 This is a sub task of update_gtids_impl responsible only to handle
3509 the case of a thread with a set of GTIDs being updated.
3510
3511 - Release ownership of the GTIDs owned by the THD. This removes
3512 the GTID from Owned_gtids and clears the ownership status in the
3513 THD object.
3514 - Add the owned GTIDs to executed_gtids if the is_commit flag is set.
3515 - Send a broadcast on the condition variable for the sidno which we
3516 released ownership.
3517
3518 @param[in] thd - Thread for which owned GTID set should be updated.
3519 @param[in] is_commit - If the thread is being updated by a commit.
3520 */
3521 void update_gtids_impl_own_gtid_set(THD *thd, bool is_commit);
3522 /**
3523 Lock a given sidno of a transaction being updated.
3524
3525 This is a sub task of update_gtids_impl responsible only to lock the
3526 sidno of the GTID being updated.
3527
3528 @param[in] sidno - The sidno to be locked.
3529 */
3531 /**
3532
3533 Locks the sidnos of all the GTIDs of the commit group starting on the
3534 transaction passed as parameter.
3535
3536 This is a sub task of update_commit_group responsible only to lock the
3537 sidno(s) of the GTID(s) being updated.
3538
3539 The function should follow thd->next_to_commit to lock all sidnos of all
3540 transactions being updated in a group.
3541
3542 @param[in] thd - Thread that owns the GTID(s) to be updated or leader
3543 of the commit group in the case of a commit group
3544 update.
3545 */
3547 /**
3548 Handle the case that the thread own a single non-anonymous GTID.
3549
3550 This is a sub task of update_gtids_impl responsible only to handle
3551 the case of a thread with a single non-anonymous GTID being updated
3552 either for commit or rollback.
3553
3554 - Release ownership of the GTID owned by the THD. This removes
3555 the GTID from Owned_gtids and clears the ownership status in the
3556 THD object.
3557 - Add the owned GTID to executed_gtids if the is_commit flag is set.
3558 - Send a broadcast on the condition variable for the sidno which we
3559 released ownership.
3560
3561 @param[in] thd - Thread to be updated that owns single non-anonymous GTID.
3562 @param[in] is_commit - If the thread is being updated by a commit.
3563 */
3564 void update_gtids_impl_own_gtid(THD *thd, bool is_commit);
3565 /**
3566 Unlock a given sidno after broadcasting its changes.
3567
3568 This is a sub task of update_gtids_impl responsible only to
3569 unlock the sidno of the GTID being updated after broadcasting
3570 its changes.
3571
3572 @param[in] sidno - The sidno to be broadcasted and unlocked.
3573 */
3575 /**
3576 Unlocks all locked sidnos after broadcasting their changes.
3577
3578 This is a sub task of update_commit_group responsible only to
3579 unlock the sidno(s) of the GTID(s) being updated after broadcasting
3580 their changes.
3581 */
3583 /**
3584 Handle the case that the thread owns ANONYMOUS GTID.
3585
3586 This is a sub task of update_gtids_impl responsible only to handle
3587 the case of a thread with an ANONYMOUS GTID being updated.
3588
3589 - Release ownership of the anonymous GTID owned by the THD and clears
3590 the ownership status in the THD object.
3591 - Decrease counters of GTID-violating transactions.
3592
3593 @param[in] thd - Thread to be updated that owns anonymous GTID.
3594 @param[in,out] more_trx - If the 'transaction' has been split into
3595 multiple transactions in the binlog.
3596 This is firstly assigned with the return of
3597 Gtid_state::update_gtids_impl_begin function, and
3598 its value can be set to true when
3599 Gtid_state::update_gtids_impl_anonymous_gtid
3600 detects more content on the transaction cache.
3601 */
3602 void update_gtids_impl_own_anonymous(THD *thd, bool *more_trx);
3603 /**
3604 Handle the case that the thread owns nothing.
3605
3606 This is a sub task of update_gtids_impl responsible only to handle
3607 the case of a thread that owns nothing being updated.
3608
3609 There are two cases when this happens:
3610 - Normally, it is a rollback of an automatic transaction, so
3611 the is_commit is false and gtid_next=automatic.
3612 - There is also a corner case. This case may happen for a transaction
3613 that uses GTID_NEXT=AUTOMATIC, and violates GTID_CONSISTENCY, and
3614 commits changes to the database, but does not write to the binary log,
3615 so that no GTID is generated. An example is CREATE TEMPORARY TABLE
3616 inside a transaction when binlog_format=row. Despite the thread does
3617 not own anything, the GTID consistency violation makes it necessary to
3618 call end_gtid_violating_transaction. Therefore
3619 MYSQL_BIN_LOG::gtid_end_transaction will call
3620 gtid_state->update_on_commit in this case, and subsequently we will
3621 reach this case.
3622
3623 @param[in] thd - Thread to be updated that owns anonymous GTID.
3624 */
3626 /**
3627 Handle the final part of update_gtids_impl.
3628
3629 This is a sub task of update_gtids_impl responsible only to handle
3630 the call to end_gtid_violating_transaction function when there is no
3631 more transactions split after the current transaction.
3632
3633 @param[in] thd - Thread for which owned GTID is updated.
3634 @param[in] more_trx - This is the value returned from
3635 Gtid_state::update_gtids_impl_begin and can be
3636 changed for transactions owning anonymous GTID at
3637 Gtid_state::update_gtids_impl_own_anonymous.
3638 */
3639 void update_gtids_impl_end(THD *thd, bool more_trx);
3640 /**
3641 This array is used by Gtid_state_update_gtids_impl* functions.
3642
3643 The array items (one per sidno of the sid_map) will be set as true for
3644 each sidno that requires to be locked when updating a set of GTIDs
3645 (at Gtid_set::update_gtids_impl_lock_sidnos).
3646
3647 The array items will be set false at
3648 Gtid_set::update_gtids_impl_broadcast_and_unlock_sidnos.
3649
3650 It is used to so that lock, unlock, and broadcast operations are only
3651 called once per sidno per commit group, instead of once per transaction.
3652
3653 Its access is protected by:
3654 - global_sid_lock->wrlock when growing and cleaning up;
3655 - MYSQL_BIN_LOG::LOCK_commit when setting true/false on array items.
3656 */
3658 /**
3659 Ensure that commit_group_sidnos have room for the SIDNO passed as
3660 parameter.
3661
3662 This function must only be called in one place:
3663 Gtid_state::ensure_sidno().
3664
3665 @param sidno The SIDNO.
3666 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
3667 */
3669};
3670
3671/*
3672 BUG# #18089914 - REFACTORING: RENAME GROUP TO GTID
3673 changed AUTOMATIC_GROUP to AUTOMATIC_GTID
3674 changed ANONYMOUS_GROUP to ANONYMOUS_GTID
3675 changed INVALID_GROUP to INVALID_GTID
3676 changed UNDEFINED_GROUP to UNDEFINED_GTID
3677 changed GTID_GROUPto ASSIGNED_GTID
3678 changed NOT_YET_DETERMINED_GROUP to NOT_YET_DETERMINED_GTID
3679*/
3680
3681/**
3682 Enumeration of different types of values for Gtid_specification,
3683 i.e, the different internal states that @@session.gtid_next can be in.
3684*/
3686 /**
3687 Specifies that the GTID has not been generated yet; it will be
3688 generated on commit. It will depend on the GTID_MODE: if
3689 GTID_MODE<=OFF_PERMISSIVE, then the transaction will be anonymous;
3690 if GTID_MODE>=ON_PERMISSIVE, then the transaction will be assigned
3691 a new GTID.
3692
3693 This is the default value: thd->variables.gtid_next has this state
3694 when GTID_NEXT="AUTOMATIC".
3695
3696 It is important that AUTOMATIC_GTID==0 so that the default value
3697 for thd->variables->gtid_next.type is AUTOMATIC_GTID.
3698 */
3700 /**
3701 Specifies that the transaction has been assigned a GTID (UUID:NUMBER).
3702
3703 thd->variables.gtid_next has this state when GTID_NEXT="UUID:NUMBER".
3704
3705 This is the state of GTID-transactions replicated to the slave.
3706 */
3708 /**
3709 Specifies that the transaction is anonymous, i.e., it does not
3710 have a GTID and will never be assigned one.
3711
3712 thd->variables.gtid_next has this state when GTID_NEXT="ANONYMOUS".
3713
3714 This is the state of any transaction generated on a pre-GTID
3715 server, or on a server with GTID_MODE==OFF.
3716 */
3718 /**
3719 GTID_NEXT is set to this state after a transaction with
3720 GTID_NEXT=='UUID:NUMBER' is committed.
3721
3722 This is used to protect against a special case of unsafe
3723 non-transactional updates.
3724
3725 Background: Non-transactional updates are allowed as long as they
3726 are sane. Non-transactional updates must be single-statement
3727 transactions; they must not be mixed with transactional updates in
3728 the same statement or in the same transaction. Since
3729 non-transactional updates must be logged separately from
3730 transactional updates, a single mixed statement would generate two
3731 different transactions.
3732
3733 Problematic case: Consider a transaction, Tx1, that updates two
3734 transactional tables on the master, t1 and t2. Then slave (s1) later
3735 replays Tx1. However, t2 is a non-transactional table at s1. As such, s1
3736 will report an error because it cannot split Tx1 into two different
3737 transactions. Had no error been reported, then Tx1 would be split into Tx1
3738 and Tx2, potentially causing severe harm in case some form of fail-over
3739 procedure is later engaged by s1.
3740
3741 To detect this case on the slave and generate an appropriate error
3742 message rather than causing an inconsistency in the GTID state, we
3743 do as follows. When committing a transaction that has
3744 GTID_NEXT==UUID:NUMBER, we set GTID_NEXT to UNDEFINED_GTID. When
3745 the next part of the transaction is being processed, an error is
3746 generated, because it is not allowed to execute a transaction when
3747 GTID_NEXT==UNDEFINED. In the normal case, the error is not
3748 generated, because there will always be a Gtid_log_event after the
3749 next transaction.
3750 */
3752 /**
3753 GTID_NEXT is set to this state by the slave applier thread when it
3754 reads a Format_description_log_event that does not originate from
3755 this server.
3756
3757 Background: when the slave applier thread reads a relay log that
3758 comes from a pre-GTID master, it must preserve the transactions as
3759 anonymous transactions, even if GTID_MODE>=ON_PERMISSIVE. This
3760 may happen, e.g., if the relay log was received when master and
3761 slave had GTID_MODE=OFF or when master and slave were old, and the
3762 relay log is applied when slave has GTID_MODE>=ON_PERMISSIVE.
3763
3764 So the slave thread should set GTID_NEXT=ANONYMOUS for the next
3765 transaction when it starts to process an old binary log. However,
3766 there is no way for the slave to tell if the binary log is old,
3767 until it sees the first transaction. If the first transaction
3768 begins with a Gtid_log_event, we have the GTID there; if it begins
3769 with query_log_event, row events, etc, then this is an old binary
3770log. So at the time the binary log begins, we just set
3771 GTID_NEXT=NOT_YET_DETERMINED_GTID. If it remains
3772 NOT_YET_DETERMINED when the next transaction begins,
3773 gtid_pre_statement_checks will automatically turn it into an
3774 anonymous transaction. If a Gtid_log_event comes across before
3775 the next transaction starts, then the Gtid_log_event will just set
3776 GTID_NEXT='UUID:NUMBER' accordingly.
3777 */
3779 /**
3780 The applier sets GTID_NEXT this state internally, when it
3781 processes an Anonymous_gtid_log_event on a channel having
3782 ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS, before it calls
3783 set_gtid_next. This tells set_gtid_next to generate a new,
3784 sequential GTID, and acquire ownership for it. Thus, this state
3785 is only used for a very brief period of time. It is not
3786 user-visible.
3787 */
3790/// Global state of GTIDs.
3791extern Gtid_state *gtid_state;
3792
3793/**
3794 This struct represents a specification of a GTID for a statement to
3795 be executed: either "AUTOMATIC", "ANONYMOUS", or "SID:GNO".
3796
3797 This is a POD. It has to be a POD because it is used in THD::variables.
3798*/
3800 /// The type of this GTID
3802 /**
3803 The GTID:
3804 { SIDNO, GNO } if type == GTID;
3805 { 0, 0 } if type == AUTOMATIC or ANONYMOUS.
3806 */
3808 /// Set the type to ASSIGNED_GTID and SID, GNO to the given values.
3809 void set(rpl_sidno sidno, rpl_gno gno) {
3810 gtid.set(sidno, gno);
3812 }
3813 /// Set the type to ASSIGNED_GTID and SID, GNO to the given Gtid.
3814 void set(const Gtid &gtid_param) { set(gtid_param.sidno, gtid_param.gno); }
3815 /// Set the type to AUTOMATIC_GTID.
3817 /// Set the type to ANONYMOUS_GTID.
3819 /// Set the type to NOT_YET_DETERMINED_GTID.
3821 /// Set to undefined. Must only be called if the type is ASSIGNED_GTID.
3823 assert(type == ASSIGNED_GTID);
3825 }
3826 /// Return true if this Gtid_specification is equal to 'other'.
3827 bool equals(const Gtid_specification &other) const {
3828 return (type == other.type &&
3829 (type != ASSIGNED_GTID || gtid.equals(other.gtid)));
3830 }
3831 /**
3832 Return true if this Gtid_specification is a ASSIGNED_GTID with the
3833 same SID, GNO as 'other_gtid'.
3834 */
3835 bool equals(const Gtid &other_gtid) const {
3836 return type == ASSIGNED_GTID && gtid.equals(other_gtid);
3837 }
3838#ifdef MYSQL_SERVER
3839 /**
3840 Parses the given string and stores in this Gtid_specification.
3841
3842 @param sid_map sid_map to use when converting SID to a sidno.
3843 @param text The text to parse
3844 @return RETURN_STATUS_OK or RETURN_STATUS_REPORTED_ERROR.
3845 */
3846 enum_return_status parse(Sid_map *sid_map, const char *text);
3847 /// Returns true if the given string is a valid Gtid_specification.
3848 static bool is_valid(const char *text);
3849#endif
3851 /**
3852 Writes this Gtid_specification to the given string buffer.
3853
3854 @param sid_map Sid_map to use if the type of this
3855 Gtid_specification is ASSIGNED_GTID.
3856 @param [out] buf The buffer
3857 @param need_lock If true, this function acquires global_sid_lock
3858 before looking up the sidno in sid_map, and then releases it. If
3859 false, this function asserts that the lock is held by the caller.
3860 @retval The number of characters written.
3861 */
3862 int to_string(const Sid_map *sid_map, char *buf,
3863 bool need_lock = false) const;
3864 /**
3865 Writes this Gtid_specification to the given string buffer.
3866
3867 @param sid SID to use if the type of this Gtid_specification is
3868 ASSIGNED_GTID. Can be NULL if this Gtid_specification is
3869 ANONYMOUS_GTID or AUTOMATIC_GTID.
3870 @param[out] buf The buffer
3871 @retval The number of characters written.
3872 */
3873 int to_string(const rpl_sid *sid, char *buf) const;
3874#ifndef NDEBUG
3875 /// Debug only: print this Gtid_specification to stdout.
3876 void print() const {
3877 char buf[MAX_TEXT_LENGTH + 1];
3879 printf("%s\n", buf);
3880 }
3881#endif
3882 /**
3883 Print this Gtid_specification to the trace file if debug is
3884 enabled; no-op otherwise.
3885 */
3886 void dbug_print(const char *text [[maybe_unused]] = "",
3887 bool need_lock [[maybe_unused]] = false) const {
3888#ifndef NDEBUG
3889 char buf[MAX_TEXT_LENGTH + 1];
3890 to_string(global_sid_map, buf, need_lock);
3891 DBUG_PRINT("info", ("%s%s%s", text, *text ? ": " : "", buf));
3892#endif
3893 }
3894};
3895
3896/**
3897 Indicates if a statement should be skipped or not. Used as return
3898 value from gtid_before_statement.
3899*/
3901 /// Statement can execute.
3903 /// Statement should be cancelled.
3905 /**
3906 Statement should be skipped, but there may be an implicit commit
3907 after the statement if gtid_commit is set.
3908 */
3911
3912#ifdef MYSQL_SERVER
3913
3914/**
3915 Check if current transaction should be skipped, that is, if GTID_NEXT
3916 was already logged.
3917
3918 @param thd The calling thread.
3919
3920 @retval true Transaction was already logged.
3921 @retval false Transaction must be executed.
3922*/
3923bool is_already_logged_transaction(const THD *thd);
3924
3925/**
3926 Perform GTID-related checks before executing a statement:
3927
3928 - Check that the current statement does not contradict
3929 enforce_gtid_consistency.
3930
3931 - Check that there is no implicit commit in a transaction when
3932 GTID_NEXT==UUID:NUMBER.
3933
3934 - Change thd->variables.gtid_next.type to ANONYMOUS_GTID if it is
3935 currently NOT_YET_DETERMINED_GTID.
3936
3937 - Check whether the statement should be cancelled.
3938
3939 @param thd THD object for the session.
3940
3941 @retval GTID_STATEMENT_EXECUTE The normal case: the checks
3942 succeeded, and statement can execute.
3943
3944 @retval GTID_STATEMENT_CANCEL The checks failed; an
3945 error has be generated and the statement must stop.
3946
3947 @retval GTID_STATEMENT_SKIP The checks succeeded, but the GTID has
3948 already been executed (exists in GTID_EXECUTED). So the statement
3949 must not execute; however, if there are implicit commits, then the
3950 implicit commits must execute.
3951*/
3953
3954/**
3955 Perform GTID-related checks before executing a statement, but after
3956 executing an implicit commit before the statement, if any:
3957
3958 If gtid_next=anonymous, but the thread does not hold anonymous
3959 ownership, then acquire anonymous ownership. (Do this only if this
3960 is not an 'innocent' statement, i.e., SET/SHOW/DO/SELECT that does
3961 not invoke a stored function.)
3962
3963 It is important that this is done after the implicit commit, because
3964 the implicit commit may release anonymous ownership.
3965
3966 @param thd THD object for the session
3967
3968 @retval false Success.
3969
3970 @retval true Error. Error can happen if GTID_MODE=ON. The error has
3971 been reported by (a function called by) this function.
3972*/
3974
3975/**
3976 Acquire ownership of the given Gtid_specification.
3977
3978 The Gtid_specification must be of type ASSIGNED_GTID or ANONYMOUS_GTID.
3979
3980 The caller must hold global_sid_lock (normally the rdlock). The
3981 lock may be temporarily released and acquired again. In the end,
3982 the lock will be released, so the caller should *not* release the
3983 lock.
3984
3985 The function will try to acquire ownership of the GTID and update
3986 both THD::gtid_next, Gtid_state::owned_gtids, and
3987 THD::owned_gtid / THD::owned_sid.
3988
3989 @param thd The thread that acquires ownership.
3990
3991 @param spec The Gtid_specification.
3992
3993 @retval false Success: either we have acquired ownership of the
3994 GTID, or it is already included in GTID_EXECUTED and will be
3995 skipped.
3996
3997 @retval true Failure; the thread was killed or an error occurred.
3998 The error has been reported using my_error.
3999*/
4000bool set_gtid_next(THD *thd, const Gtid_specification &spec);
4001#ifdef HAVE_GTID_NEXT_LIST
4002int gtid_acquire_ownership_multiple(THD *thd);
4003#endif
4004
4005/**
4006 Return sidno for a given sid, see Sid_map::add_sid() for details.
4007*/
4009
4010/**
4011 Return last gno for a given sidno, see
4012 Gtid_state::get_last_executed_gno() for details.
4013*/
4015
4017
4018/**
4019 If gtid_next=ANONYMOUS or NOT_YET_DETERMINED, but the thread does
4020 not hold anonymous ownership, acquire anonymous ownership.
4021
4022 @param thd Thread.
4023
4024 @retval true Error (can happen if gtid_mode=ON and
4025 gtid_next=anonymous). The error has already been reported using
4026 my_error.
4027
4028 @retval false Success.
4029*/
4031
4032/**
4033 The function commits or rolls back the gtid state if it needs to.
4034 It's supposed to be invoked at the end of transaction commit or
4035 rollback, as well as as at the end of XA prepare.
4036
4037 @param thd Thread context
4038 @param needs_to The actual work will be done when the parameter is true
4039 @param do_commit When true the gtid state changes are committed, otherwise
4040 they are rolled back.
4041*/
4042
4043inline void gtid_state_commit_or_rollback(THD *thd, bool needs_to,
4044 bool do_commit) {
4045 if (needs_to) {
4046 if (do_commit)
4048 else
4050 }
4051}
4052
4053#endif // ifdef MYSQL_SERVER
4054
4055#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:1982
Const_interval_iterator(const Gtid_set *gtid_set)
Create this Const_interval_iterator.
Definition: rpl_gtid.h:1989
Const_interval_iterator(const Gtid_set *gtid_set, rpl_sidno sidno)
Create this Const_interval_iterator.
Definition: rpl_gtid.h:1985
Class representing a lock on free_intervals_mutex.
Definition: rpl_gtid.h:2210
bool locked
Definition: rpl_gtid.h:2234
void unlock_if_locked()
Lock the lock if it is locked.
Definition: rpl_gtid.h:2223
Free_intervals_lock(Gtid_set *_gtid_set)
Create a new lock, but do not acquire it.
Definition: rpl_gtid.h:2213
~Free_intervals_lock()
Destroy this object and unlock the lock if it is locked.
Definition: rpl_gtid.h:2230
void lock_if_not_locked()
Lock the lock if it is not already locked.
Definition: rpl_gtid.h:2216
Gtid_set * gtid_set
Definition: rpl_gtid.h:2233
Iterator over all gtids in a Gtid_set.
Definition: rpl_gtid.h:2040
Gtid get() const
Return next gtid, or {0,0} if we reached the end.
Definition: rpl_gtid.h:2066
rpl_sidno sidno
The SIDNO of the current element, or 0 if the iterator is past the last element.
Definition: rpl_gtid.h:2093
const Gtid_set * gtid_set
The Gtid_set we iterate over.
Definition: rpl_gtid.h:2088
void next()
Advance to next gtid.
Definition: rpl_gtid.h:2047
rpl_gno gno
The GNO of the current element, or 0 if the iterator is past the last element.
Definition: rpl_gtid.h:2098
Const_interval_iterator ivit
Iterator over the intervals for the current SIDNO.
Definition: rpl_gtid.h:2100
Gtid_iterator(const Gtid_set *gs)
Definition: rpl_gtid.h:2042
void next_sidno()
Find the next sidno that has one or more intervals.
Definition: rpl_gtid.h:2073
Iterator over intervals for a given SIDNO.
Definition: rpl_gtid.h:1941
Interval_p get() const
Return current_elem.
Definition: rpl_gtid.h:1967
void init(Gtid_set_p gtid_set, rpl_sidno sidno)
Reset this iterator.
Definition: rpl_gtid.h:1958
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:1949
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:1975
Interval_iterator_base(Gtid_set_p gtid_set)
Construct a new iterator over the free intervals of a Gtid_set.
Definition: rpl_gtid.h:1954
void next()
Advance current_elem one step.
Definition: rpl_gtid.h:1962
Iterator over intervals of a non-const Gtid_set, with additional methods to modify the Gtid_set.
Definition: rpl_gtid.h:1999
Interval_iterator(Gtid_set *gtid_set)
Destroy this Interval_iterator.
Definition: rpl_gtid.h:2005
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:2013
void insert(Interval *iv)
Insert the given element before current_elem.
Definition: rpl_gtid.h:2015
void remove(Gtid_set *gtid_set)
Remove current_elem.
Definition: rpl_gtid.h:2020
Interval_iterator(Gtid_set *gtid_set, rpl_sidno sidno)
Create this Interval_iterator.
Definition: rpl_gtid.h:2002
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:1248
void put_free_interval(Interval *iv)
Puts the given interval in the list of free intervals.
Definition: rpl_gtid_set.cc:266
rpl_gno get_last_gno(rpl_sidno sidno) const
Definition: rpl_gtid_set.cc:735
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:1237
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:1158
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:1079
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:1924
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:1755
int get_n_intervals() const
Return the number of intervals in this Gtid_set.
Definition: rpl_gtid.h:2153
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:924
Sid_map * sid_map
Sid_map associated with this Gtid_set.
Definition: rpl_gtid.h:2327
friend std::ostream & operator<<(std::ostream &os, const Gtid_set &in)
For use with C++ std::ostream
Definition: rpl_gtid.h:1848
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:622
Checkable_rwlock * sid_lock
Read-write lock that protects updates to the number of SIDs.
Definition: rpl_gtid.h:2191
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:1000
void init()
Worker for the constructor.
Definition: rpl_gtid_set.cc:113
static const int CHUNK_GROW_SIZE
The default number of intervals in an Interval_chunk.
Definition: rpl_gtid.h:2126
Interval_chunk * chunks
Linked list of chunks.
Definition: rpl_gtid.h:2336
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:1892
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:717
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:143
int get_n_intervals(rpl_sidno sidno) const
Return the number of intervals for the given sidno.
Definition: rpl_gtid.h:2143
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:658
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:2334
bool contains_gtid(const Gtid &gtid) const
Return true iff the given GTID exists in this set.
Definition: rpl_gtid.h:1652
static const String_format default_string_format
The default String_format: the format understood by add_gtid_text(const char *).
Definition: rpl_gtid.h:1882
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:299
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:191
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:690
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:1839
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:2332
mysql_mutex_t free_intervals_mutex
Lock protecting the list of free intervals.
Definition: rpl_gtid.h:2196
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:1860
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:1041
int n_chunks
The number of chunks.
Definition: rpl_gtid.h:2348
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:635
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:579
void clear()
Removes all gtids from this Gtid_set.
Definition: rpl_gtid_set.cc:274
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:1121
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:1211
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:361
void get_gtid_intervals(std::list< Gtid_interval > *gtid_intervals) const
Gets all gtid intervals from this Gtid_set.
Definition: rpl_gtid_set.cc:838
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:1679
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:880
size_t cached_string_length
The string length.
Definition: rpl_gtid.h:2340
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:435
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:312
void _add_gtid(rpl_sidno sidno, rpl_gno gno)
Adds the given GTID to this Gtid_set.
Definition: rpl_gtid.h:1525
bool is_empty() const
Returns true if this Gtid_set is empty.
Definition: rpl_gtid.h:1712
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:1887
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:942
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:1296
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:649
size_t get_encoded_length() const
Returns the length of this Gtid_set when encoded using the encode() function.
Definition: rpl_gtid_set.cc:1381
~Gtid_set()
Destroy this Gtid_set.
Definition: rpl_gtid_set.cc:128
void claim_memory_ownership(bool claim)
Claim ownership of memory.
Definition: rpl_gtid_set.cc:102
bool has_cached_string_length
If the string is cached.
Definition: rpl_gtid.h:2338
const String_format * cached_string_format
The String_format that was used when cached_string_length was computed.
Definition: rpl_gtid.h:2342
void get_free_interval(Interval **out)
Returns a fresh new Interval object.
Definition: rpl_gtid_set.cc:253
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:772
void _remove_gtid(const Gtid &gtid)
Removes the given GTID from this Gtid_set.
Definition: rpl_gtid.h:1563
Sid_map * get_sid_map() const
Return the Sid_map associated with this Gtid_set.
Definition: rpl_gtid.h:1895
void _remove_gtid(rpl_sidno sidno, rpl_gno gno)
Removes the given GTID from this Gtid_set.
Definition: rpl_gtid.h:1541
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:202
void _add_gtid(const Gtid &gtid)
Adds the given GTID to this Gtid_set.
Definition: rpl_gtid.h:1557
rpl_sidno get_max_sidno() const
Returns the maximal sidno that this Gtid_set currently has space for.
Definition: rpl_gtid.h:1658
void assert_free_intervals_locked()
Definition: rpl_gtid.h:2236
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:1735
Represents the server's GTID state: the set of committed GTIDs, the set of lost gtids,...
Definition: rpl_gtid.h:2710
bool update_gtids_impl_check_skip_gtid_rollback(THD *thd)
Used by unit tests that need to access private members.
Definition: rpl_gtid_state.cc:767
int init()
Add @GLOBAL.SERVER_UUID to this binlog's Sid_map.
Definition: rpl_gtid_state.cc: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:776
void end_automatic_gtid_violating_transaction()
Decrease the global counter when ending a GTID-violating transaction having GTID_NEXT=AUTOMATIC.
Definition: rpl_gtid.h:2899
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:3203
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:3259
const Gtid_set * get_lost_gtids() const
Return a pointer to the Gtid_set that contains the lost gtids.
Definition: rpl_gtid.h:3198
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:2929
rpl_sidno server_sidno
The SIDNO for this server.
Definition: rpl_gtid.h:3407
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:944
void update_gtids_impl_lock_sidno(rpl_sidno sidno)
Lock a given sidno of a transaction being updated.
Definition: rpl_gtid_state.cc:827
rpl_gno next_free_gno
The next_free_gno variable will be set with the supposed next free GNO every time a new GNO is delive...
Definition: rpl_gtid.h:3048
Sid_map * sid_map
The Sid_map used by this Gtid_state.
Definition: rpl_gtid.h:3384
std::atomic< int32 > atomic_anonymous_gtid_count
The number of anonymous transactions owned by any client.
Definition: rpl_gtid.h:3410
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:2996
Gtid_state(Checkable_rwlock *_sid_lock, Sid_map *_sid_map)
Constructs a new Gtid_state object.
Definition: rpl_gtid.h:2719
Gtid_set lost_gtids
The set of GTIDs that existed in some previously purged binary log.
Definition: rpl_gtid.h:3391
const Owned_gtids * get_owned_gtids() const
Return a pointer to the Owned_gtids that contains the owned gtids.
Definition: rpl_gtid.h:3219
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:3223
Owned_gtids owned_gtids
The set of GTIDs that are owned by some thread.
Definition: rpl_gtid.h:3405
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:3221
const Gtid_set * get_previous_gtids_logged() const
Definition: rpl_gtid.h:3215
void update_gtids_impl_broadcast_and_unlock_sidno(rpl_sidno sidno)
Unlock a given sidno after broadcasting its changes.
Definition: rpl_gtid_state.cc:908
int32 get_gtid_wait_count()
Return the number of clients that have an ongoing call to WAIT_FOR_EXECUTED_GTID_SET or WAIT_UNTIL_SQ...
Definition: rpl_gtid.h:3013
Mutex_cond_array sid_locks
Contains one mutex/cond pair for every SIDNO.
Definition: rpl_gtid.h:3386
char * to_string() const
Debug only: return a newly allocated string, or NULL on out-of-memory.
Definition: rpl_gtid.h:3252
int read_gtid_executed_from_table()
Fetch gtids from gtid_executed table and store them into gtid_executed set.
Definition: rpl_gtid_state.cc:752
Gtid_set previous_gtids_logged
Definition: rpl_gtid.h:3403
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:3208
int compress(THD *thd)
Compress the gtid_executed table, read each row by the PK(sid, gno_start) in increasing order,...
Definition: rpl_gtid_state.cc:756
int32 get_anonymous_gtid_violating_transaction_count()
Return the number of ongoing GTID-violating transactions having GTID_NEXT=AUTOMATIC.
Definition: rpl_gtid.h:2971
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:3093
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:954
void update_gtids_impl_own_anonymous(THD *thd, bool *more_trx)
Handle the case that the thread owns ANONYMOUS GTID.
Definition: rpl_gtid_state.cc:922
bool wait_for_gtid(THD *thd, const Gtid &gtid, struct timespec *abstime=nullptr)
This is only a shorthand for wait_for_sidno, which contains additional debug printouts and assertions...
Definition: rpl_gtid_state.cc:289
void acquire_anonymous_ownership()
Acquire anonymous ownership.
Definition: rpl_gtid.h:2843
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:760
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:3401
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:3396
void update_gtids_impl_own_gtid(THD *thd, bool is_commit)
Handle the case that the thread own a single non-anonymous GTID.
Definition: rpl_gtid_state.cc:854
int32 get_automatic_gtid_violating_transaction_count()
Return the number of ongoing GTID-violating transactions having GTID_NEXT=AUTOMATIC.
Definition: rpl_gtid.h:2921
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:3269
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:3089
bool is_owned(const Gtid &gtid) const
Returns true if GTID is owned, otherwise returns 0.
Definition: rpl_gtid.h:2776
int to_string(char *buf) const
Debug only: Generate a string in the given buffer and return the length.
Definition: rpl_gtid.h:3239
bool is_executed(const Gtid &gtid) const
Returns true if the given GTID is logged.
Definition: rpl_gtid.h:2763
Prealloced_array< bool, 8 > commit_group_sidnos
This array is used by Gtid_state_update_gtids_impl* functions.
Definition: rpl_gtid.h:3657
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:3382
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:2879
void update_gtids_impl_broadcast_and_unlock_sidnos()
Unlocks all locked sidnos after broadcasting their changes.
Definition: rpl_gtid_state.cc:914
void lock_sidno(rpl_sidno sidno)
Locks a mutex for the given SIDNO.
Definition: rpl_gtid.h:3087
void update_gtids_impl_own_gtid_set(THD *thd, bool is_commit)
Handle the case that the thread own a set of GTIDs.
Definition: rpl_gtid_state.cc:799
void broadcast_sidnos(const Gtid_set *set)
Broadcasts the condition variable for each SIDNO where the given Gtid_set has at least one GTID.
Definition: rpl_gtid_state.cc: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:3232
std::atomic< int32 > atomic_automatic_gtid_violation_count
The number of GTID-violating transactions that use GTID_NEXT=AUTOMATIC.
Definition: rpl_gtid.h:3412
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:3417
void end_anonymous_gtid_violating_transaction()
Decrease the global counter when ending a GTID-violating transaction having GTID_NEXT=ANONYMOUS.
Definition: rpl_gtid.h:2947
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:3414
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:833
int32 get_anonymous_ownership_count()
Return the number of clients that hold anonymous ownership.
Definition: rpl_gtid.h:2873
void update_gtids_impl_end(THD *thd, bool more_trx)
Handle the final part of update_gtids_impl.
Definition: rpl_gtid_state.cc:950
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:789
void broadcast_sidno(rpl_sidno sidno)
Broadcasts updates for the given SIDNO.
Definition: rpl_gtid.h:3091
void release_anonymous_ownership()
Release anonymous ownership.
Definition: rpl_gtid.h:2858
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:2979
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:2614
rpl_sidno max_sidno
Max SIDNO of the current iterator.
Definition: rpl_gtid.h:2669
Node * node
Current node on current SIDNO hash.
Definition: rpl_gtid.h:2676
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:2674
const Owned_gtids * owned_gtids
The Owned_gtids set we iterate over.
Definition: rpl_gtid.h:2665
Node * get_node() const
Return the current GTID Node, or NULL if we reached the end.
Definition: rpl_gtid.h:2661
Gtid_iterator(const Owned_gtids *og)
Definition: rpl_gtid.h:2616
Gtid get() const
Return next GTID, or {0,0} if we reached the end.
Definition: rpl_gtid.h:2652
void next()
Advance to next GTID.
Definition: rpl_gtid.h:2626
rpl_sidno sidno
The SIDNO of the current element, or 1 in the initial iteration.
Definition: rpl_gtid.h:2667
malloc_unordered_multimap< rpl_gno, unique_ptr_my_free< Node > > * hash
Current SIDNO hash.
Definition: rpl_gtid.h:2671
Represents the set of GTIDs that are owned by some thread.
Definition: rpl_gtid.h:2425
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:2520
char * to_string() const
Debug only: return a newly allocated string representation of this Owned_gtids.
Definition: rpl_gtid.h:2552
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:2536
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:2477
int to_string(char *out) const
Write a string representation of this Owned_gtids to the given buffer.
Definition: rpl_gtid.h:2493
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:2482
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:2595
Prealloced_array< malloc_unordered_multimap< rpl_gno, unique_ptr_my_free< Node > > *, 8 > sidno_to_hash
Growable array of hashes.
Definition: rpl_gtid.h:2607
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:2570
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:2593
~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:2560
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:2791
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:1052
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:2883
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:4043
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:431
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:3900
@ GTID_STATEMENT_CANCEL
Statement should be cancelled.
Definition: rpl_gtid.h:3904
@ GTID_STATEMENT_EXECUTE
Statement can execute.
Definition: rpl_gtid.h:3902
@ 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:3909
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:423
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:3685
@ UNDEFINED_GTID
GTID_NEXT is set to this state after a transaction with GTID_NEXT=='UUID:NUMBER' is committed.
Definition: rpl_gtid.h:3751
@ 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:3717
@ ASSIGNED_GTID
Specifies that the transaction has been assigned a GTID (UUID:NUMBER).
Definition: rpl_gtid.h:3707
@ 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:3788
@ NOT_YET_DETERMINED_GTID
Definition: rpl_gtid.h:3778
@ AUTOMATIC_GTID
Specifies that the GTID has not been generated yet; it will be generated on commit.
Definition: rpl_gtid.h:3699
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:2121
Interval intervals[1]
Definition: rpl_gtid.h:2123
Interval_chunk * next
Definition: rpl_gtid.h:2122
Represents one element in the linked list of intervals associated with a SIDNO.
Definition: rpl_gtid.h:1901
rpl_gno start
The first GNO of this interval.
Definition: rpl_gtid.h:1904
rpl_gno end
The first GNO after this interval.
Definition: rpl_gtid.h:1906
bool equals(const Interval &other) const
Return true iff this interval is equal to the given interval.
Definition: rpl_gtid.h:1908
Interval * next
Pointer to next interval in list.
Definition: rpl_gtid.h:1912
Class Gtid_set::String_format defines the separators used by Gtid_set::to_string.
Definition: rpl_gtid.h:1771
const int sid_gno_separator_length
Definition: rpl_gtid.h:1789
const char * end
The generated string begins with this.
Definition: rpl_gtid.h:1775
const int begin_length
The following fields are the lengths of each field above.
Definition: rpl_gtid.h:1787
const int gno_start_end_separator_length
Definition: rpl_gtid.h:1790
const char * gno_sid_separator
In 'SID:GNO,SID:GNO', this is the ','.
Definition: rpl_gtid.h:1783
const char * sid_gno_separator
In 'SID:GNO', this is the ':'.
Definition: rpl_gtid.h:1777
const int empty_set_string_length
Definition: rpl_gtid.h:1793
const int gno_gno_separator_length
Definition: rpl_gtid.h:1791
const char * begin
The generated string begins with this.
Definition: rpl_gtid.h:1773
const char * empty_set_string
If the set is empty and this is not NULL, then this string is generated.
Definition: rpl_gtid.h:1785
const char * gno_gno_separator
In 'SID:GNO:GNO', this is the second ':'.
Definition: rpl_gtid.h:1781
const char * gno_start_end_separator
In 'SID:GNO-GNO', this is the '-'.
Definition: rpl_gtid.h:1779
const int gno_sid_separator_length
Definition: rpl_gtid.h:1792
const int end_length
Definition: rpl_gtid.h:1788
Holds information about a Gtid_set.
Definition: rpl_gtid.h:2378
Gtid_set * gtid_set
Pointer to the Gtid_set.
Definition: rpl_gtid.h:2380
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:2393
Gtid_set * get_gtid_set() const
Return NULL if this is NULL, otherwise return the Gtid_set.
Definition: rpl_gtid.h:2384
void set_null()
Set this Gtid_set to NULL.
Definition: rpl_gtid.h:2404
bool is_non_null
True if this Gtid_set is NULL.
Definition: rpl_gtid.h:2382
This struct represents a specification of a GTID for a statement to be executed: either "AUTOMATIC",...
Definition: rpl_gtid.h:3799
void set_not_yet_determined()
Set the type to NOT_YET_DETERMINED_GTID.
Definition: rpl_gtid.h:3820
enum_gtid_type type
The type of this GTID.
Definition: rpl_gtid.h:3801
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:3807
bool equals(const Gtid_specification &other) const
Return true if this Gtid_specification is equal to 'other'.
Definition: rpl_gtid.h:3827
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:3814
static const int MAX_TEXT_LENGTH
Definition: rpl_gtid.h:3850
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:3886
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:3818
void set_undefined()
Set to undefined. Must only be called if the type is ASSIGNED_GTID.
Definition: rpl_gtid.h:3822
void set_automatic()
Set the type to AUTOMATIC_GTID.
Definition: rpl_gtid.h:3816
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:3809
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:3835
void print() const
Debug only: print this Gtid_specification to stdout.
Definition: rpl_gtid.h:3876
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:2586
my_thread_id owner
Owner of the GTID.
Definition: rpl_gtid.h:2590
rpl_gno gno
GNO of the GTID.
Definition: rpl_gtid.h:2588
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