MySQL主从延迟现象及原理分析详解

一、现象

凌晨对线上一张表添加索引,表数据量太大(1亿+数据,数据量50G以上),造成主从延迟几个小时,各个依赖从库的系统无法查询数据,最终影响业务。

现在就梳理下主从延迟的原理。

二、原理

根据 MySQL 官方文档 MySQL Replication Implementation Details 中的描述,MySQL 主从复制依赖于三个线程:master一个线程(Binlog dump thread),slave两个线程(I/O threadSQL thread)。主从复制流程如下图:

master 服务器和 slave 服务器连接时,创建Binlog dump thread以发送bin log数据:

  • 一个Binlog dump thread对应一个 slave 服务器;
  • Binlog dump threadbin log获取数据时会加锁,获取到数据后,立即释放锁。

当 slave 服务器收到 START_SLAVE 命令时,会创建I/O threadSQL thread

  • I/O thread以拉的方式,从 master 读取事件,并存储到 slave 服务器的relay log中;
  • SQL threadrelay log中读取事件并执行;
  • slave可以按照自己的节奏读取和更新数据,也可以随意操作复制进程(启动和停止)。

注: START_SLAVE命令成功启动线程后,如果后面I/O threadSQL thread因为某些原因停止,则不会有任何的警告,业务方无法感知。可以通过查看 slave 的 error 日志,或者通过 SHOW SLAVE STATUS 查看 slave 上的线程状态。

通过 SHOW PROCESSLIST 可查看线程状态:

Binlog dump thread:

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
  Id: 2
 User: root
 Host: localhost:32931
  db: NULL
Command: Binlog Dump
 Time: 94
 State: Has sent all binlog to slave; waiting for binlog to
   be updated
 Info: NULL

I/O thread 和 SQL thread:

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
  Id: 10
 User: system user
 Host:
  db: NULL
Command: Connect
 Time: 11
 State: Waiting for master to send event
 Info: NULL
 *************************** 2. row ***************************
  Id: 11
 User: system user
 Host:
  db: NULL
Command: Connect
 Time: 11
 State: Has read all relay log; waiting for the slave I/O
   thread to update it
 Info: NULL

三、分析

根据上面的原理,由于slave是单线程(I/O thread)读取数据,单线程(SQL thread)更新数据,而master是多线程写入,那么只要master写入的频率大于slave读取更新的频率,就有可能出现主从延迟的情况,如:

  1. master写入tps较高,大于slave更新速度;
  2. slave执行某些语句耗时较长,如持有锁等;
  3. master执行某些DDL语句时,执行的时间较长,在slave也执行相同的时间;

此处创建了索引,咨询 DBA,产生的bin log文件有100多G,数据量太大,导致从库I/O thread一直读取DDL操作产生的bin log事件,而影响到正常的业务DML事件的更新,从而表现为主从同步延迟。

四、解决方案

从主从延迟的原因来看,解决方案可以从以下几个方向入手:

  1. 业务选型,对于无法忍受从库延迟的架构,可选择分布式架构等,避开从库延迟问题
  2. 执行时间,对大表进行线上DDL操作尽量选择凌晨等业务量较小的时候
  3. 硬件配置,升级从库硬件配置,如SSD
  4. 减少请求,增加缓存层,减少读请求落库

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • MySQL limit性能分析与优化

    一.结论 语法结构: limit offset, rows 结论:rows 相同条件下,offset 值越大,limit 语句性能越差 二.测试 执行测试: 5750000 条数据 sql 1 执行时间: sql 6执行时间: 三.优化 方式一:可根据主键ID等其他索引字段定位到数据位置,然后使用 limit 0, rows 如: select * from gift_record_0 where id >= 43611207 limit 1000 0.14 s 方式二(根据业务需求):针对不需

  • PHP实现PDO操作mysql存储过程示例

    本文实例讲述了PHP实现PDO操作mysql存储过程.分享给大家供大家参考,具体如下: 一 代码 sql语句: create procedure pro_reg (in nc varchar(80), in pwd varchar(80), in email varchar(80),in address varchar(50)) begin insert into tb_reg (name, pwd ,email ,address) values (nc, pwd, email, address

  • 实例讲解MySQL中乐观锁和悲观锁

    数据库管理系统中并发控制的任务是确保在多个事务同时存取数据库中同一数据不破坏事务的隔离性和统一性以及数据库的统一性 乐观锁和悲观锁式并发控制主要采用的技术手段 悲观锁 在关系数据库管理系统中,悲观并发控制(悲观锁,PCC)是一种并发控制的方法.它可以阻止一个事务以影响其他用户的方式来修改数据.如果一个事务执行的操作的每行数据应用了锁,那只有当这个事务锁释放,其他事务才能够执行与该锁冲突的操作 悲观并发控制主要应用于数据争用激烈的环境,以及发生并发冲突时使用锁保护数据的成本要低于回滚事务的成本环境

  • GDB调试Mysql实战之源码编译安装

    下载源码 git clone https://github.com/mysql/mysql-server.git cd mysql-server git checkout 5.7 编译安装 安装依赖 yum install -y cmake make gcc gcc-c++ ncurses-devel bison gdb 需要注意的一点,需要指定 boost 路径,会 cmake 的时候自动下载 cd BUILD; cmake .. -DDOWNLOAD_BOOST=1 -DWITH_BOOST

  • Mysql主从复制注意事项的讲解

    一.报错error connecting to master 'x@x.x.x.x:x' - retry-time: 60  retries: 86400 今天搭建mysql主从复制,一直报这个错.我是在一台虚拟机上使用多实例创建的2个不同端口的数据库,查了很久,才解决. 1.检查主从复制的用户名密码: 2.检查MASTER_LOG_FILE和MASTER_LOG_POS. 记住配置从库的命令,这些参数都要参考主库的配置: mysql> CHANGE MASTER TO MASTER_HOST=

  • MySQL中int最大值深入讲解

    导语 前两天看到的问题,展开写一下. 字节 我们都知道计算机是以二进制为基础.存储的基本单位是 Bit,也称为比特.二进制位.1bit 可以表示 0 或者 1 两个数字,是可能存在的最小的信息量,任何小于1 bit 的内容都算不上信息. 复杂的内容就要用多 bit 来表示.Byte ,也称为字节,通常用作计量单位.1 byte 等于 8 bit,即 1 byte 可以表示 28 内容. MySQL 中的字节 先说明一下,在 MySQL 中的整数类型,可以分为 unsigned 和 signed

  • MySQL和Redis实现二级缓存的方法详解

    redis简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用 Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储 Redis支持数据的备份,即master-slave模式的数据备份 优势 性能极高 - Redis能读的速度是110

  • MySQL普通索引和唯一索引的深入讲解

    场景 1.维护一个市民系统,有一个字段为身份证号 2.业务代码能保证不会写入两个重复的身份证号(如果业务无法保证,可以依赖数据库的唯一索引来进行约束) 3.常用SQL查询语句:SELECT name FROM CUser WHERE id_card = 'XXX' 4.建立索引 身份证号比较大,不建议设置为主键 从性能角度出发,选择普通索引还是唯一索引? 假设字段k上的值都不重复 查询过程 1.查询语句:SELECT id FROM T WHERE k=5 2.查询过程 通过B+树从树根开始,按

  • Docker创建MySQL的讲解

    1.下载MySQL Image 命令: docker pull mysql 2.创建容器 命令样例: sudo docker run -p 3306:3306 --name mysql -v $PWD/conf:/etc/mysql/conf.d -v $PWD/logs:/logs -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql 命令说明: 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具

  • Mysql主键和唯一键的区别点总结

    什么是主键? 主键是表中唯一标识该表中每个元组(行)的列.主键对表实施完整性约束.表中只允许使用一个主键.主键不接受任何重复值和空值.表中的主键值很少更改,因此在选择主键是需要小心,要选择很少发生更改的地方.一个表的主键可以被另一个表的外键引用. 为了更好地理解主键,我们创建一个名为Student的表,它具有roll_number.name.batch.phone_number.citizen_id等属性. 在上面的示例中,roll_number属性永远不能具有相同的NULL值,因为在每个大学中

随机推荐