『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;…

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

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

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;比如突然弹出的错误…

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

上海亚商投顾前言&#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 创作不易…

HarmonyOS-高级(四)

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

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

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

练9:进制转换

欢迎大家订阅【蓝桥杯Python每日一练】 专栏&#xff0c;开启你的 Python数据结构与算法 学习之旅&#xff01; 文章目录 1 进制转换2 例题分析 1 进制转换 ①任意制转为十进制 【示例】 ②十进制转为任意制 【法一】 【法二】 2 例题分析 题目地址&#xff1a;https:/…

C语言:指针详解续

一、字符指针变量 我们知道有种指针类型为字符指针(char*)。 #include <stdio.h> int main() {char ch w;char* pch &ch;printf("%c\n", *pch);return 0; } 其实它还有一种使用方式。 #include <stdio.h> int main() {char* pstr "hello…

HarmonyOS-高级(一)

文章目录 一次开发、多端部署自由流转 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;HarmonyOS专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月09日12点19分 一次开发、多端部署 布局能力 自适应布局 拉伸能力均分能力占比能力缩放…

【嵌入式系统】第4章 嵌入式最小系统,供电电路,时钟电路,复位电路,程序下载电路

关注作者了解更多 我的其他CSDN专栏 过程控制系统 工程测试技术 虚拟仪器技术 可编程控制器 工业现场总线 数字图像处理 智能控制 传感器技术 嵌入式系统 复变函数与积分变换 单片机原理 线性代数 大学物理 热工与工程流体力学 数字信号处理 光电融合集成电路…

期权懂|交易个股期权需要注意哪些风险?

期权小懂每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 交易个股期权需要注意哪些风险&#xff1f; 一、交易个股期权需要注意合约到期风险&#xff1a; 需关注到期日&#xff0c;及时平仓或行权&#xff0c;避免合约作废。二、交易个…

MVC配置文件配置及位置

配置文件位置 默认位置 WEB-INF目录下&#xff1a;-servlet.xml 指定位置 在web.xml中配置 DispatcherServlet中的contextConfigLocation属性可以指定配置文件位置 确保配置文件存在于类路径&#xff08;Resources&#xff09;下 web.xml <?xml version"1.0" …

可视化逻辑表达式编辑器

优质博文&#xff1a;IT-BLOG-CN 一、QueryBuilder介绍 QueryBuilder 是一个用于创建查询和过滤器的 UI 组件。 QueryBuilder的特点 1、支持的输入属性丰富&#xff0c;常见的 字符串&#xff0c;整数&#xff0c;浮点数&#xff0c;布尔类型&#xff0c;日期类型&#xff0…

Linux下mysql环境的搭建

1.mysql的下载 去MySQL官网下载mysql的linux压缩包 MySQL :: Download MySQL Community Server 如果下载慢请到网盘中自行下载 通过网盘分享的文件&#xff1a;mysql-8.0.40-1.el7.x86_64.rpm-bundle.tar 链接: https://pan.baidu.com/s/1vUJ-VuTwer1nLPT-haQCqw?pwd6342 提…