MySQL:主从报错中的位点解析


老是遇到类似的问题,不胜其烦啊。就随便看了看,记录如下,仅供参考。


问题展示和位点分析

报错信息如下:

Last_IO_Error: Got fatal error 1236 from master when reading data from binary log
'bogus data in log event; the first event '' at 4, the last event read from '/opt/bin/log_bin.000009
at 935, the last byte read from '
/opt/bin/log_bin.000009' at 954.'

因为多次遇到这种错误,对于几个报错中提到的position不是很熟悉,稍微翻了一下,本错误来自函数Binlog_sender::log_read_error_msg,其由Binlog_sender::read_event调入,也就是dump线程读取event的时候,其中8.0有如下定义:

  • Binlog_read_error::BOGUS "bogus data in log event";
  • Binlog_read_error::EVENT_TOO_LARGE "log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master";
  • Binlog_read_error::MEM_ALLOCATE "memory allocation failed reading log event";
  • Binlog_read_error::TRUNC_EVENT "binlog truncated in the middle of event; consider out of disk space on master";
  • Binlog_read_error::CHECKSUM_FAILURE event read from binlog did not pass crc check";

也就是这错误是DUMP线程抛出来的。很多都是自解释的,但是我们遇到的是bogus data in log event,貌似不太好直接解释,稍微看看其代表的是dump线程读取的event header中的event 的长度小于的最小长度,这不可能。而我们遇到的时候是做了主库的binlog清理,而DUMP线程可能还在读取event。那么几个position是什么意思呢?稍微看了一下总结如下,实际上就是:

snprintf(error_text, sizeof(error_text),
         "%s; the first event '%s' at %lld, "
         "the last event read from '%s' at %lld, "
         "the last byte read from '%s' at %lld.",
         m_errmsg, m_start_file, m_start_pos, m_last_file, m_last_pos,
         log_file, reader.position());

  • the first event '%s' at %lld 为 m_start_file, m_start_pos

为DUMP线程启动时候读取的position,对于auto_position这个值应该是空,因为auto_position传给dump线程的就是空position,其定位依赖的是GTID。而对于传统的当然就是传过来的是需要读取的position。正常运行情况下可以直接输出一下这两个值,下面是auto_position的值。

(gdb) p m_start_pos
$8 = 4
(gdb) p m_start_file
$9 = 0x7fff9f2111e0 ""
(gdb) 

  • the last event read from '%s' at %lld 为m_start_pos, m_last_file

为dump线程最后一次无故障读取的event的位置,因为读取的时候要进行错误判断,如果报错了就不计入这个位置了,所谓的故障就是我们前面提到的这些故障。

  • the last byte read from '%s' at %lld. 为log_file, reader.position()

为dump线程最后一次读取的event位置,如果读取没有问题才会计入上面的指标,是不同的,但是一定大于上面的值。

后面两个位点就2行代码就解释了如下:

  if ((error= Log_event::read_log_event(log_cache, &m_packet, m_fdle.get(), NULL, checksum_alg,
                                        NULL, NULL, header))) //读取
    goto read_error;//如果报错走error逻辑

  set_last_pos(my_b_tell(log_cache));//否则记录m_start_pos,和m_last_file  

  void set_last_pos(my_off_t log_pos)
  {
    m_last_file= m_linfo.log_file_name;
    m_last_pos= log_pos;
  }

附录:报错栈

这里用的5.7的栈如下:

com_binlog_dump_gtid
 ->mysql_binlog_send
   ->Binlog_sender::run
     ->Binlog_sender::send_binlog
       ->Binlog_sender::send_events
         ->Binlog_sender::read_event
           ->Binlog_sender::log_read_error_msg




免责声明:

1、本站资源由自动抓取工具收集整理于网络。

2、本站不承担由于内容的合法性及真实性所引起的一切争议和法律责任。

3、电子书、小说等仅供网友预览使用,书籍版权归作者或出版社所有。

4、如作者、出版社认为资源涉及侵权,请联系本站,本站将在收到通知书后尽快删除您认为侵权的作品。

5、如果您喜欢本资源,请您支持作者,购买正版内容。

6、资源失效,请下方留言,欢迎分享资源链接

文章评论

0条评论