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.mzph.cn/news/76176.shtml

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

相关文章

基于Java SSM+layui+mysql实现的图书借记管理系统源代码+数据库

介绍 本项目使用的技术栈是SSMlayuimysql&#xff0c;服务器使用的是tomcat 其中书籍图片存放的位置需要先在tomcat根目录下conf/setting.xml中配置虚拟路径&#xff0c;本项目配置的是D:\upload 完整代码下载地址&#xff1a;图书借记管理系统 用户角色划分 游客 使用本系…

ArcGis地图

1、概述 官网&#xff1a;https://developers.arcgis.com/qt/ 官网&#xff1a;官网指导 官网&#xff1a;Add graphics to a map view 官网&#xff1a;Esri官方博客 官网(github)&#xff1a;https://github.com/Esri Arcgis runtime sdk for Qt 开发记录&#xff08;系列文…

Vue+NodeJS实现邮件发送

一.邮箱配置 这里以QQ邮箱为例,网易邮箱类似. 设置->账号 二.后端服务搭建 index.js const express require(express) const router require(./router); const app express()// 使用路由文件 app.use(/,router);app.listen(3000, () > {console.log(server…

项目上线部署--》网站运行机制

网站运行机制 &#x1f31f;名词解释 域名 DNS 服务器 服务器 &#x1f31f; 网站请求流程 静态页面 动态页面 前后端分离的页面 前后端不分离的页面 &#x1f31f;写在最后 &#x1f31f;名词解释 域名 www.baidu.comwww.taobao.comwww.qq.com 域名俗称网址&#xf…

Linux centos7 bash编程训练__打印各类形状

利用for循环&#xff0c;打印各种不同的三角形、矩形和菱形。 主要是fort循环嵌套使用&#xff0c;及条件判断等。 因方法简单&#xff0c;不作更多解释&#xff0c;部分注释可以帮助初学者掌握代码。 下面列出代码&#xff0c;供参考。 #! /bin/bash ## 打印输出各种*型形…

觉非科技数据闭环系列 | BEV感知研发实践

随着自动驾驶迈向量产场景&#xff0c;“BEV感知数据闭环”已成为新一代自动驾驶量产系统的核心架构。数据成为了至关重要的技术驱动力&#xff0c;发挥数据闭环的飞轮效应或将成为下半场从1到N的胜负关键。 觉非科技在此方面已进行了大量的研究工作&#xff0c;并在实际量产项…

解决nbsp;不生效的问题

代码块 {{title}} title:附 \xa0\xa0\xa0件,//或者 <span v-html"title"></span> title:附 件&#xff1a;,效果图

Elasticsearch近实时架构

1 Elasticsearch 与 Lucene 的结构理解 一个Elasticsearch索引由一个或多个分片&#xff08;shards&#xff09;组成。这些分片可以是主分片&#xff08;primary shard&#xff09;或副本分片&#xff08;replica shard&#xff09;。每个分片都是一个独立的Lucene索引&#xf…

Unity 性能优化Shader分析处理函数:ShaderUtil.GetShaderGlobalKeywords用法

Unity 性能优化Shader分析处理函数&#xff1a;ShaderUtil.GetShaderGlobalKeywords用法 点击封面跳转下载页面 简介 Unity 性能优化Shader分析处理函数&#xff1a;ShaderUtil.GetShaderGlobalKeywords用法 在Unity开发中&#xff0c;性能优化是一个非常重要的方面。一个常见…

修改Tomcat的默认端口号

1、找到Tomcat的安装路径。 2、打开conf文件夹。 3、用记事本打开server.xml文件 4、找到 <Connector port"8080" protocol"HTTP/1.1"&#xff0c;其中的8080就是tomcat的默认端口&#xff0c;将其修改为你需要的端口即可。

github 创建自己的分支 并下载代码

github创建自己的分支 并下载代码 目录概述需求&#xff1a; 设计思路实现思路分析1.进入到master分支&#xff0c;git checkout master;2.master-slave的个人远程仓库3.爬虫调度器4.建立本地分支与个人远程分支之间的联系5.master 拓展实现 参考资料和推荐阅读 Survive by day…

Prometheus 监控指南:如何可靠地记录数字时间序列数据

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f405;&#x1f43e;猫头虎建议程序员必备技术栈一览表&#x1f4d6;&#xff1a; &#x1f6e0;️ 全栈技术 Full Stack: &#x1f4da…

第69步 时间序列建模实战:ARIMA建模(R)

基于WIN10的64位系统演示 一、写在前面 这一期&#xff0c;我们使用R进行SARIMA模型的构建。 同样&#xff0c;这里使用这个数据&#xff1a; 《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemorrhagic Fever with Re…

html的日期选择插件

1.效果 2.文档 https://layui.gitee.io/v2/docs/ 3.引入 官网地址&#xff1a; https://layui.gitee.io/v2/ 引入&#xff08;在官网下载&#xff0c;&#xff09;jquery-1.7.2.min.js,layui/layui.js **<link href"js/layui/css/layui.css" rel"stylesh…

Mysql数据库基础和增删改查操作

一、数据库基本概念 数据&#xff1a;描述事物的符号记录&#xff0c;包括数字&#xff0c;文字、图形、图像、声音、档案记录等&#xff0c;以“记录”形式按统一的格式进行存储。 表&#xff1a;将不同的记录组织在一起用来存储具体数据。 数据库&#xff1a;表的集合&…

10.2 整流电路

在分析整流电路时&#xff0c;为了突出重点&#xff0c;简化分析过程&#xff0c;一般均假定负载为纯电阻性&#xff1b;整流二极管为理想二极管&#xff0c;即导通时正向压降为零&#xff0c;截止时反向电流为零&#xff1b;变压器无损耗&#xff0c;内部压降为零等。 一、整…

java封装国密SM4为 jar包,PHP调用

java封装国密SM4为 jar包,PHP调用 创建java工程引入SM4 jar包封装CMD可调用jar包PHP 传参调用刚用java弄了个class给php调用,本以为项目上用到java封装功能的事情就结束了,没想到又来了java的加密需求,这玩意上头,毕竟不是强项,没办法,只好再次封装。 但是这次的有点不…

thinkPhp5返回某些指定字段

//去除掉密码$db new UserModel();$result $db->field(password,true)->where("username{$params[username]} AND password{$params[password]}")->find(); 或者指定要的字段的数组 $db new UserModel();$result $db->field([username,create_time…

总结986

时间记录&#xff1a; 7:10起床 8:00~下午2:00课程设计&#xff0c;偷学了3小时 2:17~3:55午觉 4:10~5:30计网 5:35~6:41数据结构 7:00~7:22继续数据结构课后习题重做 7:23~8:07考研政治&#xff0c;做题20道纠错 8:15~8:39每日长难句 8:39~10:21 14年tex2纠错标记 1…

【算法训练-数组 四】【合并】:合并两个有序数组

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【数组合并】&#xff0c;使用【数组】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…