麻了,一个操作把MySQL主从复制整崩了
前言
最近公司某项目上反馈mysql主从复制失败,被运维部门记了一次大过,影响到了项目的验收推进,那么究竟是什么原因导致的呢?而主从复制的原理又是什么呢?本文就对排查分析的过程做一个记录。
主从复制原理
我们先来简单了解下MySQL主从复制的原理。
- 主库
master服务器会将 SQL 记录通过dump线程写入到 二进制日志binary log中; - 从库
slave服务器开启一个io thread线程向服务器发送请求,向 主库master请求binary log。主库master服务器在接收到请求之后,根据偏移量将新的binary log发送给slave服务器。 - 从库
slave服务器收到新的binary log之后,写入到自身的relay log中,这就是所谓的中继日志。 - 从库
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。
- 上图的
write,是指把日志写入到文件系统的page cache,并没有把数据持久化到磁盘,所以速度比较快 - 上图的
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。
- 查看
binlog日志
./mysqlbinlog --no-defaults --base64-output=decode-rows -vv /mysqldata/mysql/binlog/mysql-bin.004816|more
- 以事务为单位统计
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。
- 通过
start-position和stop-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的大概有多少个呢?
- 通过超过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了
- 根据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还有statement和mixed两种模式。
- STATEMENT模式 ,基于SQL语句的复制
- 优点: 不需要记录每一行数据的变化,减少
binlog日志量,节约IO,提高性能。 - 缺点: 由于只记录语句,所以,在
statement level下 已经发现了有不少情况会造成MySQL的复制出现问题,主要是修改数据的时候使用了某些定的函数或者功能的时候会出现。
- ROW模式,基于行的复制
5.1.5版本的MySQL才开始支持,不记录每条sql语句的上下文信息,仅记录哪条数据被修改了,修改成什么样了。
- 优点:
binlog中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录那一条被修改。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节。不会出现某些特定的情况下的存储过程或function,以及trigger的调用和触发无法被正确复制的问题 - 缺点: 所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,会产生大量的日志内容。
- MIXED模式
从5.1.8版本开始,MySQL提供了Mixed格式,实际上就是Statement与Row的结合。
在Mixed模式下,一般的语句修改使用statment格式保存binlog。如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog。
总结
最终分析下来,我们定位到原来是由于大事务+blob字段大致binlog非常大,最终我们采用了修改业务代码,将blob字段单独拆到一张表中解决。所以,在设计开发过程中,要尽量避免大事务,同时在数据库建模的时候特别考虑将blob字段独立成表。
欢迎关注个人公众号【JAVA旭阳】交流学习
麻了,一个操作把MySQL主从复制整崩了的更多相关文章
- MySQL主从复制入门
1.MySQL主从复制入门 首先,我们看一个图: MySQL 主从复制与读写分离概念及架构分析 影响MySQL-A数据库的操作,在数据库执行后,都会写入本地的日志系统A中. 假设,实时的将变化了的日志 ...
- Linux 笔记 - 第二十三章 MySQL 主从复制配置
一.前言 MySQL Replication,也被称为主从复制.AB 复制.简单来说就是 A 和 B 两台服务器做主从后,在 A 服务器上写入数据,B 服务器上也会跟着写入输入,两者之间的数据是实时同 ...
- MySQL主从复制的原理和实践操作
MySQL 主从(MySQL Replication),主要用于 MySQL 的实时备份.高可用HA.读写分离.在配置主从复制之前需要先准备 2 台 MySQL 服务器. 一.MySQL主从原理 1. ...
- MYSQL主从复制搭建及切换操作(GTID与传统)
结构如下: MYSQL主从复制方式有默认的复制方式异步复制,5.5版本之后半同步复制,5.6版本之后新增GTID复制,包括5.7版本的多源复制. MYSQL版本:5.7.20 操作系统版本:linux ...
- MYSQL一个设备上的主从复制实现-windows
只记录一次在一个设备上实现mysql主从复制的过程,很详细,建议收藏,用到的时候照着步骤做就可以,会记录所有需要注意到的细节和一些容易遇到的坑以及解决办法! 如果需要在同一台电脑(服务器)上实现mys ...
- Mycat实现mysql主从复制(读写分离)
数据库性能瓶颈主要原因: 随着用户数的增多,带来的是数据库连接的大幅度增长 随着业务体量的增长,表数据量(空间存储的问题)的大幅增长,其中涉及到索引的优化,mysql默认的索引是硬盘级别的,BTREE ...
- 在线建立或重做mysql主从复制架构方法(传统模式和GTID模式)【转】
mysql主从复制架构,是mysql数据库主要特色之一,绝大多数公司都有用到. 而GTID模式是基于事务的复制模式的意思,发展到现在也是越来越多人用. 以前很多文章,介绍搭建mysql主从复制架构,是 ...
- CentOS下MySQL主从复制,读写分离
1.环境:所有系统都是CentOS5.5 mysql-5.6.31-2.el5,MySQL中都没有数据 主服务器IP为192.168.128.230 从服务器IP为192.168.128.235 代理 ...
- Mysql主从复制原理详解
一.为什么要做主从同步 1.读写分离,降低对主数据库的IO消耗 2.避免数据丢失 3.提高业务系统性能 二.主从同步和集群的区别 1.主从同步 一般需要两台及以上数据库服务器即可(一台用于写入数据,一 ...
- 重新学习Mysql数据13:Mysql主从复制,读写分离,分表分库策略与实践
一.MySQL扩展具体的实现方式 随着业务规模的不断扩大,需要选择合适的方案去应对数据规模的增长,以应对逐渐增长的访问压力和数据量. 关于数据库的扩展主要包括:业务拆分.主从复制.读写分离.数据库分库 ...
随机推荐
- redhat7.6配置本地yum源
redhat7.6配置本地yum源 将光盘或者iso文件挂载到 /mnt 目录下 查看配置文件 [root@zqds122 mnt]# cat /etc/yum.repos.d/rh7ISO.repo ...
- [Unity热更新]Addressables
参考链接: https://linxinfa.blog.csdn.net/article/details/122390621?spm=1001.2014.3001.5502 总结: 1.
- cider 二面
cider 二面 1.祖传自我介绍 2.当前BLF外卖业务缺点是什么? 产品单一 : 跟竞品比较起来,产品单一导致用户流量很少 3.QLExpress二次开发的原因 流程对接 提升性能 后台对接 4. ...
- centos7下安装Node.js MongoDB Nginx
一.Node.js 方法1(笔者采用).如果对Node.js环境有比较高的要求,建议选择源码安装的方式进行安装,通过wget命令下载Node.js官网上的tar.gz文件包到centos服务器上,进 ...
- 关于Go语言的底层,你想知道的都在这里!
目录 1. GoLang语言 1.1 Slice 1.2 Map 1.3 Channel 1.4 Goroutine 1.5 GMP调度 1.6 垃圾回收机制 1.7 其他知识点 2. Web框架Gi ...
- 499div2-E Border :裴蜀定理
这个定理就像类似学扩展欧几里得判断是否有解的条件,当时是ax+by = c:仅当c = k*gcd(a,b)时有解,其实也就是只要是公约数的倍数就行. 而裴蜀定理是多个未知量x1*a1+x2*a2+. ...
- RTC月度小报6月丨编程挑战赛圆满收官;声网上市1周年回顾...
本月亮点速览 产品与技术: 声网Agora 实时音视频服务正式上线 HTC VIVE Sync App,支持非 VR 用户 「灵动课堂」发布 1.1.2 版本 「互动直播」6 月共发布两个版,最新版本 ...
- 自己动手从零写桌面操作系统GrapeOS系列教程——18.外设和IO
学习操作系统原理最好的方法是自己写一个简单的操作系统. 一.外设和I/O接口 前面我们介绍过冯·诺依曼结构包含5部分,其中输入设备和输出设备统称为外部设备,简称外设.常见的外设有鼠标.键盘.显示器.硬 ...
- RHCE服务----DNS
实验要求: 1.建立DNS服务器,负责解析的域为openedu.com 2.要求将MX记录指向mail.openedu.com,且对应A记录为本机IP 3.要求将NS记录指向ns1.openedu.c ...
- ArgoCD实践之基于配置清单创建Application
1. 什么是Application ArgoCD的两个核心概念为Application和Project,他们可分别基于Application CRD和AppProject CRD创建; 核心组件: A ...