zoukankan      html  css  js  c++  java
  • slave IO流程之二:注册slave请求和dump请求

    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
    View Code

    (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;
    View Code

    这是除了第一个没有的在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))
    View Code

    该函数指向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   }
    View Code

    (2)在net_write_command中

    1   buff[4]=command;                /* For first packet */
    View Code

    这个写了该报文的类型,

     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));
    View Code

    这所以这样写是因为每个报文有个这样头

    1  if (!skip_check)
    2   {
    3     result= ((mysql->packet_length= cli_safe_read_with_ok(mysql, 1, NULL)) ==
    4              packet_error ? 1 : 0);
    View Code

    (3)mysql协议的公共报文头部

    每个报文都有一个这样的头,这是忘记在上一章讲的

    View Code

    第一个是这个报文的长度(以字节为单位),第二个是这个报文的系列号,当然发送的内容原来就是一个报文,但是太长分成多个,第三个就是报文本身

    对于超过16M的报文会这样发送

    View Code

     二、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
    View Code

    (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));
    View Code

    同样地是COM_BINLOG_DUMP的格式。

    这边也使用simple_command(mysql, command, command_buffer, command_size, 1)写入。

  • 相关阅读:
    人脸识别常用的性能评价指标
    【计算机视觉】seetaFace
    【error】'isnan' was not declared in this scope
    【opencv基础】图像的几何变换
    [c++]base64编解码 and image
    【leetcode】232-Implement Queue using Stacks
    【leetcode】231-power-of-two
    C++中vector容器的常用操作方法实例总结
    【leetcode】226-invert-binary-tree
    第3章 文件I/O(2)_文件I/O系统调用及文件描述符
  • 原文地址:https://www.cnblogs.com/onlyac/p/5817727.html
Copyright © 2011-2022 走看看