VIP漂移,IO线程断连 注意事项

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 考虑一个问题如下: A----B \ / VIP | C这种构架A B 切换了,如果VIP漂移了,C从库是否有问题。结论就是POS一定不行,GTID却一定可以。证明如下:《深入理解MySQL主从原理 32讲》中的17和22节详细描述了下文提到的IO和DUMP线程流程,有兴趣可以关注一下:IO thread如果遇到主库IP断开操作会进入重连流程。

考虑一个问题如下:

 
A----B
 \  /
 VIP
  | 
  C

这种构架A B 切换了,如果VIP漂移了,C从库是否有问题。结论就是POS一定不行,GTID却一定可以。证明如下:


《深入理解MySQL主从原理 32讲》中的17和22节详细描述了下文提到的IO和DUMP线程流程,有兴趣可以关注一下:
image.png

IO thread如果遇到主库IP断开操作会进入重连流程。这个过程触发如下逻辑

event_len= read_event(mysql, mi, &suppress_warnings); //返回读取的长度

event_len中返回错误码,如下:

if (event_len == packet_error)
      {
        uint mysql_error_number= mysql_errno(mysql);
        switch (mysql_error_number) {
        case CR_NET_PACKET_TOO_LARGE:
          sql_print_error("\
Log entry on master is longer than slave_max_allowed_packet (%lu) on \
slave. If the entry is correct, restart the server with a higher value of \
slave_max_allowed_packet",
                         slave_max_allowed_packet);
          mi->report(ERROR_LEVEL, ER_NET_PACKET_TOO_LARGE,
                     "%s", "Got a packet bigger than 'slave_max_allowed_packet' bytes");
          goto err;
        case ER_MASTER_FATAL_ERROR_READING_BINLOG:
          mi->report(ERROR_LEVEL, ER_MASTER_FATAL_ERROR_READING_BINLOG,
                     ER(ER_MASTER_FATAL_ERROR_READING_BINLOG),
                     mysql_error_number, mysql_error(mysql));
          goto err;
        case ER_OUT_OF_RESOURCES:
          sql_print_error("\
Stopping slave I/O thread due to out-of-memory error from master");
          mi->report(ERROR_LEVEL, ER_OUT_OF_RESOURCES,
                     "%s", ER(ER_OUT_OF_RESOURCES));
          goto err;
        }
        if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
                             reconnect_messages[SLAVE_RECON_ACT_EVENT]))
          goto err;
        goto connected;
      } 

上面的有些错误是不能重连的自行参考,如果重新连接成功,将会进入goto connected;

这里会重新走一遍连接流程,最重要的是GTID和POSTION 会进入DUMP线程定位流程,也就是GTID
会重新搜索主库的mysql binlog 和 GTID 进行定位。

因此我们可以确认类似下面

 
A----B
 \  /
 VIP
  | 
  C

这种构架当VIP切换完成后,主要保证A B无损切换,那么C是没有问题的,但是POSTION却不行,因为A库的位点和B点的位点不一定完全一致。这一点是需要注意的。

证明很简单,我只需要将主库IP先关闭然后过一会起来即可。日志如下:

2019-08-06T21:30:29.723923+08:00 4 [ERROR] Slave I/O for channel '': error reconnecting to master 'repl@192.168.99.101:3340' - retry-time: 60  retries: 1, Error_code: 2
003

我们设置断点如下。

从库设置在request_dump函数上,触发如下:

(gdb) bt
#0  request_dump (thd=0x7ffe800009a0, mysql=0x7ffe8000e670, mi=0x7ffe7c0223b0, suppress_warnings=0x7fffec0c5d8b)
    at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/rpl_slave.cc:4363
#1  0x00000000018beee1 in handle_slave_io (arg=0x7ffe7c0223b0) at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/rpl_slave.cc:5768
#2  0x0000000001945620 in pfs_spawn_thread (arg=0x7ffe7c033f90) at /root/mysqlall/percona-server-locks-detail-5.7.22/storage/perfschema/pfs.cc:2190
#3  0x00007ffff7bc6aa1 in start_thread () from /lib64/libpthread.so.0
#4  0x00007ffff6719bcd in clone () from /lib64/libc.so.6

主库设置在com_binlog_dump_gtid上

(gdb) bt
#0  com_binlog_dump_gtid (thd=0x7fffe800edc0, packet=0x7fffe80068c1 "", packet_length=43) at /mysqldata/percona-server-locks-detail-5.7.22/sql/rpl_master.cc:356
#1  0x00000000015c769b in dispatch_command (thd=0x7fffe800edc0, com_data=0x7fffec58bd70, command=COM_BINLOG_DUMP_GTID)
    at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1705
#2  0x00000000015c58ff in do_command (thd=0x7fffe800edc0) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1021
#3  0x000000000170e578 in handle_connection (arg=0x6660220) at /mysqldata/percona-server-locks-detail-5.7.22/sql/conn_handler/connection_handler_per_thread.cc:312
#4  0x0000000001945538 in pfs_spawn_thread (arg=0x665f200) at /mysqldata/percona-server-locks-detail-5.7.22/storage/perfschema/pfs.cc:2190
#5  0x00007ffff7bcfaa1 in start_thread () from /lib64/libpthread.so.0
#6  0x00007ffff6b37c4d in clone () from /lib64/libc.so.6

因此这里主要证明的就是,即便是IO线程重连主库GTID定位操作依然会重新跑一次。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
算法 数据处理 Python
Python并发编程:解密异步IO与多线程
本文将深入探讨Python中的并发编程技术,重点介绍异步IO和多线程两种常见的并发模型。通过对比它们的特点、适用场景和实现方式,帮助读者更好地理解并发编程的核心概念,并掌握在不同场景下选择合适的并发模型的方法。
|
负载均衡 NoSQL Java
redis中的io多线程(线程池)
redis中的io多线程(线程池)
591 0
|
负载均衡 NoSQL Java
|
6月前
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
243 23
|
11月前
|
Java Linux
【网络】高并发场景处理:线程池和IO多路复用
【网络】高并发场景处理:线程池和IO多路复用
282 2
WXM
|
存储 缓存 算法
IO/线程的零拷贝
服务器在提供文件传输功能时,传统实现方式是通过读取磁盘文件内容,将其加载到用户空间的缓冲区,再通过网络 API 发送至客户端,这个过程涉及多次上下文切换和内存拷贝,导致性能下降。
WXM
151 12
|
数据采集 算法 数据处理
Python并发编程:异步IO与多线程的比较与应用
本文探讨了Python中异步IO和多线程两种并发编程模型的优劣及其在实际应用中的适用性。通过比较它们在性能、资源消耗和代码复杂度等方面的差异,分析了不同场景下选择合适的并发模型的策略和方法。
|
Python
并发编程,Python让你轻松驾驭多线程与异步IO!
【6月更文挑战第12天】本文探讨了Python中的并发编程,包括多线程和异步IO。通过`threading`模块展示了多线程编程,创建并运行多个线程以并发执行任务。同时,使用`asyncio`库演示了异步IO编程,允许在单线程中高效处理多个IO操作。两个示例代码详细解释了如何在Python中实现并发,展现了其在提升程序性能和响应速度方面的潜力。
117 3
|
数据采集 算法 数据处理
Python中的并发编程:异步IO与多线程对比分析
传统的多线程编程在Python中因为全局解释器锁(GIL)的存在受到限制,导致多线程并不能充分利用多核处理器的优势。本文将探讨Python中的异步IO编程与多线程编程的差异与优劣,并分析适合的应用场景。
|
并行计算 数据处理 开发者
Python并发编程:解析异步IO与多线程
本文探讨了Python中的并发编程技术,着重比较了异步IO和多线程两种常见的并发模型。通过详细分析它们的特点、优劣势以及适用场景,帮助读者更好地理解并选择适合自己项目需求的并发编程方式。