Let's first look at what happens to a slave registration to master, first slave need to send a Com_register_slave type request (sql_parse.cc) command to master, where master will use Register_ The slave function registers a slave to slave_list.
The code is as follows |
Copy Code |
Case Com_register_slave: { if (!register_slave (THD, (uchar*) packet, packet_length)) MY_OK (THD); Break } |
What happens when you register a slave thread? We omit the useless code to see the focus directly: (repl_failsafe.cc)
code is as follows |
copy code |
int Register_slave (thd* THD, uchar* packet, uint packet_length) { int res; Slave_info *si; Uchar *p= packet, *p_end= packet + packet_length; ....//omitted if (! Si->master_id= Uint4korr (P)) si->master_id= server_id; si->thd= THD; & nbsp Pthread_mutex_lock (&lock_slave_list); Unregister_slave (thd,0,0);//Key here, first unregister server_id the same slave thread res= My_hash_insert (&slave_ List, (uchar*) SI); Register the new Slave thread with the slave_list Pthread_mutex_unlock (&lock_slave_list); return res; ... } |
What do you mean by that? This is the mechanism, slave_list is a hash table, server_id is a key, each thread to register, you need to delete the same server_id slave thread, and then add a new slave thread to the Slave_list table.
After the thread registers, requests Binlog, sends the COM_BINLOG_DUMP request, the master sends the Binlog to slave, the code is as follows:
The code is as follows |
Copy Code |
Case Com_binlog_dump: { ULONG POS; USHORT Flags; UInt32 slave_server_id; Status_var_increment (Thd->status_var.com_other); Thd->enable_slow_log= opt_log_slow_admin_statements; if (Check_global_access (THD, Repl_slave_acl)) Break /* todo:the following has to is changed to a 8 byte integer */ & nbsp; pos = Uint4korr (packet); flags = Uint2korr (packet + 4); thd->server_id=0;/* Avoid suicide */ if ( Slave_server_id= Uint4korr (PACKET+6))//mysqlbinlog.server_id==0 Kill_zombie_dump_threads (slave_server_id); thd->server_id = slave_server_id; General_log_print (THD, command, "log: '%s ' Pos:%ld", packet+10, (long) POS); Mysql_binlog_send (THD, thd->strdup (packet +), (my_off_t) POS, flags); Keep sending logs to the slave end Unregister_slave (thd,1,1); Clean the slave thread after the send is complete, because the Binlog dump thread must be killed to perform this step /* Fake Com_quit--if we get this, the thread needs to terminate * * Error = TRUE; Break } |
The Mysql_binlog_send function is in sql_repl.cc, which is polling master Binlog and sending it to slave.
Let's take a quick look at what Unregister_slave did (repl_failsafe.cc):
The code is as follows |
Copy Code |
void Unregister_slave (thd* THD, bool only_mine, BOOL Need_mutex) { if (thd->server_id) { if (Need_mutex) Pthread_mutex_lock (&lock_slave_list); slave_info* Old_si; if (Old_si = (slave_info*) hash_search (&slave_list, (uchar*) &thd->server_id, 4) && (!only_mine | | old_si->thd = = THD)) Get the slave value. Hash_delete (&slave_list, (uchar*) old_si); Take it off the slave_list. if (Need_mutex) Pthread_mutex_unlock (&lock_slave_list); } } |
This explains why the same server_id is killed because once registered, the same server_id slave thread is deleted and the current slave is added, because sometimes the slave is disconnected, the request comes up again, of course, the original thread needs to be kicked off. This is the line Chenghong connection mechanism.