前言

最近公司某项目上反馈mysql主从复制失败,被运维部门记了一次大过,影响到了项目的验收推进,那么究竟是什么原因导致的呢?而主从复制的原理又是什么呢?本文就对排查分析的过程做一个记录。

主从复制原理

我们先来简单了解下MySQL主从复制的原理。

  1. 主库master 服务器会将 SQL 记录通过 dump 线程写入到 二进制日志binary log 中;
  2. 从库slave 服务器开启一个 io thread 线程向服务器发送请求,向 主库master 请求 binary log。主库master 服务器在接收到请求之后,根据偏移量将新的 binary log 发送给 slave 服务器。
  3. 从库slave 服务器收到新的 binary log 之后,写入到自身的 relay log 中,这就是所谓的中继日志。
  4. 从库slave 服务器,单独开启一个 sql thread 读取 relay log 之后,写入到自身数据中,从而保证主从的数据一致。

以上是MySQL主从复制的简要原理,更多细节不展开讨论了,根据运维反馈,主从复制失败主要在IO线程获取二进制日志bin log超时,一看主数据库的binlog日志竟达到了4个G,正常情况下根据配置应该是不超过300M。

binlog写入机制

想要了解binlog为什么达到4个G,我们来看下binlog的写入机制。

binlog的写入时机也非常简单,事务执行过程中,先把日志写到 binlog cache ,事务提交的时候,再把binlog cache写到binlog文件中。因为一个事务的binlog不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一个块内存作为binlog cache

  1. 上图的write,是指把日志写入到文件系统的page cache,并没有把数据持久化到磁盘,所以速度比较快
  2. 上图的fsync,才是将数据持久化到磁盘的操作, 生成binlog日志中

生产上MySQL中binlog中的配置max_binlog_size为250M, 而max_binlog_size是用来控制单个二进制日志大小,当前日志文件大小超过此变量时,执行切换动作。,该设置并不能严格控制Binlog的大小,尤其是binlog比较靠近最大值而又遇到一个比较大事务时,为了保证事务的完整性,可能不做切换日志的动作,只能将该事务的所有$QL都记录进当前日志,直到事务结束。一般情况下可采取默认值。

所以说怀疑是不是遇到了大事务,因而我们需要看看binlog中的内容具体是哪个事务导致的。

查看binlog日志

我们可以使用mysqlbinlog这个工具来查看下binlog中的内容,具体用法参考官网:https://dev.mysql.com/doc/refman/8.0/en/mysqlbinlog.html

  1. 查看binlog日志
./mysqlbinlog --no-defaults --base64-output=decode-rows -vv /mysqldata/mysql/binlog/mysql-bin.004816|more
  1. 以事务为单位统计binlog日志文件中占用的字节大小
./mysqlbinlog --no-defaults --base64-output=decode-rows -vv /mysqldata/mysql/binlog/mysql-bin.004816|grep GTID -B1|grep '^# at' | awk '{print $3}' | awk 'NR==1 {tmp=$1} NR>1 {print ($1-tmp, tmp, $1); tmp=$1}'|sort -n -r|more

生产中某个事务竟然占用4个G。

  1. 通过start-positionstop-position统计这个事务各个SQL占用字节大小
./mysqlbinlog --no-defaults --base64-output=decode-rows --start-position='xxxx' --stop-position='xxxxx' -vv /mysqldata/mysql/binlog/mysql-bin.004816 |grep '^# at'| awk '{print $3}' | awk 'NR==1 {tmp=$1} NR>1 {print ($1-tmp, tmp, $1); tmp=$1}'|sort -n -r|more

发现最大的一个SQL竟然占用了32M的大小,那超过10M的大概有多少个呢?

  1. 通过超过10M大小的数量
./mysqlbinlog --no-defaults --base64-output=decode-rows --start-position='xxxx' --stop-position='xxxxx' -vv /mysqldata/mysql/binlog/mysql-bin.004816|grep '^# at' | awk '{print $3}' | awk 'NR==1 {tmp=$1} NR>1 {print ($1-tmp, tmp, $1); tmp=$1}'|awk '$1>10000000 {print $0}'|wc -l

统计结果显示竟然有200多个,毛估一下,也有近4个G了

  1. 根据pos, 我们看下究竟是什么SQL导致的
./mysqlbinlog --no-defaults --base64-output=decode-rows --start-position='xxxx' --stop-position='xxxxx' -vv /mysqldata/mysql/binlog/mysql-bin.004816|grep '^# atxxxx' -C5| grep -v '###' | more

根据sql,分析了下,这个表正好有个blob字段,统计了下blob字段总合大概有3个G大小,然后我们业务上有个导入操作,这是一个非常大的事务,会频繁更新这表中记录的更新时间,导致生成binlog非常大。

问题: 明明只是简单的修改更新时间的语句,压根没有动blob字段,为什么生产的binlog这么大?因为生产的binlog采用的是row模式。

binlog的模式

binlog日志记录存在3种模式,而生产使用的是row模式,它最大的特点,是很精确,你更新表中某行的任何一个字段,会记录下整行的内容,这也就是为什么blob字段都被记录到binlog中,导致binlog非常大。此外,binlog还有statementmixed两种模式。

  1. STATEMENT模式 ,基于SQL语句的复制
  • 优点: 不需要记录每一行数据的变化,减少binlog日志量,节约IO,提高性能。
  • 缺点: 由于只记录语句,所以,在statement level下 已经发现了有不少情况会造成MySQL的复制出现问题,主要是修改数据的时候使用了某些定的函数或者功能的时候会出现。
  1. ROW模式,基于行的复制

5.1.5版本的MySQL才开始支持,不记录每条sql语句的上下文信息,仅记录哪条数据被修改了,修改成什么样了。

  • 优点: binlog中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录那一条被修改。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节。不会出现某些特定的情况下的存储过程或function,以及trigger的调用和触发无法被正确复制的问题
  • 缺点: 所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,会产生大量的日志内容。
  1. MIXED模式

从5.1.8版本开始,MySQL提供了Mixed格式,实际上就是StatementRow的结合。

Mixed模式下,一般的语句修改使用statment格式保存binlog。如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog

总结

最终分析下来,我们定位到原来是由于大事务+blob字段大致binlog非常大,最终我们采用了修改业务代码,将blob字段单独拆到一张表中解决。所以,在设计开发过程中,要尽量避免大事务,同时在数据库建模的时候特别考虑将blob字段独立成表。

欢迎关注个人公众号【JAVA旭阳】交流学习

麻了,一个操作把MySQL主从复制整崩了的更多相关文章

  1. MySQL主从复制入门

    1.MySQL主从复制入门 首先,我们看一个图: MySQL 主从复制与读写分离概念及架构分析 影响MySQL-A数据库的操作,在数据库执行后,都会写入本地的日志系统A中. 假设,实时的将变化了的日志 ...

  2. Linux 笔记 - 第二十三章 MySQL 主从复制配置

    一.前言 MySQL Replication,也被称为主从复制.AB 复制.简单来说就是 A 和 B 两台服务器做主从后,在 A 服务器上写入数据,B 服务器上也会跟着写入输入,两者之间的数据是实时同 ...

  3. MySQL主从复制的原理和实践操作

    MySQL 主从(MySQL Replication),主要用于 MySQL 的实时备份.高可用HA.读写分离.在配置主从复制之前需要先准备 2 台 MySQL 服务器. 一.MySQL主从原理 1. ...

  4. MYSQL主从复制搭建及切换操作(GTID与传统)

    结构如下: MYSQL主从复制方式有默认的复制方式异步复制,5.5版本之后半同步复制,5.6版本之后新增GTID复制,包括5.7版本的多源复制. MYSQL版本:5.7.20 操作系统版本:linux ...

  5. MYSQL一个设备上的主从复制实现-windows

    只记录一次在一个设备上实现mysql主从复制的过程,很详细,建议收藏,用到的时候照着步骤做就可以,会记录所有需要注意到的细节和一些容易遇到的坑以及解决办法! 如果需要在同一台电脑(服务器)上实现mys ...

  6. Mycat实现mysql主从复制(读写分离)

    数据库性能瓶颈主要原因: 随着用户数的增多,带来的是数据库连接的大幅度增长 随着业务体量的增长,表数据量(空间存储的问题)的大幅增长,其中涉及到索引的优化,mysql默认的索引是硬盘级别的,BTREE ...

  7. 在线建立或重做mysql主从复制架构方法(传统模式和GTID模式)【转】

    mysql主从复制架构,是mysql数据库主要特色之一,绝大多数公司都有用到. 而GTID模式是基于事务的复制模式的意思,发展到现在也是越来越多人用. 以前很多文章,介绍搭建mysql主从复制架构,是 ...

  8. CentOS下MySQL主从复制,读写分离

    1.环境:所有系统都是CentOS5.5 mysql-5.6.31-2.el5,MySQL中都没有数据 主服务器IP为192.168.128.230 从服务器IP为192.168.128.235 代理 ...

  9. Mysql主从复制原理详解

    一.为什么要做主从同步 1.读写分离,降低对主数据库的IO消耗 2.避免数据丢失 3.提高业务系统性能 二.主从同步和集群的区别 1.主从同步 一般需要两台及以上数据库服务器即可(一台用于写入数据,一 ...

  10. 重新学习Mysql数据13:Mysql主从复制,读写分离,分表分库策略与实践

    一.MySQL扩展具体的实现方式 随着业务规模的不断扩大,需要选择合适的方案去应对数据规模的增长,以应对逐渐增长的访问压力和数据量. 关于数据库的扩展主要包括:业务拆分.主从复制.读写分离.数据库分库 ...

随机推荐

  1. 之前学的yield

    生成器&迭代器 生成器的特性1.生成器是一个有yield关键字的函数对象,yield暂停并保存并返回调用结果2.第一次通过next开始运行这个函数,以后每次next就从yield开始继续运行函 ...

  2. Vue解决后台传过来的时间展示时带T

    用空格替换: {{scope.row.ctime.toLocaleString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '')}} 参考作者:https: ...

  3. SQLServer自带备份优劣分析

    众所周知, SQL Server自身的"维护计划"可以实现自动备份数据库. 既然这样,那还有必要使用第三方专业备份软件吗? 本文以[护卫神·好备份专业版]为例,分析两者之间的优劣. ...

  4. Pinia使用技巧

    vue2使用的vuex,是一个状态管理器,现在vue3出了最新的pinia,今年偿试一下. 首先是安装,这里要注意一下,有一个持久化插件,如果不用的话,页面一刷新,状态会消失. npm install ...

  5. 给c++写python的split()与input()【python一样写c++、一】

    python的split确实是很香的功能. 写c++的时候,就会想着,要是能直接input().split()那不挺好. 实际上真的可以:自己动手,丰衣足食. 先放成品展示. int main(){ ...

  6. RPA的市场定义和企业选型

    RPA(Robotic Process Automation)译为机器人流程自动化,又可以称为数字化劳动力,是一种智能化软件,通过模拟并增强人类与计算机的交互过程,实现工作流程中的自动化.RPA具有对 ...

  7. Harmonic Number 调和级数(欧拉常数)或者分块暴力

    给你个n让你求 Memory limit 32768 kB 输出误差不超过1e-8 思路:做之前不知都调和级数不知道欧拉常数没问题,肯定能先想到暴力打标,打完发现数组内存太大,那么问题就是怎么能让内存 ...

  8. MyBatis 整体架构【包含 SQL执行流程】

    Mybatis 的整体架构分为三层,分别是基础支持层.核心处理层和接口层.基础支持层为核心处理层的功能提供了良好的支撑.

  9. 【数仓运维实践】关于GaussDB(DWS)单SQL磁盘空间管控

    摘要:本文主要讲解数仓运维中遇到单SQL磁盘空间管控问题的解析和方案. 本文分享自华为云社区<GaussDB(DWS)运维 -- 单SQL磁盘空间管控>,作者: 譡里个檔. [问题描述] ...

  10. ArgoCD实践之基于配置清单创建Application

    1. 什么是Application ArgoCD的两个核心概念为Application和Project,他们可分别基于Application CRD和AppProject CRD创建; 核心组件: A ...