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