『MySQL 实战 45 讲』24 - MySQL是怎么保证主备一致的?

MySQL是怎么保证主备一致的?

MySQL 主备的基本原理

  1. 基本的主备切换流程
    在这里插入图片描述
  • 状态 1:客户端的读写都直接访问节点 A,而节点 B 是 A 的备库
  • 状态 2:切换时,读写访问的都是节点 B,而节点 A 是 B 的备库
  • 注意:建议备库只设置制度(readonly)模式
    • 虽然是只读,但是因为 readonly 设置对超级 (super) 权限用户是无效的,而用于同步更新的线程,就拥有超级权限
  1. 节点 A 到节点 B 的内部流程
    在这里插入图片描述
  • 主库接收到客户端的更新请求后,执行内部事务的更新逻辑,同时写 binlog
  • 备库 B 跟主库 A 之间维持了一个长连接
  • 完整流程
    • 备库 B 上通过 change master 命令,设置主库 A 的 IP、端口、用户名、密码,以及要从哪个位置开始请求 binlog,这个位置包含文件名和日志偏移量
    • 在备库 B 上执行 start slave 命令,这时候备库会启动两个线程,就是图中的 io_thread 和 sql_thread。其中 io_thread 负责与主库建立连接
    • 主库 A 校验完用户名、密码后,开始按照备库 B 传过来的位置,从本地读取 binlog,发给 B
    • 备库 B 拿到 binlog 后,写到本地文件,称为中转日志(relay log)
    • sql_thread 读取中转日志,解析出日志里的命令,并执行

binlog 的三种格式对比

  1. 目前有三种格式:statement、row、mixed
  2. 要注意修改 binlog 格式为 statement,可以用过 show variables like ‘%binlog_format%’; 查看
  • sql
# 使用后重启 mysql
set global binlog_format='STATEMENT'
  • docker
    • 首先配置一下 my.cnf
      [mysqld]
      server_id=1000
      binlog-ignore-db=mysql  
      log-bin=mall-mysql-bin  
      binlog_cache_size=1M  
      binlog_format=statement
      expire_logs_days=7  
      slave_skip_errors=1062
      
    • 运行 docker
      docker run -p 3305:3306 --name mysql-master --restart=always --privileged=true \
      -v /root/mysql-master/log:/var/log/mysql \
      -v /root/mysql-master/data:/var/lib/mysql \
      -v /root/mysql-master/conf:/etc/mysql \
      -v /etc/localtime:/etc/localtime:ro \
      -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.30
      
  1. 首先创建一个数据表
CREATE TABLE `t` ( `id` int(11) NOT NULL, `a` int(11) DEFAULT NULL, `t_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `a` (`a`), KEY `t_modified`(`t_modified`)) ENGINE=InnoDB;insert into t values(1,1,'2018-11-13');
insert into t values(2,2,'2018-11-12');
insert into t values(3,3,'2018-11-11');
insert into t values(4,4,'2018-11-10');
insert into t values(5,5,'2018-11-09');

在这里插入图片描述
4. 执行一次删除语句,查看 delete 语句在 binlog 是怎么记录的

  • 要注意执行前,如果是通过 mysql 客户端 启动的,要执行 mysql -c -root ***,否则下面的注释行不会记录在 binlog
delete from t /*comment*/  where a>=4 and t_modified<='2018-11-10' limit 1;
  1. binlog_format=statement 时,binlog 里面记录的就是 SQL 语句的原文
  • 首先要通过 show variables like ‘log_%’; 查看 log_bin 参数是否为 ON,否则是看不到日志
  • 通过 show binary logs; 去查看有哪些 binlog 日志,一般最大的 File_size 会记录刚刚执行的 sql
show binlog events in 'mall-mysql-bin.000004';

在这里插入图片描述

  • 输出结果解释
    • 第一行:可先忽略
    • 第二、四行: BEGIN 与 COMMIT 对应,中间是事务
    • 第三行:真实执行语句
  1. 其实,刚刚执行的 delete 语句,注意:在 statement 格式下,是 unsafe 的,因为会出现主从不一致的情况
    在这里插入图片描述
  • 不一致的例子
    • 如果 delete 语句使用的是索引 a,那么会根据索引 a 找到第一个满足条件的行,也就是说删除的是 a=4 这一行
    • 但如果使用的是索引 t_modified,那么删除的就是 t_modified='2018-11-09’ 也就是 a=5 这一行
  1. 修改 binlog_format='row',再看看 binlog 实际内容
  • 这里的 binlog 里没有了 SQL 语句的原文,而是换成两个 event
    • Table_map event: 要操作的表是 test 库的表 t
    • Delete_rows event:用于定义删除的行为
      在这里插入图片描述
  1. 实际上面的信息还是没看到i昂西信息,需要借助 mysqlbinlog 工具
  • 如果没有的话,执行 yum install mysql,会有相关的工具下载下来
# 其中 2191 是上面从对应的位置开始的
# 我这边没执行成功,因为可能 8 的版本,5 的 mysqlbinlog 没办法解析
mysqlbinlog -vv binlog.000058 --start-position=2191

在这里插入图片描述

  • 其中的信息如下:
    • server id 1:表示这个事务是在 server_id=1 的这个库上执行的
    • CRC32:每个 event 都有 CRC32 的值,主要是 binlog_checksum 设置为 CRC32
    • Table_map event:实际 map 到数字应该是 93。如果有操作多个表,每个表会有对应的数字
    • @1=4、 @2=4…:实际就是对应删除的行每一列的值
    • binlog_row_image 默认配置为 FULL,所以 Delete_event 包含了删除行的所有字段的值,如果把 binlog_row_image 设置为 MINIMAL,则只会记录必要的信息,在这个例子里,就是只会记录 id=4 这个信息
    • 最后的 Xid event,用于表示事务被正确地提交了
  1. 总结
  • 当 binlog_format 使用 row 格式的时候,binlog 里面记录了真实删除行的主键 id,这样 binlog 传到备库去的时候,就肯定会删除 id=4 的行,不会有主备删除不同行的问题

为什么会有 mixed 格式的 binlog

  1. statement 格式的 binlog 可能会导致主备不一致,所以要使用 row 格式
  2. row 格式的缺点是,很占空间。
  • 用一个 delete 语句删掉 10 万行数据,用 statement 的话就是一个 SQL 语句被记录到 binlog 中,占用几十个字节的空间
  • 用 row 格式的 binlog,就要把这 10 万条记录都写到 binlog 中
  1. MySQL 就取了个折中方案,也就是有了 mixed 格式的 binlog。MySQL 自己会判断这条 SQL 语句是否可能引起主备不一致,如果有可能,就用 row 格式,否则就用 statement 格式
  2. 越来越多的场景要求把 MySQL 的 binlog 格式设置成 row,最直接好处:恢复数据
  • delete 语句:
    • row 格式的 binlog 保留了被删掉的行的整行信息。可以将 delete 语句转换成 insert 数据插入回去恢复
  • insert 语句
    • row 格式下,insert 语句的 binlog 里会记录所有的字段信息。可以将 insert 转成 delete 语句,删除误插入的一行数据
  • update 语句:
    • binlog 里面会记录修改前整行的数据和修改后的整行数据。只需要把 event 的前后两行信息对调一下,就可以去数据库里面执行恢复更新操作
  1. mixed 格式的 binlog 现在已经用得不多了
  2. 关于时间戳的问题
  • 首先把 binlog 格式设置为 mixed,然后执行下面语句
insert into t values(10,10, now());

在这里插入图片描述

  • MySQL 会选择使用 statement 格式。如果 binlog 过了 1 分钟才传给备库的话,主备的数据不会造成不一致,原因为
  • 当使用 mysqlbinlog 工具查看的时候,它会多一条 SET TIMESTAMP 命令
    在这里插入图片描述
  1. 总结
  • binlog 来恢复数据的标准做法是,用 mysqlbinlog 工具解析出来,然后把解析结果整个发给 MySQL 执行。类似下面的命令
    • 命令意思:将 master.000001 文件里面从第 2738 字节到第 2973 字节中间这段内容解析出来,放到 MySQL 去执行
mysqlbinlog master.000001  --start-position=2738 --stop-position=2973 | mysql -h127.0.0.1 -P13000 -u$user -p$pwd;

循环复制问题(双 M 结构)

在这里插入图片描述

  1. 业务逻辑
  • 节点 A 上更新了一条语句,然后再把生成的 binlog 发给节点 B,节点 B 执行完这条更新语句后也会生成 binlog
    • 建议:log_slave_updates 设置为 on,表示备库执行 relay log 后生成 binlog。可以让更新事件在备库上也记录一份
  1. 上面业务逻辑可能会出现循环复制问题,解决的方式
  • 规定两个库的 server id 必须不同,如果相同,则它们之间不能设定为主备关系
  • 一个备库接到 binlog 并在重放的过程中,生成与原 binlog 的 server id 相同的新的 binlog
  • 每个库在收到从自己的主库发过来的日志后,先判断 server id,如果跟自己的相同,表示这个日志是自己生成的,就直接丢弃这个日志

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/62643.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自荐一部IT方案架构师回忆录

作者本人毕业于一个不知名大专院校&#xff0c;所读专业计算机科学技术。2009年开始IT职业生涯&#xff0c;至今工作15年。擅长TSQL/Shell/linux等技术&#xff0c;曾经就职于超万人大型集团、国内顶级云厂商、央国企公司。参与过运营商大数据平台、大型智慧城市ICT、云计算、人…

python数据分析之爬虫基础:selenium详细讲解

目录 1、selenium介绍 2、selenium的作用&#xff1a; 3、配置浏览器驱动环境及selenium安装 4、selenium基本语法 4.1、selenium元素的定位 4.2、selenium元素的信息 4.3、selenium元素的交互 5、Phantomjs介绍 6、chrome handless模式 1、selenium介绍 &#xff08;1…

【数据结构——查找】顺序查找(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 测试说明 我的通关代码: 测试结果&#xff1a; 任务描述 本关任务&#xff1a;实现顺序查找的算法。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.根据输入数据建立顺序表&#xff0c;2.顺序表的输出&#xff0c;…

光伏电站建设成本利润估算

​截至2024年9月底,全国光伏发电装机容量达到7.7亿千瓦,同比增长48.4%。其中集中式光伏4.3亿千瓦,分布式光伏3.4亿千瓦。2024年前三季度,全国光伏发电量6359亿千瓦时,同比增长45.5%。全国光伏发电利用率97.2%,同比下降1.1个百分点.早在今年2月份,中国光伏行业协会名誉理…

create-react-app react19 搭建项目报错

报错截图 此时运行会报错&#xff1a; 解决方法&#xff1a; 1.根据提示安装依赖法 执行npm i web-vitals然后重新允许 2.删除文件法 在index.js中删除对报错文件的引入&#xff0c;删除报错文件

scala的集合性能2

可变集合\n可变集合允许在原地修改数据&#xff0c;适合需要频繁更新的场景。Scala 的可变集合包括 ArrayBuffer、HashSet和HashMap。 1. ArrayBuffer\nArrayBuffer 是一个可变的动态数组&#xff0c;提供高效的随机访问和添加操作。 import scala.collection.mutable.ArrayB…

【Ubuntu】脚本自动化控制终端填充

1.sh脚本文件控制终端写入命令 在SLAM算法中&#xff0c;每次启动vins都需要起很多终端&#xff0c;尽管使用了超级终端Terminator可以终端内划分看起来更加便捷&#xff0c;但是每次起算法的命令还是要自己输入&#xff0c;已经被麻烦了两年了&#xff0c;今天突然想写写一个…

【自学】Vues基础

学习目录 Vues基础本地应用网络应用综合应用 工具的准备 我个人比较喜欢使用HTMLDROWNER&#xff0c;学习资料推荐使用VC&#xff0c;仅供选择吧 前置知识 HTMLCSSJSAJAX&#xff1a;这个是学习资料博主推荐的 个人感觉认真学好HTMLCSSJS理解vues基础很容易上手 官方网址…

Scratch 消灭字母小游戏

背景 最近尝试一边自学Scratch&#xff0c;一边尝试教给小孩&#xff0c;看他打字时在键盘上乱打一气&#xff0c;想起来自己小时候玩过的学习机打字母游戏&#xff0c;就想给他下载一个。结果网上看到的代码&#xff0c;要么质量太差&#xff08;有26个字母就要写 26 个判断&…

python调用matlab函数(内置 + 自定义) —— 安装matlab.engine

文章目录 一、简介二、安装matlab.engine2.1、基于 CMD 安装2.2、基于 MATLAB 安装&#xff08;不建议&#xff09; 三、python调用matlab函数&#xff08;内置 自定义&#xff09; 一、简介 matlab.engine&#xff08;MATLAB Engine API for Python&#xff09;&#xff1a;…

pytroch环境安装-pycharm

环境介绍 安装pycharm 官网下载即可&#xff0c;我这里已经安装&#xff0c;就不演示了 安装anaconda 【官网链接】点击下载 注意这一步选择just me 这一步全部勾上 打开 anaconda Prompt 输入conda create -n pytorch python3.8 命令解释&#xff1a;创建一个叫pytorch&…

Photoshop提示错误弹窗dll缺失是什么原因?要怎么解决?

Photoshop提示错误弹窗“DLL缺失”&#xff1a;原因分析与解决方案 在创意设计与图像处理领域&#xff0c;Photoshop无疑是众多专业人士和爱好者的首选工具。然而&#xff0c;在使用Photoshop的过程中&#xff0c;有时会遇到一些令人头疼的问题&#xff0c;比如突然弹出的错误…

自己总结:selenium高阶知识

全篇大概10000字&#xff08;含代码&#xff09;&#xff0c;建议阅读时间30min 一、等待机制 如果有一些内容是通过Ajax加载的内容&#xff0c;那就需要等待内容加载完毕才能进行下一步操作。 为了避免人为操作等待&#xff0c;会遇到的问题&#xff0c; selenium将等待转换…

上海亚商投顾:创业板指震荡调整 机器人概念股再度爆发

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日冲高回落&#xff0c;深成指、创业板指盘中跌超1%&#xff0c;尾盘跌幅有所收窄。机器人概念股逆势爆…

(Linux)CentOS7离线安装MinIO(超详细)

目录 前言1. 下载2. 安装VMware3. 安装CentOS4. 离线安装MinIO4.1. ssh工具连接CentOS4.2. 上传MinIO离线包4.2.1 创建data目录4.2.2 上传RPM包到data目录4.2.3 安装RPM包4.2.4 创建MinIO数据目录4.2.5 配置 MinIO 服务4.2.6 启动 MinIO4.2.7 开放端口 4.2.8 访问MinIO 创作不易…

【JavaWeb后端学习笔记】Maven项目管理

Maven 1、分模块设计2、Maven继承2.1 继承关系2.2 版本锁定 3、Maven聚合4、聚合与继承的关系 1、分模块设计 如果一个项目中含有大量的功能模块。可以考虑将这些功能分模块设计&#xff0c;逐一进行开发。例如将公共类可以定义在一个项目中&#xff0c;将通用工具类也放在一个…

HarmonyOS-高级(四)

文章目录 应用开发安全应用DFX能力介绍HiLog使用指导HiAppEvent &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;HarmonyOS专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月11日11点18分 应用开发安全 应用隐私保护 隐私声明弹窗的作…

网络安全法-网络运行安全

第三章 网络运行安全 第一节 一般规定 第二十一条 国家实行网络安全等级保护制度。网络运营者应当按照网络安全等级保护制度的要求&#xff0c;履行下列安全保护义务&#xff0c;保障网络免受干扰、破坏或者未经授权的访问&#xff0c;防止网络数据泄露或者被窃取、篡改&…

论文阅读:Statistical Comparisons of Classifiers over Multiple Data Sets

论文地址&#xff1a;Statistical Comparisons of Classifiers over Multiple Data Sets (acm.org) 前面在机器学习之Friedman检验-CSDN博客 中提到了Friedman检验&#xff0c;这里将对这个方法的论文进行详细的阅读&#xff0c;以了解其原理。 摘要 尽管用于在单个数据集上比…

【Unity技巧】Unity项目中哪些文件不用管理(.gitignore)

Unity的项目编译后一般都比较大&#xff0c;动辙几个G。这里面一般我们只需要把Assets, Packages, ProjectSettings这三个文件夹进行源代码管理就可以&#xff0c;其他文件就可以通过下面的.gitignore来忽略掉。 .gitignore文件的内容如下&#xff1a; # 将此 .gitignore 文件…