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