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