MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rpl_rli.h
1 /* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 #ifndef RPL_RLI_H
17 #define RPL_RLI_H
18 
19 #include "sql_priv.h"
20 #include "rpl_info.h"
21 #include "rpl_utility.h"
22 #include "rpl_tblmap.h"
23 #include "rpl_reporting.h"
24 #include "rpl_utility.h"
25 #include "log.h" /* LOG_INFO */
26 #include "binlog.h" /* MYSQL_BIN_LOG */
27 #include "sql_class.h" /* THD */
28 
29 struct RPL_TABLE_LIST;
30 class Master_info;
31 extern uint sql_slave_skip_counter;
32 
33 /*******************************************************************************
34 Replication SQL Thread
35 
36 Relay_log_info contains:
37  - the current relay log
38  - the current relay log offset
39  - master log name
40  - master log sequence corresponding to the last update
41  - misc information specific to the SQL thread
42 
43 Relay_log_info is initialized from a repository, i.e. table or file, if there is
44 one. Otherwise, data members are intialized with defaults by calling
45 init_relay_log_info().
46 
47 The relay.info table/file shall be updated whenever: (i) the relay log file
48 is rotated, (ii) SQL Thread is stopped, (iii) while processing a Xid_log_event,
49 (iv) after a Query_log_event (i.e. commit or rollback) and (v) after processing
50 any statement written to the binary log without a transaction context.
51 
52 The Xid_log_event is a commit for transactional engines and must be handled
53 differently to provide reliability/data integrity. In this case, positions
54 are updated within the context of the current transaction. So
55 
56  . If the relay.info is stored in a transactional repository and the server
57  crashes before successfully committing the transaction the changes to the
58  position table will be rolled back along with the data.
59 
60  . If the relay.info is stored in a non-transactional repository, for instance,
61  a file or a system table created using MyIsam, and the server crashes before
62  successfully committing the transaction the changes to the position table
63  will not be rolled back but data will.
64 
65 In particular, when there are mixed transactions, i.e a transaction that updates
66 both transaction and non-transactional engines, the Xid_log_event is still used
67 but reliability/data integrity cannot be achieved as we shall explain in what
68 follows.
69 
70 Changes to non-transactional engines, such as MyIsam, cannot be rolled back if a
71 failure happens. For that reason, there is no point in updating the positions
72 within the boundaries of any on-going transaction. This is true for both commit
73 and rollback. If a failure happens after processing the pseudo-transaction but
74 before updating the positions, the transaction will be re-executed when the
75 slave is up most likely causing an error that needs to be manually circumvented.
76 This is a well-known issue when non-transactional statements are executed.
77 
78 Specifically, if rolling back any transaction, positions are updated outside the
79 transaction boundaries. However, there may be a problem in this scenario even
80 when only transactional engines are updated. This happens because if there is a
81 rollback and such transaction is written to the binary log, a non-transactional
82 engine was updated or a temporary table was created or dropped within its
83 boundaries.
84 
85 In particular, in both STATEMENT and MIXED logging formats, this happens because
86 any temporary table is automatically dropped after a shutdown/startup.
87 See BUG#26945 for further details.
88 
89 Statements written to the binary log outside the boundaries of a transaction are
90 DDLs or maintenance commands which are not transactional. These means that they
91 cannot be rolled back if a failure happens. In such cases, the positions are
92 updated after processing the events. If a failure happens after processing the
93 statement but before updating the positions, the statement will be
94 re-executed when the slave is up most likely causing an error that needs to be
95 manually circumvented. This is a well-known issue when non-transactional
96 statements are executed.
97 
98 The --sync-relay-log-info does not have effect when a system table, either
99 transactional or non-transactional is used.
100 
101 To correctly recovery from failures, one should combine transactional system
102 tables along with the --relay-log-recovery.
103 *******************************************************************************/
104 class Relay_log_info : public Rpl_info
105 {
106  friend class Rpl_info_factory;
107 
108 public:
115 
118  };
119 
120  /*
121  The SQL thread owns one Relay_log_info, and each client that has
122  executed a BINLOG statement owns one Relay_log_info. This function
123  returns zero for the Relay_log_info object that belongs to the SQL
124  thread and nonzero for Relay_log_info objects that belong to
125  clients.
126  */
127  inline bool belongs_to_client()
128  {
129  DBUG_ASSERT(info_thd);
130  return !info_thd->slave_thread;
131  }
132 
133  /*
134  If true, events with the same server id should be replicated. This
135  field is set on creation of a relay log info structure by copying
136  the value of ::replicate_same_server_id and can be overridden if
137  necessary. For example of when this is done, check sql_binlog.cc,
138  where the BINLOG statement can be used to execute "raw" events.
139  */
140  bool replicate_same_server_id;
141 
142  /*** The following variables can only be read when protect by data lock ****/
143  /*
144  cur_log_fd - file descriptor of the current read relay log
145  */
146  File cur_log_fd;
147  /*
148  Protected with internal locks.
149  Must get data_lock when resetting the logs.
150  */
151  MYSQL_BIN_LOG relay_log;
152  LOG_INFO linfo;
153 
154  /*
155  cur_log
156  Pointer that either points at relay_log.get_log_file() or
157  &rli->cache_buf, depending on whether the log is hot or there was
158  the need to open a cold relay_log.
159 
160  cache_buf
161  IO_CACHE used when opening cold relay logs.
162  */
163  IO_CACHE cache_buf,*cur_log;
164 
165  /*
166  Identifies when the recovery process is going on.
167  See sql/slave.cc:init_recovery for further details.
168  */
169  bool is_relay_log_recovery;
170 
171  /* The following variables are safe to read any time */
172 
173  /*
174  When we restart slave thread we need to have access to the previously
175  created temporary tables. Modified only on init/end and by the SQL
176  thread, read only by SQL thread.
177  */
178  TABLE *save_temporary_tables;
179 
180  /* parent Master_info structure */
181  Master_info *mi;
182 
183  /*
184  Needed to deal properly with cur_log getting closed and re-opened with
185  a different log under our feet
186  */
187  uint32 cur_log_old_open_count;
188 
189  /*
190  Let's call a group (of events) :
191  - a transaction
192  or
193  - an autocommiting query + its associated events (INSERT_ID,
194  TIMESTAMP...)
195  We need these rli coordinates :
196  - relay log name and position of the beginning of the group we currently are
197  executing. Needed to know where we have to restart when replication has
198  stopped in the middle of a group (which has been rolled back by the slave).
199  - relay log name and position just after the event we have just
200  executed. This event is part of the current group.
201  Formerly we only had the immediately above coordinates, plus a 'pending'
202  variable, but this dealt wrong with the case of a transaction starting on a
203  relay log and finishing (commiting) on another relay log. Case which can
204  happen when, for example, the relay log gets rotated because of
205  max_binlog_size.
206  */
207 protected:
208  char group_relay_log_name[FN_REFLEN];
209  ulonglong group_relay_log_pos;
210  char event_relay_log_name[FN_REFLEN];
211  ulonglong event_relay_log_pos;
212  ulonglong future_event_relay_log_pos;
213 
214  /*
215  Original log name and position of the group we're currently executing
216  (whose coordinates are group_relay_log_name/pos in the relay log)
217  in the master's binlog. These concern the *group*, because in the master's
218  binlog the log_pos that comes with each event is the position of the
219  beginning of the group.
220 
221  Note: group_master_log_name, group_master_log_pos must only be
222  written from the thread owning the Relay_log_info (SQL thread if
223  !belongs_to_client(); client thread executing BINLOG statement if
224  belongs_to_client()).
225  */
226  char group_master_log_name[FN_REFLEN];
227  volatile my_off_t group_master_log_pos;
228 
229  /*
230  When it commits, InnoDB internally stores the master log position it has
231  processed so far; the position to store is the one of the end of the
232  committing event (the COMMIT query event, or the event if in autocommit
233  mode).
234  */
235 #if MYSQL_VERSION_ID < 40100
236  ulonglong future_master_log_pos;
237 #else
238  ulonglong future_group_master_log_pos;
239 #endif
240 
241 private:
242  Gtid_set gtid_set;
243 
244 public:
245  int add_logged_gtid(rpl_sidno sidno, rpl_gno gno)
246  {
247  int ret= 0;
248  global_sid_lock->assert_some_lock();
249  DBUG_ASSERT(sidno <= global_sid_map->get_max_sidno());
250  gtid_set.ensure_sidno(sidno);
251  if (gtid_set._add_gtid(sidno, gno) != RETURN_STATUS_OK)
252  ret= 1;
253  return ret;
254  }
255  const Gtid_set *get_gtid_set() const { return &gtid_set; }
256 
257  int init_relay_log_pos(const char* log,
258  ulonglong pos, bool need_data_lock,
259  const char** errmsg,
260  bool look_for_description_event);
261 
262  /*
263  Handling of the relay_log_space_limit optional constraint.
264  ignore_log_space_limit is used to resolve a deadlock between I/O and SQL
265  threads, the SQL thread sets it to unblock the I/O thread and make it
266  temporarily forget about the constraint.
267  */
268  ulonglong log_space_limit,log_space_total;
269  bool ignore_log_space_limit;
270 
271  /*
272  Used by the SQL thread to instructs the IO thread to rotate
273  the logs when the SQL thread needs to purge to release some
274  disk space.
275  */
276  bool sql_force_rotate_relay;
277 
278  time_t last_master_timestamp;
279 
280  void clear_until_condition();
281 
287  {
288  sql_delay= 0;
289  }
290 
291  /*
292  Needed for problems when slave stops and we want to restart it
293  skipping one or more events in the master log that have caused
294  errors, and have been manually applied by DBA already.
295  */
296  volatile uint32 slave_skip_counter;
297  volatile ulong abort_pos_wait; /* Incremented on change master */
298  mysql_mutex_t log_space_lock;
299  mysql_cond_t log_space_cond;
300 
301  /*
302  Condition and its parameters from START SLAVE UNTIL clause.
303 
304  UNTIL condition is tested with is_until_satisfied() method that is
305  called by exec_relay_log_event(). is_until_satisfied() caches the result
306  of the comparison of log names because log names don't change very often;
307  this cache is invalidated by parts of code which change log names with
308  notify_*_log_name_updated() methods. (They need to be called only if SQL
309  thread is running).
310  */
311  enum {UNTIL_NONE= 0, UNTIL_MASTER_POS, UNTIL_RELAY_POS,
312  UNTIL_SQL_BEFORE_GTIDS, UNTIL_SQL_AFTER_GTIDS,
313  UNTIL_SQL_AFTER_MTS_GAPS
314 #ifndef DBUG_OFF
315  , UNTIL_DONE
316 #endif
317 }
318  until_condition;
319  char until_log_name[FN_REFLEN];
320  ulonglong until_log_pos;
321  /* extension extracted from log_name and converted to int */
322  ulong until_log_name_extension;
330  /*
331  True if the current event is the first gtid event to be processed
332  after executing START SLAVE UNTIL SQL_*_GTIDS.
333  */
334  bool until_sql_gtids_first_event;
335  /*
336  Cached result of comparison of until_log_name and current log name
337  -2 means unitialised, -1,0,1 are comarison results
338  */
339  enum
340  {
341  UNTIL_LOG_NAMES_CMP_UNKNOWN= -2, UNTIL_LOG_NAMES_CMP_LESS= -1,
342  UNTIL_LOG_NAMES_CMP_EQUAL= 0, UNTIL_LOG_NAMES_CMP_GREATER= 1
343  } until_log_names_cmp_result;
344 
345  char cached_charset[6];
346  /*
347  trans_retries varies between 0 to slave_transaction_retries and counts how
348  many times the slave has retried the present transaction; gets reset to 0
349  when the transaction finally succeeds. retried_trans is a cumulative
350  counter: how many times the slave has retried a transaction (any) since
351  slave started.
352  */
353  ulong trans_retries, retried_trans;
354 
355  /*
356  If the end of the hot relay log is made of master's events ignored by the
357  slave I/O thread, these two keep track of the coords (in the master's
358  binlog) of the last of these events seen by the slave I/O thread. If not,
359  ign_master_log_name_end[0] == 0.
360  As they are like a Rotate event read/written from/to the relay log, they
361  are both protected by rli->relay_log.LOCK_log.
362  */
363  char ign_master_log_name_end[FN_REFLEN];
364  ulonglong ign_master_log_pos_end;
365 
366  /*
367  Indentifies where the SQL Thread should create temporary files for the
368  LOAD DATA INFILE. This is used for security reasons.
369  */
370  char slave_patternload_file[FN_REFLEN];
371  size_t slave_patternload_file_size;
372 
377 
384  {
385  if (until_condition==UNTIL_RELAY_POS)
386  until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
387  }
388 
394  {
395  if (until_condition==UNTIL_MASTER_POS)
396  until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
397  }
398 
399  inline void inc_event_relay_log_pos()
400  {
401  event_relay_log_pos= future_event_relay_log_pos;
402  }
403 
404  int inc_group_relay_log_pos(ulonglong log_pos,
405  bool need_data_lock);
406 
407  int wait_for_pos(THD* thd, String* log_name, longlong log_pos,
408  longlong timeout);
409  int wait_for_gtid_set(THD* thd, String* gtid, longlong timeout);
410  void close_temporary_tables();
411 
412  /* Check if UNTIL condition is satisfied. See slave.cc for more. */
413  bool is_until_satisfied(THD *thd, Log_event *ev);
414  inline ulonglong until_pos()
415  {
416  return ((until_condition == UNTIL_MASTER_POS) ? group_master_log_pos :
417  group_relay_log_pos);
418  }
419 
420  RPL_TABLE_LIST *tables_to_lock; /* RBR: Tables to lock */
421  uint tables_to_lock_count; /* RBR: Count of tables to lock */
422  table_mapping m_table_map; /* RBR: Mapping table-id to table */
423  /* RBR: Record Rows_query log event */
424  Rows_query_log_event* rows_query_ev;
425 
426  bool get_table_data(TABLE *table_arg, table_def **tabledef_var, TABLE **conv_table_var) const
427  {
428  DBUG_ASSERT(tabledef_var && conv_table_var);
429  for (TABLE_LIST *ptr= tables_to_lock ; ptr != NULL ; ptr= ptr->next_global)
430  if (ptr->table == table_arg)
431  {
432  *tabledef_var= &static_cast<RPL_TABLE_LIST*>(ptr)->m_tabledef;
433  *conv_table_var= static_cast<RPL_TABLE_LIST*>(ptr)->m_conv_table;
434  DBUG_PRINT("debug", ("Fetching table data for table %s.%s:"
435  " tabledef: %p, conv_table: %p",
436  table_arg->s->db.str, table_arg->s->table_name.str,
437  *tabledef_var, *conv_table_var));
438  return true;
439  }
440  return false;
441  }
442 
450  bool cached_charset_compare(char *charset) const;
451 
452  void cleanup_context(THD *, bool);
453  void slave_close_thread_tables(THD *);
454  void clear_tables_to_lock();
455  int purge_relay_logs(THD *thd, bool just_reset, const char** errmsg);
456 
457  /*
458  Used to defer stopping the SQL thread to give it a chance
459  to finish up the current group of events.
460  The timestamp is set and reset in @c sql_slave_killed().
461  */
462  time_t last_event_start_time;
463  /*
464  A container to hold on Intvar-, Rand-, Uservar- log-events in case
465  the slave is configured with table filtering rules.
466  The withhold events are executed when their parent Query destiny is
467  determined for execution as well.
468  */
469  Deferred_log_events *deferred_events;
470 
471  /*
472  State of the container: true stands for IRU events gathering,
473  false does for execution, either deferred or direct.
474  */
475  bool deferred_events_collecting;
476 
477  /*****************************************************************************
478  WL#5569 MTS
479 
480  legends:
481  C - Coordinator;
482  W - Worker;
483  WQ - Worker Queue containing event assignments
484  */
485  DYNAMIC_ARRAY workers; // number's is determined by global slave_parallel_workers
486  volatile ulong pending_jobs;
487  mysql_mutex_t pending_jobs_lock;
488  mysql_cond_t pending_jobs_cond;
489  ulong mts_slave_worker_queue_len_max;
490  ulonglong mts_pending_jobs_size; // actual mem usage by WQ:s
491  ulonglong mts_pending_jobs_size_max; // max of WQ:s size forcing C to wait
492  bool mts_wq_oversize; // C raises flag to wait some memory's released
493  Slave_worker *last_assigned_worker;// is set to a Worker at assigning a group
494  /*
495  master-binlog ordered queue of Slave_job_group descriptors of groups
496  that are under processing. The queue size is @c checkpoint_group.
497  */
498  Slave_committed_queue *gaq;
499  /*
500  Container for references of involved partitions for the current event group
501  */
502  DYNAMIC_ARRAY curr_group_assigned_parts;
503  DYNAMIC_ARRAY curr_group_da; // deferred array to hold partition-info-free events
504  bool curr_group_seen_gtid; // current group started with Gtid-event or not
505  bool curr_group_seen_begin; // current group started with B-event or not
506  bool curr_group_isolated; // current group requires execution in isolation
507  bool mts_end_group_sets_max_dbs; // flag indicates if partitioning info is discovered
508  volatile ulong mts_wq_underrun_w_id; // Id of a Worker whose queue is getting empty
509  /*
510  Ongoing excessive overrun counter to correspond to number of events that
511  are being scheduled while a WQ is close to be filled up.
512  `Close' is defined as (100 - mts_worker_underrun_level) %.
513  The counter is incremented each time a WQ get filled over that level
514  and decremented when the level drops below.
515  The counter therefore describes level of saturation that Workers
516  are experiencing and is used as a parameter to compute a nap time for
517  Coordinator in order to avoid reaching WQ limits.
518  */
519  volatile long mts_wq_excess_cnt;
520  long mts_worker_underrun_level; // % of WQ size at which W is considered hungry
521  ulong mts_coordinator_basic_nap; // C sleeps to avoid WQs overrun
522  ulong opt_slave_parallel_workers; // cache for ::opt_slave_parallel_workers
523  ulong slave_parallel_workers; // the one slave session time number of workers
524  ulong recovery_parallel_workers; // number of workers while recovering
525  uint checkpoint_seqno; // counter of groups executed after the most recent CP
526  uint checkpoint_group; // cache for ::opt_mts_checkpoint_group
527  MY_BITMAP recovery_groups; // bitmap used during recovery
528  bool recovery_groups_inited;
529  ulong mts_recovery_group_cnt; // number of groups to execute at recovery
530  ulong mts_recovery_index; // running index of recoverable groups
531  bool mts_recovery_group_seen_begin;
532 
533  /*
534  Coordinator's specific mem-root to hold various temporary data while
535  the current group is being schedulled. The root is shunk to default size
536  at the end of the group distribution.
537  */
538  MEM_ROOT mts_coor_mem_root;
539 
540  /*
541  While distibuting events basing on their properties MTS
542  Coordinator changes its mts group status.
543  Transition normally flowws to follow `=>' arrows on the diagram:
544 
545  +----------------------------+
546  V |
547  MTS_NOT_IN_GROUP => |
548  {MTS_IN_GROUP => MTS_END_GROUP --+} while (!killed) => MTS_KILLED_GROUP
549 
550  MTS_END_GROUP has `->' loop breaking link to MTS_NOT_IN_GROUP when
551  Coordinator synchronizes with Workers by demanding them to
552  complete their assignments.
553  */
554  enum
555  {
556  /*
557  no new events were scheduled after last synchronization,
558  includes Single-Threaded-Slave case.
559  */
560  MTS_NOT_IN_GROUP,
561 
562  MTS_IN_GROUP, /* at least one not-terminal event scheduled to a Worker */
563  MTS_END_GROUP, /* the last scheduled event is a terminal event */
564  MTS_KILLED_GROUP /* Coordinator gave up to reach MTS_END_GROUP */
565  } mts_group_status;
566 
567  /*
568  MTS statistics:
569  */
570  ulonglong mts_events_assigned; // number of events (statements) scheduled
571  ulong mts_groups_assigned; // number of groups (transactions) scheduled
572  volatile ulong mts_wq_overrun_cnt; // counter of all mts_wq_excess_cnt increments
573  ulong wq_size_waits_cnt; // number of times C slept due to WQ:s oversize
574  /*
575  a counter for sleeps due to Coordinator
576  experienced waiting when Workers get hungry again
577  */
578  ulong mts_wq_no_underrun_cnt;
579  ulong mts_wq_overfill_cnt; // counter of C waited due to a WQ queue was full
580  /*
581  A sorted array of the Workers' current assignement numbers to provide
582  approximate view on Workers loading.
583  The first row of the least occupied Worker is queried at assigning
584  a new partition. Is updated at checkpoint commit to the main RLI.
585  */
586  DYNAMIC_ARRAY least_occupied_workers;
587  time_t mts_last_online_stat;
588  /* end of MTS statistics */
589 
590  /* most of allocation in the coordinator rli is there */
591  void init_workers(ulong);
592 
593  /* counterpart of the init */
594  void deinit_workers();
595 
600  inline bool is_mts_recovery() const
601  {
602  return mts_recovery_group_cnt != 0;
603  }
604 
608  inline bool is_parallel_exec() const
609  {
610  bool ret= (slave_parallel_workers > 0) && !is_mts_recovery();
611 
612  DBUG_ASSERT(!ret || workers.elements > 0);
613 
614  return ret;
615  }
616 
621  inline bool is_mts_in_group()
622  {
623  return is_parallel_exec() &&
624  mts_group_status == MTS_IN_GROUP;
625  }
626 
633 
639  void reset_notified_checkpoint(ulong, time_t, bool);
640 
645  bool mts_finalize_recovery();
646  /*
647  * End of MTS section ******************************************************/
648 
649  /* The general cleanup that slave applier may need at the end of query. */
650  inline void cleanup_after_query()
651  {
652  if (deferred_events)
653  deferred_events->rewind();
654  };
655  /* The general cleanup that slave applier may need at the end of session. */
656  void cleanup_after_session()
657  {
658  if (deferred_events)
659  delete deferred_events;
660  };
661 
675  int stmt_done(my_off_t event_log_pos);
676 
677 
684  {
685  m_flags |= (1UL << flag);
686  }
687 
696  {
697  return m_flags & (1UL << flag);
698  }
699 
706  {
707  m_flags &= ~(1UL << flag);
708  }
709 
720  bool is_in_group() const {
721  return (info_thd->variables.option_bits & OPTION_BEGIN) ||
722  (m_flags & (1UL << IN_STMT));
723  }
724 
725  int count_relay_log_space();
726 
727  int rli_init_info();
728  void end_info();
729  int flush_info(bool force= FALSE);
730  int flush_current_log();
731  void set_master_info(Master_info *info);
732 
733  inline ulonglong get_future_event_relay_log_pos() { return future_event_relay_log_pos; }
734  inline void set_future_event_relay_log_pos(ulonglong log_pos)
735  {
736  future_event_relay_log_pos= log_pos;
737  }
738 
739  inline const char* get_group_master_log_name() { return group_master_log_name; }
740  inline ulonglong get_group_master_log_pos() { return group_master_log_pos; }
741  inline void set_group_master_log_name(const char *log_file_name)
742  {
743  strmake(group_master_log_name,log_file_name, sizeof(group_master_log_name)-1);
744  }
745  inline void set_group_master_log_pos(ulonglong log_pos)
746  {
747  group_master_log_pos= log_pos;
748  }
749 
750  inline const char* get_group_relay_log_name() { return group_relay_log_name; }
751  inline ulonglong get_group_relay_log_pos() { return group_relay_log_pos; }
752  inline void set_group_relay_log_name(const char *log_file_name)
753  {
754  strmake(group_relay_log_name,log_file_name, sizeof(group_relay_log_name)-1);
755  }
756  inline void set_group_relay_log_name(const char *log_file_name, size_t len)
757  {
758  strmake(group_relay_log_name, log_file_name, len);
759  }
760  inline void set_group_relay_log_pos(ulonglong log_pos)
761  {
762  group_relay_log_pos= log_pos;
763  }
764 
765  inline const char* get_event_relay_log_name() { return event_relay_log_name; }
766  inline ulonglong get_event_relay_log_pos() { return event_relay_log_pos; }
767  inline void set_event_relay_log_name(const char *log_file_name)
768  {
769  strmake(event_relay_log_name,log_file_name, sizeof(event_relay_log_name)-1);
770  }
771  inline void set_event_relay_log_name(const char *log_file_name, size_t len)
772  {
773  strmake(event_relay_log_name,log_file_name, len);
774  }
775  inline void set_event_relay_log_pos(ulonglong log_pos)
776  {
777  event_relay_log_pos= log_pos;
778  }
779  inline const char* get_rpl_log_name()
780  {
781  return (group_master_log_name[0] ? group_master_log_name : "FIRST");
782  }
783 
784 #if MYSQL_VERSION_ID < 40100
785  inline ulonglong get_future_master_log_pos() { return future_master_log_pos; }
786 #else
787  inline ulonglong get_future_group_master_log_pos() { return future_group_master_log_pos; }
788  inline void set_future_group_master_log_pos(ulonglong log_pos)
789  {
790  future_group_master_log_pos= log_pos;
791  }
792 #endif
793 
794  static size_t get_number_info_rli_fields();
795 
807  void start_sql_delay(time_t delay_end)
808  {
809  mysql_mutex_assert_owner(&data_lock);
810  sql_delay_end= delay_end;
811  THD_STAGE_INFO(info_thd, stage_sql_thd_waiting_until_delay);
812  }
813 
814  int32 get_sql_delay() { return sql_delay; }
815  void set_sql_delay(time_t _sql_delay) { sql_delay= _sql_delay; }
816  time_t get_sql_delay_end() { return sql_delay_end; }
817 
818  Relay_log_info(bool is_slave_recovery
819 #ifdef HAVE_PSI_INTERFACE
820  ,PSI_mutex_key *param_key_info_run_lock,
821  PSI_mutex_key *param_key_info_data_lock,
822  PSI_mutex_key *param_key_info_sleep_lock,
823  PSI_mutex_key *param_key_info_data_cond,
824  PSI_mutex_key *param_key_info_start_cond,
825  PSI_mutex_key *param_key_info_stop_cond,
826  PSI_mutex_key *param_key_info_sleep_cond
827 #endif
828  , uint param_id
829  );
830  virtual ~Relay_log_info();
831 
832  /*
833  Determines if a warning message on unsafe execution was
834  already printed out to avoid clutering the error log
835  with several warning messages.
836  */
837  bool reported_unsafe_warning;
838 
839  time_t get_row_stmt_start_timestamp()
840  {
841  return row_stmt_start_timestamp;
842  }
843 
844  time_t set_row_stmt_start_timestamp()
845  {
846  if (row_stmt_start_timestamp == 0)
847  row_stmt_start_timestamp= my_time(0);
848 
849  return row_stmt_start_timestamp;
850  }
851 
852  void reset_row_stmt_start_timestamp()
853  {
854  row_stmt_start_timestamp= 0;
855  }
856 
857  void set_long_find_row_note_printed()
858  {
859  long_find_row_note_printed= true;
860  }
861 
862  void unset_long_find_row_note_printed()
863  {
864  long_find_row_note_printed= false;
865  }
866 
867  bool is_long_find_row_note_printed()
868  {
869  return long_find_row_note_printed;
870  }
871 
872 public:
878 
883  {
884  return rli_description_event;
885  }
886 
891  uchar slave_version_split[3]; // bytes of the slave server version
892 
893 protected:
894  Format_description_log_event *rli_description_event;
895 
896 private:
897 
909  int sql_delay;
910 
919  time_t sql_delay_end;
920 
921  uint32 m_flags;
922 
923  /*
924  Before the MASTER_DELAY parameter was added (WL#344), relay_log.info
925  had 4 lines. Now it has 5 lines.
926  */
927  static const int LINES_IN_RELAY_LOG_INFO_WITH_DELAY= 5;
928 
929  /*
930  Before the WL#5599, relay_log.info had 5 lines. Now it has 6 lines.
931  */
932  static const int LINES_IN_RELAY_LOG_INFO_WITH_WORKERS= 6;
933 
934  /*
935  Before the Id was added (BUG#2334346), relay_log.info
936  had 6 lines. Now it has 7 lines.
937  */
938  static const int LINES_IN_RELAY_LOG_INFO_WITH_ID= 7;
939 
940  bool read_info(Rpl_info_handler *from);
941  bool write_info(Rpl_info_handler *to);
942 
943  Relay_log_info(const Relay_log_info& info);
944  Relay_log_info& operator=(const Relay_log_info& info);
945 
946  /*
947  Runtime state for printing a note when slave is taking
948  too long while processing a row event.
949  */
950  time_t row_stmt_start_timestamp;
951  bool long_find_row_note_printed;
952 
953  /*
954  If on init_info() call error_on_rli_init_info is true that means
955  that previous call to init_info() terminated with an error, RESET
956  SLAVE must be executed and the problem fixed manually.
957  */
958  bool error_on_rli_init_info;
959 };
960 
961 bool mysql_show_relaylog_events(THD* thd);
962 
967 inline bool is_mts_worker(const THD *thd)
968 {
969  return thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER;
970 }
971 
972 #endif /* RPL_RLI_H */