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