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