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