Skip to main content

mysql binlog获取

· 2 min read

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;
}