slave IO流程之二:注册slave请求和dump请求
2018-06-17 22:57:24来源:未知 阅读 ()
slave IO流程已经在http://www.cnblogs.com/onlyac/p/5815566.html中有介绍
这次我们要探索注册slave请求和dump请求的报文格式和主要流程。
一、注册slave请求
在slave IO连接完数据库后,slave IO接着在主库里注册自己,以便后续不需要提供slave IO登陆的信息如用户名密码等。
1.注册slave请求的报文格式
1 1 [15] COM_REGISTER_SLAVE 2 4 server-id 3 1 slaves hostname length 4 string[$len] slaves hostname 5 1 slaves user len 6 string[$len] slaves user 7 1 slaves password len 8 string[$len] slaves password 9 2 slaves mysql-port 10 4 replication rank 11 4 master-id
(1)报文的类型COM_REGISTER_SLAVE
(2)slave服务器的id,该id唯一并且只能通过my.cnf配置文件改变
(3)slave主机名长度
(4)slave主机名
(5)slave在主库登陆用户名长度
(6)slave在主库登陆用户名
(7)slave在主库登陆的密码长度
(8)slave在主库登陆的密码
(9)slave的mysql端口
(10)(11)这两个都是0,不用去关注
2.在register_slave_on_master中
1 int4store(pos, server_id); pos+= 4; 2 pos= net_store_data(pos, (uchar*) report_host, report_host_len); 3 pos= net_store_data(pos, (uchar*) report_user, report_user_len); 4 pos= net_store_data(pos, (uchar*) report_password, report_password_len); 5 int2store(pos, (uint16) report_port); pos+= 2; 6 /* 7 Fake rpl_recovery_rank, which was removed in BUG#13963, 8 so that this server can register itself on old servers, 9 see BUG#49259. 10 */ 11 int4store(pos, /* rpl_recovery_rank */ 0); pos+= 4; 12 /* The master will fill in master_id */ 13 int4store(pos, 0); pos+= 4;
这是除了第一个没有的在1中的报文格式,然后通过simple_command发送出去。
1 #define simple_command(mysql, command, arg, length, skip_check) \ 2 ((mysql)->methods \ 3 ? (*(mysql)->methods->advanced_command)(mysql, command, 0, \ 4 0, arg, length, skip_check, NULL) \ 5 : (set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate), 1))
该函数指向cli_advanced_command。
(1)在li_advanced_command中
在通过函数net_write_command写该报文
1 if (net_write_command(net,(uchar) command, header, header_length, 2 arg, arg_length)) 3 { 4 DBUG_PRINT("error",("Can't send command to server. Error: %d", 5 socket_errno)); 6 if (net->last_errno == ER_NET_PACKET_TOO_LARGE) 7 { 8 set_mysql_error(mysql, CR_NET_PACKET_TOO_LARGE, unknown_sqlstate); 9 goto end; 10 } 11 end_server(mysql); 12 if (mysql_reconnect(mysql) || stmt_skip) 13 goto end; 14 15 MYSQL_TRACE(SEND_COMMAND, mysql, (command, header_length, arg_length, header, arg)); 16 if (net_write_command(net,(uchar) command, header, header_length, 17 arg, arg_length)) 18 { 19 set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate); 20 goto end; 21 } 22 }
(2)在net_write_command中
1 buff[4]=command; /* For first packet */
这个写了该报文的类型,
1 if (length >= MAX_PACKET_LENGTH) 2 { 3 /* Take into account that we have the command in the first header */ 4 len= MAX_PACKET_LENGTH - 1 - head_len; 5 do 6 { 7 int3store(buff, MAX_PACKET_LENGTH); 8 buff[3]= (uchar) net->pkt_nr++; 9 if (net_write_buff(net, buff, header_size) || 10 net_write_buff(net, header, head_len) || 11 net_write_buff(net, packet, len)) 12 { 13 MYSQL_NET_WRITE_DONE(1); 14 DBUG_RETURN(1); 15 } 16 packet+= len; 17 length-= MAX_PACKET_LENGTH; 18 len= MAX_PACKET_LENGTH; 19 head_len= 0; 20 header_size= NET_HEADER_SIZE; 21 } while (length >= MAX_PACKET_LENGTH); 22 len=length; /* Data left to be written */ 23 } 24 int3store(buff, static_cast<uint>(length)); 25 buff[3]= (uchar) net->pkt_nr++; 26 rc= MY_TEST(net_write_buff(net, buff, header_size) || 27 (head_len && net_write_buff(net, header, head_len)) || 28 net_write_buff(net, packet, len) || net_flush(net));
这所以这样写是因为每个报文有个这样头
1 if (!skip_check) 2 { 3 result= ((mysql->packet_length= cli_safe_read_with_ok(mysql, 1, NULL)) == 4 packet_error ? 1 : 0);
(3)mysql协议的公共报文头部
每个报文都有一个这样的头,这是忘记在上一章讲的
第一个是这个报文的长度(以字节为单位),第二个是这个报文的系列号,当然发送的内容原来就是一个报文,但是太长分成多个,第三个就是报文本身
对于超过16M的报文会这样发送
二、dump请求
1.dump请求的报文格式
dump有两种格式:COM_BINLOG_DUMP_GTID和COM_BINLOG_DUMP
在slave IO的情形下,一般会使用COM_BINLOG_DUMP
为此,在此仅仅介绍COM_BINLOG_DUMP的格式
1 1 [12] COM_BINLOG_DUMP 2 4 binlog-pos 3 2 flags 4 4 server-id 5 string[EOF] binlog-filename
(1)报文的类型COM_BINLOG_DUMP
(2)请求binlog的写的位置
(3)一般为COM_BINLOG_DUMP_NO_BLOCK类型
(4)slave IO的所在服务器的服务器编号,和slave注册协议中的那个一致
(5)当前需要读的binlog文件名
2.在函数request_dump中
1 int4store(ptr_buffer, DBUG_EVALUATE_IF("request_master_log_pos_3", 3, 2 static_cast<uint32>(mi->get_master_log_pos()))); 3 ptr_buffer+= ::BINLOG_POS_OLD_INFO_SIZE; 4 // See comment regarding binlog_flags above. 5 int2store(ptr_buffer, binlog_flags); 6 ptr_buffer+= ::BINLOG_FLAGS_INFO_SIZE; 7 int4store(ptr_buffer, server_id); 8 ptr_buffer+= ::BINLOG_SERVER_ID_INFO_SIZE; 9 memcpy(ptr_buffer, mi->get_master_log_name(), BINLOG_NAME_INFO_SIZE); 10 ptr_buffer+= BINLOG_NAME_INFO_SIZE; 11 12 command_size= ptr_buffer - command_buffer; 13 DBUG_ASSERT(command_size == (allocation_size - 1));
同样地是COM_BINLOG_DUMP的格式。
这边也使用simple_command(mysql, command, command_buffer, command_size, 1)写入。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- PHP实现微信申请退款流程与实例,你会了嘛 2019-08-31
- 数据库读写分离Master-Slave 2019-07-24
- MySQL基础之二:主从复制 2019-07-24
- linux 启动流程分析! 2019-07-24
- linux 启动流程分析 2019-07-24
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash