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