Seconds_Behind_MasterFor MySQL master-slave instances, seconds_behind_master is an important parameter to measure the delay between master and slave. The value of seconds_behind_master can be obtained by executing "show slave status;" on the slave. Original implementationDefinition: The number of seconds that the slave SQL thread is behind processing the master binary log. Type: time_t (long) The calculation is as follows: rpl_slave.cc::show_slave_status_send_data() if ((mi->get_master_log_pos() == mi->rli->get_group_master_log_pos()) && (!strcmp(mi->get_master_log_name(), mi->rli->get_group_master_log_name()))) { if (mi->slave_running == MYSQL_SLAVE_RUN_CONNECT) protocol->store(0LL); else protocol->store_null(); } else { long time_diff = ((long)(time(0) - mi->rli->last_master_timestamp) - mi->clock_diff_with_master); protocol->store( (longlong)(mi->rli->last_master_timestamp ? max(0L, time_diff) : 0)); } There are mainly two situations:
last_master_timestampdefinition: The time of the event in the master database binlog. type: time_t (long) Calculation method: The last_master_timestamp is calculated differently depending on whether the standby server is replicated in parallel. Non-parallel replication: rpl_slave.cc:exec_relay_log_event() if ((!rli->is_parallel_exec() || rli->last_master_timestamp == 0) && !(ev->is_artificial_event() || ev->is_relay_log_event() || (ev->common_header->when.tv_sec == 0) || ev->get_type_code() == binary_log::FORMAT_DESCRIPTION_EVENT || ev->server_id == 0)) { rli->last_master_timestamp = ev->common_header->when.tv_sec + (time_t) ev->exec_time; DBUG_ASSERT(rli->last_master_timestamp >= 0); } In this mode, last_master_timestamp indicates the end time of each event, when.tv_sec indicates the start time of the event, and exec_time indicates the execution time of the transaction. This value is calculated before apply_event, so last_master_timestamp has been updated before event is executed. Since exec_time only exists in Query_log_event, last_master_timestamp changes at different event stages of applying a transaction. Take a transaction containing two insert statements as an example. When this code segment is called, the event type, timestamp, and execution time are printed out. create table t1(a int PRIMARY KEY AUTO_INCREMENT ,b longblob) engine=innodb; begin; insert into t1(b) select repeat('a',104857600); insert into t1(b) select repeat('a',104857600); commit;
Parallel replication: rpl_slave.cc mts_checkpoint_routine ts = rli->gaq->empty() ? 0 : reinterpret_cast<Slave_job_group *>(rli->gaq->head_queue())->ts; rli->reset_notified_checkpoint(cnt, ts, true); /* end-of "Coordinator::"commit_positions" */ In this mode, there is a distribution queue gaq on the standby machine. If gaq is empty, last_commit_timestamp is set to 0; if gaq is not empty, a checkpoint point lwm is maintained at this time, and all transactions before lwm are completed on the standby machine. At this time, last_commit_timestamp is updated to the time after the transaction where lwm is located is completed. The time type is time_t type. ptr_group->ts = common_header->when.tv_sec + (time_t)exec_time; // Seconds_behind_master related rli->rli_checkpoint_seqno++; if (update_timestamp) { mysql_mutex_lock(&data_lock); last_master_timestamp = new_ts; mysql_mutex_unlock(&data_lock); } In parallel replication, last_master_timestamp is updated only after event execution is completed, so seconds_behind_master will differ between non-parallel replication and parallel replication. clock_diff_with_masterdefinition:
rpl_slave.cc::get_master_version_and_clock() if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT UNIX_TIMESTAMP()")) && (master_res = mysql_store_result(mysql)) && (master_row = mysql_fetch_row(master_res))) { mysql_mutex_lock(&mi->data_lock); mi->clock_diff_with_master= (long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10)); DBUG_EXECUTE_IF("dbug.mts.force_clock_diff_eq_0", mi->clock_diff_with_master = 0;); mysql_mutex_unlock(&mi->data_lock); } This difference is calculated only once, when the master and slave establish contact. otherexec_timedefinition:
struct timeval end_time; ulonglong micro_end_time = my_micro_time(); my_micro_time_to_timeval(micro_end_time, &end_time); exec_time = end_time.tv_sec - thd_arg->query_start_in_secs(); Time function(1) time_t time(time_t timer) time_t is of long type, and the returned value is accurate only to seconds; (2) int gettimeofday (struct timeval *tv, struct timezone *tz) can obtain the current time in microseconds; (3) timeval structure #include <time.h> stuct timeval { time_t tv_sec; /*seconds*/ suseconds_t tv_usec; /*microseconds*/ } SummarizeUsing seconds_behind_master to measure the master-slave delay can only be accurate to the second level. In some scenarios, seconds_behind_master cannot accurately reflect the delay between the master and the slave. When the master and standby are abnormal, you can combine the seconds_behind_master source code for specific analysis. The above is the detailed explanation of MySQL Seconds_Behind_Master. For more information about MySQL Seconds_Behind_Master, please pay attention to other related articles on 123WORDPRESS.COM! You may also be interested in:
|
<<: Implementation of Grid common layout
>>: Website User Experience Design (UE)
I haven’t updated my blog for several days. I jus...
<br />In the field of network design, resear...
Adobe Brackets is an open source, simple and powe...
Table of contents Create a layout Add CSS styles ...
1. Introduction to nmon Nmon (Nigel's Monitor...
js interesting countdown case, for your reference...
Table of contents Inheritance ES5 prototype inher...
1. Project Structure 2.CallTomcat.java package co...
Preface: position:sticky is a new attribute of CS...
MySQL supports hash and btree indexes. InnoDB and...
Part 1 HTML <html> -- start tag <head>...
Table of contents 1. How the Bootstrap grid syste...
#!/bin/bash #Download SVN yum -y install subversi...
Table of contents style scoped style module State...
The <label> tag defines a label (tag) for an...