Mysql binlog的三种模式statement,row,mixed详解,以及无主键造成复制延时的测试

2.1  Statement 模式的概念
Statement 是基于语句的复制模式。
Statement 模式将数据库中执行的修改操作记录为 SQL 语句,再从数据库上执行相同的 SQL 语句来实现数据同步。

2.2  Statement 模式的优点
Statement 模式的优点是简单明了,易于理解和实现。

2.3  Statement 模式的缺点

Statement 模式在执行涉及非确定性函数、触发器和存储过程等操作时,可能会导致不一致的结果。

1)不支持 RU、RC 隔离级别;
2)binglog 日志文件中,上一个事物的结束点是下一个事物的开始点;
3)DML、DDL 语句都会明文显示;
4)对一些系统函数不能准确复制或者不能复制;
5)主库执行 delete from t1 where c1=xxx limit 1,statement 模式下,从库也会这么执行,可能导致删除的不是同一行数据;
6)主库有 id=1 和 id=10 两行数据,从库有 id=1,2,3,10 这四行数据,主库执行 delete from t1 where id<10 命令,从库删除过多数据。

2.4  Statement 模式的应用场景
Statement 模式适用于大多数情况下的数据库复制需求。

例如:
1)一次更新大量数据,如二十万数据。反之,在复制时,从库可能会追得太慢,然后导致延时;
2)使用 pt-table-checksum 工具时。


2.1  Row 模式的概念

MySQL 5.7 默认的日志模式为 Row。
Row 模式是基于行的复制模式,它将数据库中实际修改的行记录写入 Binlog ,从数据库通过解析 Binlog 来逐行执行相应的修改操作。
相对 statement ,Row 模式更加精确、安全,能够确保数据的一致性。
2.2  Row 模式的优点

Row 模式能准确复制修改的行记录,避免了语句复制模式下的不确定性问题。

2.3 Row 模式的缺点

如果 Binlog 文件较大,传输成本就会很高,在某些情况下,可能会导致性能下降。

1)在表有主键的情况下复制更加快;

2)系统的特殊函数也能复制;

3)更少的锁,只有行锁;

4)Binlog 文件比较大,假设单语句更新 20 万行数据,可能要半小时,也有可能把主库跑挂;

5)MySQL 5.6 之前的版本,无法从 binog 看见用户执行的 SQL 语句;

6)DDL 语句明文显示,DML 语句加密显示;

7)DML 经过 base64 加密,需要使用参数 --base64-output=decode-rows --verbose;

8)update 修改的语句可以看到历史旧数据。
2.4  Row 模式的应用场景

Row 模式适用于对数据一致性要求较高的场景,特别是涉及一些复杂的数据库操作和业务逻辑。例如,涉及触发器、存储过程和函数等的数据库操作。

使用Row 模式时需注意,Row 模式可能导致 Binlog 文件较大,需要合理设置 Binlog 文件大小和保留时间。

3.1  Mixed 模式的概念

Mixed 模式(混合模式)是将语句复制模式和行复制模式结合起来使用。

大多数的修改操作,通常使用 Statement 模式记录对应的 SQL 语句。

一些特殊的操作,涉及非确定性函数和存储过程等,则使用 Row 模式记录修改的行记录。

3.2  Mixed 模式的优缺点

Mixed 模式综合了语句复制模式和行复制模式的优点,能够在大多数情况下高效地记录修改操作,并在需要时使用行复制模式确保数据的准确性。

但 Mixed 模式对一些特殊操作的处理可能会很复杂,需要特别注意下配置和管理。

我们来测试下没有主键的情况下,从库复制延时情况:
主库:创建无主键的表log_test然后用存储过程插入4000000行数据:
delimiter //
drop procedure if exists insert_log_test;
create procedure insert_log_test()
begin
    declare i int;
    set i = 0;
     start transaction;
    while i < 1000000 do
        insert into log_test values (i,'中间提交的事务+++++++++**********++++++++');
        insert into log_test values (i,'中间提交的事务+++++++++**********++++++++');
       insert into log_test values (i,'中间提交的事务+++++++++**********++++++++');
       insert into log_test values (i,'中间提交的事务+++++++++**********++++++++');
        set i = i + 1;
    end while;
    commit;

end//
delimiter ;
mysql> call insert_log_test();
Query OK, 0 rows affected (1 min 17.62 sec)

mysql> select count(*) from log_test;
+----------+
| count(*) |
+----------+
|  4000000 |
+----------+
1 row in set (2.10 sec)

mysql> update log_test set id=id+80000000;
Query OK, 4000000 rows affected (17.84 sec)
Rows matched: 4000000  Changed: 4000000  Warnings: 0

备库:可以看到Seconds_Behind_Master一直在增大
[root@localhost:mytest1]>show slave status\G;

          Exec_Master_Log_Pos: 1012007859
              Relay_Log_Space: 1453954904
        Seconds_Behind_Master: 431

可以看到5分钟的时间,更新了不到10000行数据,追平主库需要大概5分钟*400=20000分钟=330小时=14天。。。。。

[root@localhost:mytest1]>select now();
+---------------------+
| now()               |
+---------------------+
| 2023-09-11 16:13:38 |
+---------------------+
1 row in set (0.00 sec)

[root@localhost:mytest1]>select count(*) from log_test where id>80000000;
+----------+
| count(*) |
+----------+
|    39629 |
+----------+
1 row in set (2.59 sec)

[root@localhost:mytest1]>select now();
+---------------------+
| now()               |
+---------------------+
| 2023-09-11 16:18:38 |
+---------------------+
1 row in set (0.00 sec)

[root@localhost:mytest1]>select count(*) from log_test where id>80000000;
+----------+
| count(*) |
+----------+
|    48282 |
+----------+
1 row in set (2.29 sec)

那存在主键,只存在普通索引和无任何索引三种情况,延时的不同以及原理是什么呢?

那存在主键,只存在普通索引和无任何索引三种情况,延时的不同以及原理是什么呢?
1)只存在普通索引:
从库应用的时候会重新评估应该使用哪个索引,优先使用主键和唯一键。因为表只有一个普通索引key,对于Event中的每条数据都需要进行索引定位操作,并且对于非唯一索引来讲第一次返回的第一行数据可能并不是删除的数据,可能还需要继续扫描下一行。大概的流程如图:

2)存在主键:

主库执行时会首先利用主键,只需要一次索引定位,然后顺序扫描接下来的数据进行更新就可以了。大概的流程如图:

3)不存在任何索引

如果表上一个索引都没有的话,从库执行的每个event都要进行全表扫描,代价非常大,这也是表上没有索引从库会有比较大同步延迟的关键原因。大概的流程图:

我们来实际测试一下,存在主键的情况下,从库追日志的性能提高多少,测试结果:等主库Update完成后,立即在从库查询,就发现已经追平了,由此可见主键的对提升性能的重要性。

主:
delimiter //
drop procedure if exists insert_log_test;
create procedure insert_log_test()
begin
    declare i int;
    set i = 0;
     start transaction;
    while i < 1000000 do
        insert into log_test_new values (default,i,'中间提交的事务+++++++++**********++++++++');
        insert into log_test_new values (default,i,'中间提交的事务+++++++++**********++++++++');
       insert into log_test_new values (default,i,'中间提交的事务+++++++++**********++++++++');
       insert into log_test_new values (default,i,'中间提交的事务+++++++++**********++++++++');
        set i = i + 1;
    end while;
    commit;

end//
delimiter ;

mysql> create table log_test_new(id_primary INT PRIMARY KEY AUTO_INCREMENT,id int,name VARCHAR(100));
Query OK, 0 rows affected (0.01 sec)

mysql> source /home/mysql/liys/insert_log_test.sql;
Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

mysql> call insert_log_test();
Query OK, 0 rows affected (1 min 18.90 sec)

update log_test_new set id=id+80000000;


从:从库很快就追平了日志,等主库Update完成后,立即在从库查询,就发现已经追平了,由此可见主键的对提升性能的重要性。


[root@localhost:mytest1]>select count(*)  from log_test_new where id>=80000000;
+----------+
| count(*) |
+----------+
|  4000000 |
+----------+
1 row in set (1.45 sec)

[root@localhost:mytest1]>select * from log_test_new where id=80000000;          
+------------+----------+--------------------------------------------------+
| id_primary | id       | name                                             |
+------------+----------+--------------------------------------------------+
|          1 | 80000000 | 中间提交的事务+++++++++**********++++++++        |
|          2 | 80000000 | 中间提交的事务+++++++++**********++++++++        |
|          3 | 80000000 | 中间提交的事务+++++++++**********++++++++        |
|          4 | 80000000 | 中间提交的事务+++++++++**********++++++++        |
+------------+----------+--------------------------------------------------+
4 rows in set (1.67 sec)

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

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

相关文章

多线程的创建

一、基本概念 1 cpu CPU的中文名称是中央处理器&#xff0c;是进行逻辑运算用的&#xff0c;主要由运算器、控制器、寄存器三部分组成&#xff0c;从字面意思看就是运算就是起着运算的作用&#xff0c;控制器就是负责发出cpu每条指令所需要的信息&#xff0c;寄存器就是保存运…

双系统时间问题、虚拟机扩展空间问题

文献阅读计划&#xff1a; 首先要用ChatGPT查文献&#xff0c;用关键字查询&#xff0c;然后去搜索 add cyun 9.8 但是我发现好难搜啊&#xff0c;或者说相关的关键词搜不出来东西啊。不过师兄倒是搜的挺多的&#xff0c;这一点要再去好好学习一下 双系统时间问题&#xff1a…

LeetCode 50题:实现Pow(x,n)

题目 实现 pow(x, n) &#xff0c;即计算 x 的整数 n 次幂函数&#xff08;即&#xff0c;xn &#xff09;。 示例 1&#xff1a; 输入&#xff1a;x 2.00000, n 10 输出&#xff1a;1024.00000示例 2&#xff1a; 输入&#xff1a;x 2.10000, n 3 输出&#xff1a;9.26…

iPhone苹果手机来电收到消息闪光灯闪烁通知提醒功能怎么开启?

iPhone苹果手机来电收到消息闪光灯闪烁通知提醒功能怎么开启&#xff1f; 1、打开iPhone苹果手机上的「设置」&#xff1b; 2、在苹果iPhone手机设置内找到并点击打开「辅助功能」&#xff1b; 3、在苹果iPhone手机辅助功能内找到并点击打开「音频/视觉」&#xff1b; 4、在苹…

9月11日作业

思维导图 代码 #include <iostream> #include<string.h>using namespace std;class myString { private:char *str; //记录c风格的字符串int size; //记录字符串的实际长度 public://无参构造myString():size(10){str new char[size]; …

js中如何实现字符串去重?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用 Set 数据结构⭐ 使用循环遍历⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感…

RJ45水晶头网线顺序出错排查

线序 网线水晶头RJ45常用的线序标准ANSI / TIA-568定义了T568A与T568B两种线序&#xff0c;一般使用T568B&#xff0c;水晶头8个孔对应的8条线颜色如下图&#xff1a; 那1至8的编号&#xff0c;是从水晶头哪一面为参考呢&#xff0c;如下图&#xff0c;是水晶头金手指一面&am…

基于51单片机+DS1302时钟模块+4位数码管显示

一、DS1302时钟模块简介 二、绘制Proteus 仿真电路图 三、编写51单片机代码 #include "DS1302.h"// 位定义 sbit DS1302_DATA P3^3; sbit SCLK P3^2; sbit RST P3^1;// 向DS1302写一个字节 void DS1302_Write_Byte(unsigned char addrOrData) {unsigned char i;f…

docker安装xxl-job连接数据库时显示无法连接问题

背景&#xff1a; 在项目中需要定时任务调度&#xff0c;需要在docker容器中安装xxl-job 遇到的问题 部署成功后&#xff0c;可以访问xxl-job登录界面&#xff0c;点登录没反应&#xff0c;但过一段时间就弹出数据库拒绝连接&#xff0c;说MyBatis连接用户失败 原因&#xf…

【AIGC专题】Stable Diffusion 从入门到企业级实战0601

一、前言 本章是《Stable Diffusion 从入门到企业级实战》系列的第六部分Prompt专题篇《Stable Diffusion Prompt 专题》第01节 《Stable Diffusion Prompt 通用画风操作实战》。本部分内容&#xff0c;位于整个Stable Diffusion生态体系的位置如下图黄色部分所示&#xff1a;…

C++ Day4

目录 仿照string类&#xff0c;完成myString 类 思维导图 仿照string类&#xff0c;完成myString 类 #include <iostream> #include<cstring>using namespace std;class myString {private:char *str; //记录c风格的字符串int size; //记录…

Mysql数据库之常用SQL语句及事务学习总结

数据库介绍 几个常见的缩写&#xff1a; DB&#xff1a;数据库。全称&#xff1a;DataBase。DBMS&#xff1a;数据库管理系统。全称&#xff1a;DataBase Management System。DBS&#xff1a;数据库系统。全称&#xff1a;DataBase System。DBA&#xff1a;数据库管理员。全称…

Mysql join用法详解

本篇文章旨在详细讲解Mysql 中join的用法&#xff0c;并附上例题。 一. left join 首先附上图 这个查询语句最根本的是要找出A表中所有的行&#xff0c; 所以如图所示&#xff0c;A表整个被涂蓝 A与B交叉的那部分可以视为ON后所跟的条件 重点是&#xff1a; 如果A表中有一条…

基于springboot2+mybatis-plus+jsp增删改查

概述 编写简单增删改查&#xff0c;理解之后可以自己试着扩展&#xff0c;相信你也可以&#xff0c;加油&#xff0c;我自己懂了的用注释记在下面方便理解 详细 一、需求&#xff08;要做什么&#xff09; 基于现今最流行的技术实现增删改查demo&#xff0c; 便于初学者上手…

[学习笔记]PageRank算法

参考资料&#xff1a;改变世界的谷歌PageRank算法 pagerank算法用于计算节点重要度 思想 如果网页被更多的入度(被引用)&#xff0c;则网页更重要。 被重要网站引用比被普通网站引用更加凸显重要性。 所以考虑一个网站是否重要&#xff0c;需要看引用它的网站是否重要&#…

从零开始搭建Apache服务器并使用内网穿透技术实现公网访问

Apache服务安装配置与结合内网穿透实现公网访问 文章目录 Apache服务安装配置与结合内网穿透实现公网访问前言1.Apache服务安装配置1.1 进入官网下载安装包1.2 Apache服务配置 2.安装cpolar内网穿透2.1 注册cpolar账号2.2 下载cpolar客户端 3. 获取远程桌面公网地址3.1 登录cpo…

Vue之scope属性

简介&#xff1a; 在使用Vue脚手架进行开发时&#xff0c;cli编译的时候本质上处理的是一个个文本文件&#xff0c;也就是字符串。每一个组件&#xff0c;即.Vue文件都是一个文本文件&#xff0c;里面包含着模板、组件对象实例以及style样式。组件化开发时&#xff0c;难免会出…

便捷查询中通快递,详细物流信息轻松获取

在如今快节奏的生活中&#xff0c;快递已成为人们生活中不可或缺的一部分。然而&#xff0c;快递查询却常常让人头疼&#xff0c;因为需要分别在不同的快递公司官网上进行查询&#xff0c;耗费时间和精力。为了解决这个问题&#xff0c;固乔科技推出了一款便捷的快递查询助手&a…

03深度学习-目标检测-深度学习方法与传统算法对比

一、目标学习的检测方法变迁及对比 “目标检测“是当前计算机视觉和机器学习领域的研究热点。从Viola-Jones Detector、DPM等冷兵器时代的智慧到当今RCNN、YOLO等深度学习土壤孕育下的GPU暴力美学&#xff0c;整个目标检测的发展可谓是计算机视觉领域的一部浓缩史。整个目标…