Skip to content

mysql binlog获取

Posted on:May 11, 2021 at 12:44 PM

mysql 报文:

mysql报文分为两部分:headerpayload

有四个字节,其中前三个字节是标识这个包的长度描述payload的长度,也就是payload最长的长度为2^24-1字节,最后一个字节则是类似于tcp的序列号,每次从0开始递增,描述的是第几个包

payload

payload则是具体负载

mysql握手

tcp三次握手之后,整个传输层的连接已经建立了,那么怎么登陆呢? 握手文档 加密的方式 举个例子:加密套件是mysql_native_password,那么第一个包会是由 server发出,附带20字节的随机码, 然后在客户端的用户提交的密码做多次sha1哈希然后回传给mysql

binlog获取分为两步:

1: COM_REGISTER_SLAVE 把slave注册到master里面 2: COM_BINLOG_DUMP 这个包主要是告诉master锁需要的binlog的名字和位点,然后就会返回一堆binlog事件给客户端

mysql 发送binlog流程

int Binlog_sender::get_binlog_end_pos(File_reader *reader, my_off_t *end_pos) {
  DBUG_TRACE;
  my_off_t read_pos = reader->position();

  do {
    /*
      MYSQL_BIN_LOG::binlog_end_pos is atomic. We should only acquire the
      LOCK_binlog_end_pos if we reached the end of the hot log and are going
      to wait for updates on the binary log (Binlog_sender::wait_new_event()).
    */
    *end_pos = mysql_bin_log.get_binlog_end_pos();

    /* If this is a cold binlog file, we are done getting the end pos */
    if (unlikely(!mysql_bin_log.is_active(m_linfo.log_file_name))) {
      *end_pos = 0;
      return 0;
    }

    DBUG_PRINT("info", ("Reading file %s, seek pos %llu, end_pos is %llu",
                        m_linfo.log_file_name, read_pos, *end_pos));
    DBUG_PRINT("info", ("Active file is %s", mysql_bin_log.get_log_fname()));

    if (read_pos < *end_pos) return 0;

    /* Some data may be in net buffer, it should be flushed before waiting */
    if (!m_wait_new_events || flush_net()) return 1;

    if (unlikely(wait_new_events(read_pos))) return 1;
  } while (unlikely(!m_thd->killed));

  return 1;
}