My Project
|
00001 /* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; version 2 of the License. 00006 00007 This program is distributed in the hope that it will be useful, 00008 but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 GNU General Public License for more details. 00011 00012 You should have received a copy of the GNU General Public License 00013 along with this program; if not, write to the Free Software Foundation, 00014 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ 00015 00016 #ifndef RPL_RLI_H 00017 #define RPL_RLI_H 00018 00019 #include "sql_priv.h" 00020 #include "rpl_info.h" 00021 #include "rpl_utility.h" 00022 #include "rpl_tblmap.h" 00023 #include "rpl_reporting.h" 00024 #include "rpl_utility.h" 00025 #include "log.h" /* LOG_INFO */ 00026 #include "binlog.h" /* MYSQL_BIN_LOG */ 00027 #include "sql_class.h" /* THD */ 00028 00029 struct RPL_TABLE_LIST; 00030 class Master_info; 00031 extern uint sql_slave_skip_counter; 00032 00033 /******************************************************************************* 00034 Replication SQL Thread 00035 00036 Relay_log_info contains: 00037 - the current relay log 00038 - the current relay log offset 00039 - master log name 00040 - master log sequence corresponding to the last update 00041 - misc information specific to the SQL thread 00042 00043 Relay_log_info is initialized from a repository, i.e. table or file, if there is 00044 one. Otherwise, data members are intialized with defaults by calling 00045 init_relay_log_info(). 00046 00047 The relay.info table/file shall be updated whenever: (i) the relay log file 00048 is rotated, (ii) SQL Thread is stopped, (iii) while processing a Xid_log_event, 00049 (iv) after a Query_log_event (i.e. commit or rollback) and (v) after processing 00050 any statement written to the binary log without a transaction context. 00051 00052 The Xid_log_event is a commit for transactional engines and must be handled 00053 differently to provide reliability/data integrity. In this case, positions 00054 are updated within the context of the current transaction. So 00055 00056 . If the relay.info is stored in a transactional repository and the server 00057 crashes before successfully committing the transaction the changes to the 00058 position table will be rolled back along with the data. 00059 00060 . If the relay.info is stored in a non-transactional repository, for instance, 00061 a file or a system table created using MyIsam, and the server crashes before 00062 successfully committing the transaction the changes to the position table 00063 will not be rolled back but data will. 00064 00065 In particular, when there are mixed transactions, i.e a transaction that updates 00066 both transaction and non-transactional engines, the Xid_log_event is still used 00067 but reliability/data integrity cannot be achieved as we shall explain in what 00068 follows. 00069 00070 Changes to non-transactional engines, such as MyIsam, cannot be rolled back if a 00071 failure happens. For that reason, there is no point in updating the positions 00072 within the boundaries of any on-going transaction. This is true for both commit 00073 and rollback. If a failure happens after processing the pseudo-transaction but 00074 before updating the positions, the transaction will be re-executed when the 00075 slave is up most likely causing an error that needs to be manually circumvented. 00076 This is a well-known issue when non-transactional statements are executed. 00077 00078 Specifically, if rolling back any transaction, positions are updated outside the 00079 transaction boundaries. However, there may be a problem in this scenario even 00080 when only transactional engines are updated. This happens because if there is a 00081 rollback and such transaction is written to the binary log, a non-transactional 00082 engine was updated or a temporary table was created or dropped within its 00083 boundaries. 00084 00085 In particular, in both STATEMENT and MIXED logging formats, this happens because 00086 any temporary table is automatically dropped after a shutdown/startup. 00087 See BUG#26945 for further details. 00088 00089 Statements written to the binary log outside the boundaries of a transaction are 00090 DDLs or maintenance commands which are not transactional. These means that they 00091 cannot be rolled back if a failure happens. In such cases, the positions are 00092 updated after processing the events. If a failure happens after processing the 00093 statement but before updating the positions, the statement will be 00094 re-executed when the slave is up most likely causing an error that needs to be 00095 manually circumvented. This is a well-known issue when non-transactional 00096 statements are executed. 00097 00098 The --sync-relay-log-info does not have effect when a system table, either 00099 transactional or non-transactional is used. 00100 00101 To correctly recovery from failures, one should combine transactional system 00102 tables along with the --relay-log-recovery. 00103 *******************************************************************************/ 00104 class Relay_log_info : public Rpl_info 00105 { 00106 friend class Rpl_info_factory; 00107 00108 public: 00112 enum enum_state_flag { 00114 IN_STMT, 00115 00117 STATE_FLAGS_COUNT 00118 }; 00119 00120 /* 00121 The SQL thread owns one Relay_log_info, and each client that has 00122 executed a BINLOG statement owns one Relay_log_info. This function 00123 returns zero for the Relay_log_info object that belongs to the SQL 00124 thread and nonzero for Relay_log_info objects that belong to 00125 clients. 00126 */ 00127 inline bool belongs_to_client() 00128 { 00129 DBUG_ASSERT(info_thd); 00130 return !info_thd->slave_thread; 00131 } 00132 00133 /* 00134 If true, events with the same server id should be replicated. This 00135 field is set on creation of a relay log info structure by copying 00136 the value of ::replicate_same_server_id and can be overridden if 00137 necessary. For example of when this is done, check sql_binlog.cc, 00138 where the BINLOG statement can be used to execute "raw" events. 00139 */ 00140 bool replicate_same_server_id; 00141 00142 /*** The following variables can only be read when protect by data lock ****/ 00143 /* 00144 cur_log_fd - file descriptor of the current read relay log 00145 */ 00146 File cur_log_fd; 00147 /* 00148 Protected with internal locks. 00149 Must get data_lock when resetting the logs. 00150 */ 00151 MYSQL_BIN_LOG relay_log; 00152 LOG_INFO linfo; 00153 00154 /* 00155 cur_log 00156 Pointer that either points at relay_log.get_log_file() or 00157 &rli->cache_buf, depending on whether the log is hot or there was 00158 the need to open a cold relay_log. 00159 00160 cache_buf 00161 IO_CACHE used when opening cold relay logs. 00162 */ 00163 IO_CACHE cache_buf,*cur_log; 00164 00165 /* 00166 Identifies when the recovery process is going on. 00167 See sql/slave.cc:init_recovery for further details. 00168 */ 00169 bool is_relay_log_recovery; 00170 00171 /* The following variables are safe to read any time */ 00172 00173 /* 00174 When we restart slave thread we need to have access to the previously 00175 created temporary tables. Modified only on init/end and by the SQL 00176 thread, read only by SQL thread. 00177 */ 00178 TABLE *save_temporary_tables; 00179 00180 /* parent Master_info structure */ 00181 Master_info *mi; 00182 00183 /* 00184 Needed to deal properly with cur_log getting closed and re-opened with 00185 a different log under our feet 00186 */ 00187 uint32 cur_log_old_open_count; 00188 00189 /* 00190 Let's call a group (of events) : 00191 - a transaction 00192 or 00193 - an autocommiting query + its associated events (INSERT_ID, 00194 TIMESTAMP...) 00195 We need these rli coordinates : 00196 - relay log name and position of the beginning of the group we currently are 00197 executing. Needed to know where we have to restart when replication has 00198 stopped in the middle of a group (which has been rolled back by the slave). 00199 - relay log name and position just after the event we have just 00200 executed. This event is part of the current group. 00201 Formerly we only had the immediately above coordinates, plus a 'pending' 00202 variable, but this dealt wrong with the case of a transaction starting on a 00203 relay log and finishing (commiting) on another relay log. Case which can 00204 happen when, for example, the relay log gets rotated because of 00205 max_binlog_size. 00206 */ 00207 protected: 00208 char group_relay_log_name[FN_REFLEN]; 00209 ulonglong group_relay_log_pos; 00210 char event_relay_log_name[FN_REFLEN]; 00211 ulonglong event_relay_log_pos; 00212 ulonglong future_event_relay_log_pos; 00213 00214 /* 00215 Original log name and position of the group we're currently executing 00216 (whose coordinates are group_relay_log_name/pos in the relay log) 00217 in the master's binlog. These concern the *group*, because in the master's 00218 binlog the log_pos that comes with each event is the position of the 00219 beginning of the group. 00220 00221 Note: group_master_log_name, group_master_log_pos must only be 00222 written from the thread owning the Relay_log_info (SQL thread if 00223 !belongs_to_client(); client thread executing BINLOG statement if 00224 belongs_to_client()). 00225 */ 00226 char group_master_log_name[FN_REFLEN]; 00227 volatile my_off_t group_master_log_pos; 00228 00229 /* 00230 When it commits, InnoDB internally stores the master log position it has 00231 processed so far; the position to store is the one of the end of the 00232 committing event (the COMMIT query event, or the event if in autocommit 00233 mode). 00234 */ 00235 #if MYSQL_VERSION_ID < 40100 00236 ulonglong future_master_log_pos; 00237 #else 00238 ulonglong future_group_master_log_pos; 00239 #endif 00240 00241 private: 00242 Gtid_set gtid_set; 00243 /* Last gtid retrieved by IO thread */ 00244 Gtid last_retrieved_gtid; 00245 00246 public: 00247 Gtid *get_last_retrieved_gtid() { return &last_retrieved_gtid; } 00248 void set_last_retrieved_gtid(Gtid gtid) { last_retrieved_gtid= gtid; } 00249 int add_logged_gtid(rpl_sidno sidno, rpl_gno gno) 00250 { 00251 int ret= 0; 00252 global_sid_lock->assert_some_lock(); 00253 DBUG_ASSERT(sidno <= global_sid_map->get_max_sidno()); 00254 gtid_set.ensure_sidno(sidno); 00255 if (gtid_set._add_gtid(sidno, gno) != RETURN_STATUS_OK) 00256 ret= 1; 00257 return ret; 00258 } 00259 const Gtid_set *get_gtid_set() const { return >id_set; } 00260 00261 int init_relay_log_pos(const char* log, 00262 ulonglong pos, bool need_data_lock, 00263 const char** errmsg, 00264 bool look_for_description_event); 00265 00266 /* 00267 Handling of the relay_log_space_limit optional constraint. 00268 ignore_log_space_limit is used to resolve a deadlock between I/O and SQL 00269 threads, the SQL thread sets it to unblock the I/O thread and make it 00270 temporarily forget about the constraint. 00271 */ 00272 ulonglong log_space_limit,log_space_total; 00273 bool ignore_log_space_limit; 00274 00275 /* 00276 Used by the SQL thread to instructs the IO thread to rotate 00277 the logs when the SQL thread needs to purge to release some 00278 disk space. 00279 */ 00280 bool sql_force_rotate_relay; 00281 00282 time_t last_master_timestamp; 00283 00284 void clear_until_condition(); 00285 00290 void clear_sql_delay() 00291 { 00292 sql_delay= 0; 00293 } 00294 00295 /* 00296 Needed for problems when slave stops and we want to restart it 00297 skipping one or more events in the master log that have caused 00298 errors, and have been manually applied by DBA already. 00299 */ 00300 volatile uint32 slave_skip_counter; 00301 volatile ulong abort_pos_wait; /* Incremented on change master */ 00302 mysql_mutex_t log_space_lock; 00303 mysql_cond_t log_space_cond; 00304 00305 /* 00306 Condition and its parameters from START SLAVE UNTIL clause. 00307 00308 UNTIL condition is tested with is_until_satisfied() method that is 00309 called by exec_relay_log_event(). is_until_satisfied() caches the result 00310 of the comparison of log names because log names don't change very often; 00311 this cache is invalidated by parts of code which change log names with 00312 notify_*_log_name_updated() methods. (They need to be called only if SQL 00313 thread is running). 00314 */ 00315 enum {UNTIL_NONE= 0, UNTIL_MASTER_POS, UNTIL_RELAY_POS, 00316 UNTIL_SQL_BEFORE_GTIDS, UNTIL_SQL_AFTER_GTIDS, 00317 UNTIL_SQL_AFTER_MTS_GAPS 00318 #ifndef DBUG_OFF 00319 , UNTIL_DONE 00320 #endif 00321 } 00322 until_condition; 00323 char until_log_name[FN_REFLEN]; 00324 ulonglong until_log_pos; 00325 /* extension extracted from log_name and converted to int */ 00326 ulong until_log_name_extension; 00333 Gtid_set until_sql_gtids; 00334 /* 00335 True if the current event is the first gtid event to be processed 00336 after executing START SLAVE UNTIL SQL_*_GTIDS. 00337 */ 00338 bool until_sql_gtids_first_event; 00339 /* 00340 Cached result of comparison of until_log_name and current log name 00341 -2 means unitialised, -1,0,1 are comarison results 00342 */ 00343 enum 00344 { 00345 UNTIL_LOG_NAMES_CMP_UNKNOWN= -2, UNTIL_LOG_NAMES_CMP_LESS= -1, 00346 UNTIL_LOG_NAMES_CMP_EQUAL= 0, UNTIL_LOG_NAMES_CMP_GREATER= 1 00347 } until_log_names_cmp_result; 00348 00349 char cached_charset[6]; 00350 /* 00351 trans_retries varies between 0 to slave_transaction_retries and counts how 00352 many times the slave has retried the present transaction; gets reset to 0 00353 when the transaction finally succeeds. retried_trans is a cumulative 00354 counter: how many times the slave has retried a transaction (any) since 00355 slave started. 00356 */ 00357 ulong trans_retries, retried_trans; 00358 00359 /* 00360 If the end of the hot relay log is made of master's events ignored by the 00361 slave I/O thread, these two keep track of the coords (in the master's 00362 binlog) of the last of these events seen by the slave I/O thread. If not, 00363 ign_master_log_name_end[0] == 0. 00364 As they are like a Rotate event read/written from/to the relay log, they 00365 are both protected by rli->relay_log.LOCK_log. 00366 */ 00367 char ign_master_log_name_end[FN_REFLEN]; 00368 ulonglong ign_master_log_pos_end; 00369 00370 /* 00371 Indentifies where the SQL Thread should create temporary files for the 00372 LOAD DATA INFILE. This is used for security reasons. 00373 */ 00374 char slave_patternload_file[FN_REFLEN]; 00375 size_t slave_patternload_file_size; 00376 00380 struct timespec last_clock; 00381 00387 inline void notify_group_relay_log_name_update() 00388 { 00389 if (until_condition==UNTIL_RELAY_POS) 00390 until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN; 00391 } 00392 00397 inline void notify_group_master_log_name_update() 00398 { 00399 if (until_condition==UNTIL_MASTER_POS) 00400 until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN; 00401 } 00402 00403 inline void inc_event_relay_log_pos() 00404 { 00405 event_relay_log_pos= future_event_relay_log_pos; 00406 } 00407 00408 int inc_group_relay_log_pos(ulonglong log_pos, 00409 bool need_data_lock); 00410 00411 int wait_for_pos(THD* thd, String* log_name, longlong log_pos, 00412 longlong timeout); 00413 int wait_for_gtid_set(THD* thd, String* gtid, longlong timeout); 00414 void close_temporary_tables(); 00415 00416 /* Check if UNTIL condition is satisfied. See slave.cc for more. */ 00417 bool is_until_satisfied(THD *thd, Log_event *ev); 00418 inline ulonglong until_pos() 00419 { 00420 return ((until_condition == UNTIL_MASTER_POS) ? group_master_log_pos : 00421 group_relay_log_pos); 00422 } 00423 00424 RPL_TABLE_LIST *tables_to_lock; /* RBR: Tables to lock */ 00425 uint tables_to_lock_count; /* RBR: Count of tables to lock */ 00426 table_mapping m_table_map; /* RBR: Mapping table-id to table */ 00427 /* RBR: Record Rows_query log event */ 00428 Rows_query_log_event* rows_query_ev; 00429 00430 bool get_table_data(TABLE *table_arg, table_def **tabledef_var, TABLE **conv_table_var) const 00431 { 00432 DBUG_ASSERT(tabledef_var && conv_table_var); 00433 for (TABLE_LIST *ptr= tables_to_lock ; ptr != NULL ; ptr= ptr->next_global) 00434 if (ptr->table == table_arg) 00435 { 00436 *tabledef_var= &static_cast<RPL_TABLE_LIST*>(ptr)->m_tabledef; 00437 *conv_table_var= static_cast<RPL_TABLE_LIST*>(ptr)->m_conv_table; 00438 DBUG_PRINT("debug", ("Fetching table data for table %s.%s:" 00439 " tabledef: %p, conv_table: %p", 00440 table_arg->s->db.str, table_arg->s->table_name.str, 00441 *tabledef_var, *conv_table_var)); 00442 return true; 00443 } 00444 return false; 00445 } 00446 00453 void cached_charset_invalidate(); 00454 bool cached_charset_compare(char *charset) const; 00455 00456 void cleanup_context(THD *, bool); 00457 void slave_close_thread_tables(THD *); 00458 void clear_tables_to_lock(); 00459 int purge_relay_logs(THD *thd, bool just_reset, const char** errmsg); 00460 00461 /* 00462 Used to defer stopping the SQL thread to give it a chance 00463 to finish up the current group of events. 00464 The timestamp is set and reset in @c sql_slave_killed(). 00465 */ 00466 time_t last_event_start_time; 00467 /* 00468 A container to hold on Intvar-, Rand-, Uservar- log-events in case 00469 the slave is configured with table filtering rules. 00470 The withhold events are executed when their parent Query destiny is 00471 determined for execution as well. 00472 */ 00473 Deferred_log_events *deferred_events; 00474 00475 /* 00476 State of the container: true stands for IRU events gathering, 00477 false does for execution, either deferred or direct. 00478 */ 00479 bool deferred_events_collecting; 00480 00481 /***************************************************************************** 00482 WL#5569 MTS 00483 00484 legends: 00485 C - Coordinator; 00486 W - Worker; 00487 WQ - Worker Queue containing event assignments 00488 */ 00489 DYNAMIC_ARRAY workers; // number's is determined by global slave_parallel_workers 00490 volatile ulong pending_jobs; 00491 mysql_mutex_t pending_jobs_lock; 00492 mysql_cond_t pending_jobs_cond; 00493 mysql_mutex_t exit_count_lock; // mutex of worker exit count 00494 ulong mts_slave_worker_queue_len_max; 00495 ulonglong mts_pending_jobs_size; // actual mem usage by WQ:s 00496 ulonglong mts_pending_jobs_size_max; // max of WQ:s size forcing C to wait 00497 bool mts_wq_oversize; // C raises flag to wait some memory's released 00498 Slave_worker *last_assigned_worker;// is set to a Worker at assigning a group 00499 /* 00500 master-binlog ordered queue of Slave_job_group descriptors of groups 00501 that are under processing. The queue size is @c checkpoint_group. 00502 */ 00503 Slave_committed_queue *gaq; 00504 /* 00505 Container for references of involved partitions for the current event group 00506 */ 00507 DYNAMIC_ARRAY curr_group_assigned_parts; 00508 DYNAMIC_ARRAY curr_group_da; // deferred array to hold partition-info-free events 00509 bool curr_group_seen_gtid; // current group started with Gtid-event or not 00510 bool curr_group_seen_begin; // current group started with B-event or not 00511 bool curr_group_isolated; // current group requires execution in isolation 00512 bool mts_end_group_sets_max_dbs; // flag indicates if partitioning info is discovered 00513 volatile ulong mts_wq_underrun_w_id; // Id of a Worker whose queue is getting empty 00514 /* 00515 Ongoing excessive overrun counter to correspond to number of events that 00516 are being scheduled while a WQ is close to be filled up. 00517 `Close' is defined as (100 - mts_worker_underrun_level) %. 00518 The counter is incremented each time a WQ get filled over that level 00519 and decremented when the level drops below. 00520 The counter therefore describes level of saturation that Workers 00521 are experiencing and is used as a parameter to compute a nap time for 00522 Coordinator in order to avoid reaching WQ limits. 00523 */ 00524 volatile long mts_wq_excess_cnt; 00525 long mts_worker_underrun_level; // % of WQ size at which W is considered hungry 00526 ulong mts_coordinator_basic_nap; // C sleeps to avoid WQs overrun 00527 ulong opt_slave_parallel_workers; // cache for ::opt_slave_parallel_workers 00528 ulong slave_parallel_workers; // the one slave session time number of workers 00529 ulong exit_counter; // Number of workers contributed to max updated group index 00530 ulonglong max_updated_index; 00531 ulong recovery_parallel_workers; // number of workers while recovering 00532 uint checkpoint_seqno; // counter of groups executed after the most recent CP 00533 uint checkpoint_group; // cache for ::opt_mts_checkpoint_group 00534 MY_BITMAP recovery_groups; // bitmap used during recovery 00535 bool recovery_groups_inited; 00536 ulong mts_recovery_group_cnt; // number of groups to execute at recovery 00537 ulong mts_recovery_index; // running index of recoverable groups 00538 bool mts_recovery_group_seen_begin; 00539 00540 /* 00541 While distibuting events basing on their properties MTS 00542 Coordinator changes its mts group status. 00543 Transition normally flowws to follow `=>' arrows on the diagram: 00544 00545 +----------------------------+ 00546 V | 00547 MTS_NOT_IN_GROUP => | 00548 {MTS_IN_GROUP => MTS_END_GROUP --+} while (!killed) => MTS_KILLED_GROUP 00549 00550 MTS_END_GROUP has `->' loop breaking link to MTS_NOT_IN_GROUP when 00551 Coordinator synchronizes with Workers by demanding them to 00552 complete their assignments. 00553 */ 00554 enum 00555 { 00556 /* 00557 no new events were scheduled after last synchronization, 00558 includes Single-Threaded-Slave case. 00559 */ 00560 MTS_NOT_IN_GROUP, 00561 00562 MTS_IN_GROUP, /* at least one not-terminal event scheduled to a Worker */ 00563 MTS_END_GROUP, /* the last scheduled event is a terminal event */ 00564 MTS_KILLED_GROUP /* Coordinator gave up to reach MTS_END_GROUP */ 00565 } mts_group_status; 00566 00567 /* 00568 MTS statistics: 00569 */ 00570 ulonglong mts_events_assigned; // number of events (statements) scheduled 00571 ulonglong mts_groups_assigned; // number of groups (transactions) scheduled 00572 volatile ulong mts_wq_overrun_cnt; // counter of all mts_wq_excess_cnt increments 00573 ulong wq_size_waits_cnt; // number of times C slept due to WQ:s oversize 00574 /* 00575 a counter for sleeps due to Coordinator 00576 experienced waiting when Workers get hungry again 00577 */ 00578 ulong mts_wq_no_underrun_cnt; 00579 ulong mts_wq_overfill_cnt; // counter of C waited due to a WQ queue was full 00580 /* 00581 A sorted array of the Workers' current assignement numbers to provide 00582 approximate view on Workers loading. 00583 The first row of the least occupied Worker is queried at assigning 00584 a new partition. Is updated at checkpoint commit to the main RLI. 00585 */ 00586 DYNAMIC_ARRAY least_occupied_workers; 00587 time_t mts_last_online_stat; 00588 /* end of MTS statistics */ 00589 00590 /* most of allocation in the coordinator rli is there */ 00591 void init_workers(ulong); 00592 00593 /* counterpart of the init */ 00594 void deinit_workers(); 00595 00600 inline bool is_mts_recovery() const 00601 { 00602 return mts_recovery_group_cnt != 0; 00603 } 00604 00605 inline void clear_mts_recovery_groups() 00606 { 00607 if (recovery_groups_inited) 00608 { 00609 bitmap_free(&recovery_groups); 00610 mts_recovery_group_cnt= 0; 00611 recovery_groups_inited= false; 00612 } 00613 } 00614 00618 inline bool is_parallel_exec() const 00619 { 00620 bool ret= (slave_parallel_workers > 0) && !is_mts_recovery(); 00621 00622 DBUG_ASSERT(!ret || workers.elements > 0); 00623 00624 return ret; 00625 } 00626 00631 inline bool is_mts_in_group() 00632 { 00633 return is_parallel_exec() && 00634 mts_group_status == MTS_IN_GROUP; 00635 } 00636 00642 void reset_notified_relay_log_change(); 00643 00649 void reset_notified_checkpoint(ulong, time_t, bool); 00650 00655 bool mts_finalize_recovery(); 00656 /* 00657 * End of MTS section ******************************************************/ 00658 00659 /* The general cleanup that slave applier may need at the end of query. */ 00660 inline void cleanup_after_query() 00661 { 00662 if (deferred_events) 00663 deferred_events->rewind(); 00664 }; 00665 /* The general cleanup that slave applier may need at the end of session. */ 00666 void cleanup_after_session() 00667 { 00668 if (deferred_events) 00669 delete deferred_events; 00670 }; 00671 00685 int stmt_done(my_off_t event_log_pos); 00686 00687 00693 void set_flag(enum_state_flag flag) 00694 { 00695 m_flags |= (1UL << flag); 00696 } 00697 00705 bool get_flag(enum_state_flag flag) 00706 { 00707 return m_flags & (1UL << flag); 00708 } 00709 00715 void clear_flag(enum_state_flag flag) 00716 { 00717 m_flags &= ~(1UL << flag); 00718 } 00719 00731 bool is_in_group() const { 00732 return (info_thd->variables.option_bits & OPTION_BEGIN) || 00733 (m_flags & (1UL << IN_STMT)) || 00734 /* If a SET GTID_NEXT was issued we are inside of a group */ 00735 info_thd->owned_gtid.sidno; 00736 } 00737 00738 int count_relay_log_space(); 00739 00740 int rli_init_info(); 00741 void end_info(); 00742 int flush_info(bool force= FALSE); 00743 int flush_current_log(); 00744 void set_master_info(Master_info *info); 00745 00746 inline ulonglong get_future_event_relay_log_pos() { return future_event_relay_log_pos; } 00747 inline void set_future_event_relay_log_pos(ulonglong log_pos) 00748 { 00749 future_event_relay_log_pos= log_pos; 00750 } 00751 00752 inline const char* get_group_master_log_name() { return group_master_log_name; } 00753 inline ulonglong get_group_master_log_pos() { return group_master_log_pos; } 00754 inline void set_group_master_log_name(const char *log_file_name) 00755 { 00756 strmake(group_master_log_name,log_file_name, sizeof(group_master_log_name)-1); 00757 } 00758 inline void set_group_master_log_pos(ulonglong log_pos) 00759 { 00760 group_master_log_pos= log_pos; 00761 } 00762 00763 inline const char* get_group_relay_log_name() { return group_relay_log_name; } 00764 inline ulonglong get_group_relay_log_pos() { return group_relay_log_pos; } 00765 inline void set_group_relay_log_name(const char *log_file_name) 00766 { 00767 strmake(group_relay_log_name,log_file_name, sizeof(group_relay_log_name)-1); 00768 } 00769 inline void set_group_relay_log_name(const char *log_file_name, size_t len) 00770 { 00771 strmake(group_relay_log_name, log_file_name, len); 00772 } 00773 inline void set_group_relay_log_pos(ulonglong log_pos) 00774 { 00775 group_relay_log_pos= log_pos; 00776 } 00777 00778 inline const char* get_event_relay_log_name() { return event_relay_log_name; } 00779 inline ulonglong get_event_relay_log_pos() { return event_relay_log_pos; } 00780 inline void set_event_relay_log_name(const char *log_file_name) 00781 { 00782 strmake(event_relay_log_name,log_file_name, sizeof(event_relay_log_name)-1); 00783 } 00784 inline void set_event_relay_log_name(const char *log_file_name, size_t len) 00785 { 00786 strmake(event_relay_log_name,log_file_name, len); 00787 } 00788 inline void set_event_relay_log_pos(ulonglong log_pos) 00789 { 00790 event_relay_log_pos= log_pos; 00791 } 00792 inline const char* get_rpl_log_name() 00793 { 00794 return (group_master_log_name[0] ? group_master_log_name : "FIRST"); 00795 } 00796 00797 #if MYSQL_VERSION_ID < 40100 00798 inline ulonglong get_future_master_log_pos() { return future_master_log_pos; } 00799 #else 00800 inline ulonglong get_future_group_master_log_pos() { return future_group_master_log_pos; } 00801 inline void set_future_group_master_log_pos(ulonglong log_pos) 00802 { 00803 future_group_master_log_pos= log_pos; 00804 } 00805 #endif 00806 00807 static size_t get_number_info_rli_fields(); 00808 00820 void start_sql_delay(time_t delay_end) 00821 { 00822 mysql_mutex_assert_owner(&data_lock); 00823 sql_delay_end= delay_end; 00824 THD_STAGE_INFO(info_thd, stage_sql_thd_waiting_until_delay); 00825 } 00826 00827 int32 get_sql_delay() { return sql_delay; } 00828 void set_sql_delay(time_t _sql_delay) { sql_delay= _sql_delay; } 00829 time_t get_sql_delay_end() { return sql_delay_end; } 00830 00831 Relay_log_info(bool is_slave_recovery 00832 #ifdef HAVE_PSI_INTERFACE 00833 ,PSI_mutex_key *param_key_info_run_lock, 00834 PSI_mutex_key *param_key_info_data_lock, 00835 PSI_mutex_key *param_key_info_sleep_lock, 00836 PSI_mutex_key *param_key_info_data_cond, 00837 PSI_mutex_key *param_key_info_start_cond, 00838 PSI_mutex_key *param_key_info_stop_cond, 00839 PSI_mutex_key *param_key_info_sleep_cond 00840 #endif 00841 , uint param_id 00842 ); 00843 virtual ~Relay_log_info(); 00844 00845 /* 00846 Determines if a warning message on unsafe execution was 00847 already printed out to avoid clutering the error log 00848 with several warning messages. 00849 */ 00850 bool reported_unsafe_warning; 00851 00852 time_t get_row_stmt_start_timestamp() 00853 { 00854 return row_stmt_start_timestamp; 00855 } 00856 00857 time_t set_row_stmt_start_timestamp() 00858 { 00859 if (row_stmt_start_timestamp == 0) 00860 row_stmt_start_timestamp= my_time(0); 00861 00862 return row_stmt_start_timestamp; 00863 } 00864 00865 void reset_row_stmt_start_timestamp() 00866 { 00867 row_stmt_start_timestamp= 0; 00868 } 00869 00870 void set_long_find_row_note_printed() 00871 { 00872 long_find_row_note_printed= true; 00873 } 00874 00875 void unset_long_find_row_note_printed() 00876 { 00877 long_find_row_note_printed= false; 00878 } 00879 00880 bool is_long_find_row_note_printed() 00881 { 00882 return long_find_row_note_printed; 00883 } 00884 00885 public: 00890 virtual void set_rli_description_event(Format_description_log_event *fdle); 00891 00895 Format_description_log_event *get_rli_description_event() const 00896 { 00897 return rli_description_event; 00898 } 00899 00903 void adapt_to_master_version(Format_description_log_event *fdle); 00904 uchar slave_version_split[3]; // bytes of the slave server version 00905 00906 protected: 00907 Format_description_log_event *rli_description_event; 00908 00909 private: 00910 00922 int sql_delay; 00923 00932 time_t sql_delay_end; 00933 00934 uint32 m_flags; 00935 00936 /* 00937 Before the MASTER_DELAY parameter was added (WL#344), relay_log.info 00938 had 4 lines. Now it has 5 lines. 00939 */ 00940 static const int LINES_IN_RELAY_LOG_INFO_WITH_DELAY= 5; 00941 00942 /* 00943 Before the WL#5599, relay_log.info had 5 lines. Now it has 6 lines. 00944 */ 00945 static const int LINES_IN_RELAY_LOG_INFO_WITH_WORKERS= 6; 00946 00947 /* 00948 Before the Id was added (BUG#2334346), relay_log.info 00949 had 6 lines. Now it has 7 lines. 00950 */ 00951 static const int LINES_IN_RELAY_LOG_INFO_WITH_ID= 7; 00952 00953 bool read_info(Rpl_info_handler *from); 00954 bool write_info(Rpl_info_handler *to); 00955 00956 Relay_log_info(const Relay_log_info& info); 00957 Relay_log_info& operator=(const Relay_log_info& info); 00958 00959 /* 00960 Runtime state for printing a note when slave is taking 00961 too long while processing a row event. 00962 */ 00963 time_t row_stmt_start_timestamp; 00964 bool long_find_row_note_printed; 00965 00966 /* 00967 If on init_info() call error_on_rli_init_info is true that means 00968 that previous call to init_info() terminated with an error, RESET 00969 SLAVE must be executed and the problem fixed manually. 00970 */ 00971 bool error_on_rli_init_info; 00972 }; 00973 00974 bool mysql_show_relaylog_events(THD* thd); 00975 00980 inline bool is_mts_worker(const THD *thd) 00981 { 00982 return thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER; 00983 } 00984 00985 #endif /* RPL_RLI_H */