MySQL 日志之 binlog 格式 → 关于 MySQL 默认隔离级别的探讨

news2024/9/22 17:38:35

背景问题

再讲 binlog 之前,我们先来回顾下主流关系型数据库的默认隔离级别,是默认隔离级别,不是事务有哪几种隔离级别,别会错题意了

1、Oracle、SQL Server 的默认隔离级别是什么,MySQL 的呢 ?

2、为什么 MySQL 的默认隔离级别是 RR ?

这个问题其实不太严谨,我们知道 MySQL 5.5 才将 InnoDB 代替 MyISAM 成为 MySQL 默认的存储引擎,而事务才有隔离级别一说,MyISAM 本就不支持事务,那么这个问题在 MySQL 5.5 之前根本就不成立。

严谨点来说,应该是:为什么 MySQL 5.5 及之后版本的事务默认隔离级别是 RR,或者是:为什么 InnoDB 的事务默认隔离级别是 RR

对于问题1,我相信大家都能回答的上来,Oracle,SqlServer 的默认隔离级别是 读已提交(Read Commited,简称 RC) ,而 MySQL 的默认隔离级别是 可重复读(Repeatable Read,简称 RR)

但是对于问题2,相信有很多小伙伴就会支支吾吾了:呃...,这个...,昂昂昂昂昂,太久了我记忆都不太好了...

调皮的小伙伴可能就开始岔开话题了:你讲 binlog 就讲 binlog 啦,扯什么默认隔离级别,难道 MySQL 的默认隔离级别还与 binlog 有关 ?

具体它俩是不是有关,楼主也不知道,我们一起往下看

binlog 格式

binlog 全称:binary log,即二进制日志,有时候也称归档日志,记录了对 MySQL 数据库执行了更改的所有操作,包括表结构变更(CREATE、ALTER、DROP TABLE…)、表数据修改(INSERT、UPDATE、DELETE...),但不包括 SELECT 和 SHOW 这类操作,因为这类操作对数据本身并没有修改;若更改操作并未导致数据库变化,那么该操作也会写入 binlog,例如

此时的:update tbl_t1 set name = 'lisi' where name = '123'; 并未引起数据库的变化,但还是被记录到了 binlog 中

binlog 的格式有三种:STATEMENT、ROW、MIXED,一开始只有 STATEMENT,后面慢慢衍生出了 ROW、MIXED

MySQL 5.1.5 之前 binlog 的格式只有 STATEMENT,5.1.5 开始支持 ROW 格式的 binlog,从 5.1.8 版本开始,MySQL 开始支持 MIXED 格式的 binlog

MySQL 5.7.7 之前,binlog 的默认格式都是 STATEMENT,在 5.7.7 及更高版本中,binlog_format 的默认值才是 ROW

三种格式的 binlog 各长什么样,它们有什么区别,各有什么优劣,我们往下看

STATEMENT

从 MySQL 第一个版本,到目前最新的 8.0.x,STATEMENT 一直坚挺在 binlog 的格式中,只是从 5.7.7 开始,它退居幕后,头把交椅给了 ROW

binglog 与我们开发中的代码日志是不一样的,它包含两类文件

索引文件:文件名.index,记录了哪些日志文件正在被使用,内容如下

编辑

添加图片注释,不超过 140 字(可选)

日志文件:文件名.00000*

编辑

添加图片注释,不超过 140 字(可选)

记录了对 MySQL 数据库执行了更改的所有操作

因为 binlog 的日志文件是二进制文件,不能用文本编辑器直接打开,需要用特定的工具来打开,MySQL 提供了 mysqlbinlog 来帮助我们查看日志文件内容

mysqlbinlog 可选参数很多, mysqlbinlog.exe --help

 
 

mysqlbinlog.exe Ver 3.3 for Win64 at x86 Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Dumps a MySQL binary log in a format usable for viewing or for piping to the mysql command line client. Usage: mysqlbinlog.exe [options] log-files -?, --help Display this help and exit. --base64-output[=name] Determine when the output statements should be base64-encoded BINLOG statements: 'never' disables it and works only for binlogs without row-based events; 'decode-rows' decodes row events into commented SQL statements if the --verbose option is also given; 'auto' prints base64 only when necessary (i.e., for row-based events and format description events); 'always' prints base64 whenever possible. 'always' is deprecated, will be removed in a future version, and should not be used in a production system. --base64-output with no 'name' argument is equivalent to --base64-output=always and is also deprecated. If no --base64-output[=name] option is given at all, the default is 'auto'. --character-sets-dir=name Directory for character set files. -d, --database=name List entries for just this database (local log only). --debug-check Check memory and open file usage at exit . --debug-info Print some debug info at exit. -D, --disable-log-bin Disable binary log. This is useful, if you enabled --to-last-log and are sending the output to the same MySQL server. This way you could avoid an endless loop. You would also like to use it when restoring after a crash to avoid duplication of the statements you already have. NOTE: you will need a SUPER privilege to use this option. -F, --force-if-open Force if binlog was not closed properly. (Defaults to on; use --skip-force-if-open to disable.) -f, --force-read Force reading unknown binlog events. -H, --hexdump Augment output with hexadecimal and ASCII event dump. -h, --host=name Get the binlog from server. -l, --local-load=name Prepare local temporary files for LOAD DATA INFILE in the specified directory. -o, --offset=# Skip the first N entries. -p, --password[=name] Password to connect to remote server. -P, --port=# Port number to use for connection or 0 for default to, in order of preference, my.cnf, $MYSQL_TCP_PORT, /etc/services, built-in default (3306). --protocol=name The protocol to use for connection (tcp, socket, pipe, memory). -R, --read-from-remote-server Read binary logs from a MySQL server. -r, --result-file=name Direct output to a given file. --server-id=# Extract only binlog entries created by the server having the given id. --set-charset=name Add 'SET NAMES character_set' to the output. --shared-memory-base-name=name Base name of shared memory. -s, --short-form Just show regular queries: no extra info and no row-based events. This is for testing only, and should not be used in production systems. If you want to suppress base64-output, consider using --base64-output=never instead. -S, --socket=name The socket file to use for connection. --start-datetime=name Start reading the binlog at first event having a datetime equal or posterior to the argument; the argument must be a date and time in the local time zone, in any format accepted by the MySQL server for DATETIME and TIMESTAMP types, for example: 2004-12-25 11:25:56 (you should probably use quotes for your shell to set it properly). -j, --start-position=# Start reading the binlog at position N. Applies to the first binlog passed on the command line. --stop-datetime=name Stop reading the binlog at first event having a datetime equal or posterior to the argument; the argument must be a date and time in the local time zone, in any format accepted by the MySQL server for DATETIME and TIMESTAMP types, for example: 2004-12-25 11:25:56 (you should probably use quotes for your shell to set it properly). --stop-position=# Stop reading the binlog at position N. Applies to the last binlog passed on the command line. -t, --to-last-log Requires -R. Will not stop at the end of the requested binlog but rather continue printing until the end of the last binlog of the MySQL server. If you send the output to the same MySQL server, that may lead to an endless loop. -u, --user=name Connect to the remote server as username. -v, --verbose Reconstruct SQL statements out of row events. -v -v adds comments on column data types. -V, --version Print version and exit. --open-files-limit=# Used to reserve file descriptors for use by this program. Variables (--variable-name=value) and boolean options {FALSE|TRUE} Value (after reading options) --------------------------------- ---------------------------------------- base64-output (No default value) character-sets-dir (No default value) database (No default value) debug-check FALSE debug-info FALSE disable-log-bin FALSE force-if-open TRUE force-read FALSE hexdump FALSE host (No default value) local-load (No default value) offset 0 port 3307 read-from-remote-server FALSE server-id 0 set-charset (No default value) shared-memory-base-name (No default value) short-form FALSE socket E:/soft/mysql5.5.8/tmp/mysql.sock start-datetime (No default value) start-position 4 stop-datetime (No default value) stop-position 18446744073709551615 to-last-log FALSE user (No default value) open-files-limit 18432

这些参数不做细讲,有兴趣的可自行去查阅,我们重点来关注日志文件的内容,执行 mysqlbinlog.exe ../data/mysql-bin.000004

可以看到,对数据库执行了更改的操作

编辑

添加图片注释,不超过 140 字(可选)

都是以明文形式的 SQL 记录在日志文件中,至于优缺点,我们看完另外两种格式之后再来比较

ROW

MySQL 5.7.7 及之后版本,binlog 的默认格式是 ROW,我们基于 5.7.30 版本,来看下 ROW 格式 binlog 内容是怎样的

先产生数据库更改操作

更改操作有

编辑切换为居中

添加图片注释,不超过 140 字(可选)

master 当前正在写入的 binlog 文件: mysql-bin.000002 , position 从 2885 到 3929

接下来我们看下日志文件中是怎么记录的,执行 mysqlbinlog.exe --start-position=2885 --stop-position=3929 ../data/mysql-bin.000002

可以看到,表结构变更操作以明文形式的 SQL 记录在日志文件中(与 STATEMENT 一样),但表数据变更的操作却是以一坨一坨的密文形式记录在日志文件中,不便于我们阅读

庆幸的是,mysqlbinlog 提供参数 -v 或 -vv 来解密查看,执行 mysqlbinlog.exe --base64-output=decode-rows -v --start-position=2885 --stop-position=3929 ../data/mysql-bin.000002

INSERT 没什么好注意的,每一列都插入对应的值

编辑

添加图片注释,不超过 140 字(可选)

UPDATE 就有需要注意的了,虽然我们修改列只有一列,条件列也只有一列,但是日志中记录的却是:修改列是全部列,条件列也是全部列,并且列值是具体的值,而没有 NOW()、UUID() 这样的函数

编辑

添加图片注释,不超过 140 字(可选)

表没有明确的指定主键,满足更新条件的记录也只有一条,大家可以去试试:明确指定主键且满足更新条件的记录有多条的情况,看看 binlog 日志是怎么记录的

DELETE 与 UPDATE 一样,虽说条件列只有一个,但日志中记录的确实全部列

编辑

添加图片注释,不超过 140 字(可选)

相较 STATEMENT,显得更复杂,内容会多很多, 具体 ROW 有什么优点,我们往下看

MIXED

字面意思:混合,那它混合谁? 还能混合谁?智能混合 STATEMENT 和 ROW

大多数情况下,是以 STATEMENT 格式记录 binlog 日志(因为 MySQL 默认隔离级别是 RR,而又很少有人去修改默认隔离级别),当隔离级别为 RC 模式的时候,则修改为 ROW 模式记录

有些特殊场景,也是以 ROW 格式来记录的,就不区分 RR 和 RC 了

编辑切换为居中

添加图片注释,不超过 140 字(可选)

当然还有一个 NOW() ,说白了就是,只有具体的值才最可靠,其他依赖于上下文、环境的函数、系统变量都不可靠,因为它们会因上下文、环境而变化

这个就不去展示具体的日志内容了,有兴趣的小伙伴自行去跑结果

优缺点总结

三种格式都已介绍完毕,相比之下,相信大家对它们各自的特点、优缺点已经有一定的了解了

基于 binlog 的用途之一:主从复制(三个用途:主从复制、数据恢复、审计), 楼主给大家总结下它们的优缺点

编辑切换为居中

添加图片注释,不超过 140 字(可选)

MIXED 的愿景是好的:结合 STATEMENT 和 ROW 两者的优点,产生一个完美的格式,但事与愿违,它还是会有一些问题

相比于准确性而言,性能优先级会低一些(随着技术的发展,硬件性能已不再是不可接受的瓶颈),所以推荐使用 ROW 格式

MySQL 的 binlog 与其默认隔离级别 RR 的关系

从上面 binlog 格式的内容来看,似乎与默认隔离级别 RR 没有半毛钱关系,先莫急,慢慢往下看

RC,STATEMENT 下,各版 MySQL 执行表数据修改操作

表引擎是 InnoDB,隔离级别是 RC,binlog_format=STATEMENT的统一前提下,我们分别看下 MySQl5.0.96、MySQL5.1.30、MySQL5.5.8、MySQL5.7.30 执行表数据更改操作的情况

MySQl5.0.96 可以正常执行

MySQL5.1.30 执行报错,提示

 
 

ERROR 1598 (HY000): Binary logging not possible. Message: Transaction level 'READ-COMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT'

    MySQL5.5.8、MySQL5.7.30 执行报错,都提示

 
 

ERROR 1665 (HY000): Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.

也就是说,MySQL5.1.30及之后,RC 隔离级别的 InnoDB 对 binlog_format 是有限制的,不能是 STATEMENT,否则表数据无法进行修改

MySQL 4.x 系列,由于官方不提供下载了,没法做测试,有 4.x 版本(或者5.1.21之前的5.1.x版本)的可以私信下我哦,不胜感激!

不同 session 的操作记录在 binlog 中的记录顺序

我们用两个 session 来执行更新操作,看下不同 session 的操作记录在 binlog 中的记录顺序有什么决定

可以看到 update tbl_rr_test set age = 20 where id = 1; 先执行,后 commit, update tbl_rr_test set age = 21 where id = 2; 后执行,先 commit,日志中记录的是:先commit的记录在前面,后commit的记录在后面,与执行时间点无关;就单个 session 来说,好理解,执行顺序就是记录顺序;多个 session 之间的话,先 commit 得先记录

主库对数据库的更改是按执行时间的先后顺序进行的,而 binlog 却是按 commit 的先后顺序记录的,理论上来说就会出现 MySQL Bug23051 中的示例问题

默认隔离级别 RR 与 binlog 的关系

我们来看看 MySQL Bug23051,里面有说到,MySQL 5.1 的早期版本,隔离级别是 RC、binlog 格式是STATEMENT时,InnoDB 的主从复制是有 bug 的(5.1.21 中修复),而 5.0.x 是没问题的,我们在 5.0.96 上跑下 Bug23051 中的例子

可以看到,5.0.96 下的 InnoDB,在 RC 级别,binlog_format=STATEMENT 时, UPDATE t1 SET a=11 where b=2; 的事务未提交,则 UPDATE t1 SET b=2 where b=1; 的事务会被阻塞,那么从库复制的时候,数据是没问题的

所以,综合前面的来看,从 MySQL5.0 开始,InnoDB 在 RC 级别,binlog_format=STATEMENT 时 主从复制是没有 bug 的(5.0没问题,5.1.21之前的5.1.x有问题,但官方不提供下载了,5.1.21及之后的版本不支持 RC 隔离级别下设置 binlog 为 STATEMENT)

那么 binlog 与 默认级别 RR 的关系就清楚了,就是烟哥在【原创】互联网项目中mysql应该选什么事务隔离级别中说的这段话:

 
 

那Mysql在5.0这个版本以前,binlog只支持STATEMENT这种格式!而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!

也就是说,在 MySQL5.0之前,将 RR 作为默认隔离级别,是为了规避大部分主从复制的bug,然后一直被沿用了下来而已;为什么不是规避全部的主从复制 bug,因为在 RR 隔离级别、binlog_format=STATEMENT 下,使用系统函数(NOW()、UUID()等)时,还是会导致主从数据不一致

总结

1、binlog 三个格式

目前主流的 MySQL,binlog 格式有 3 种:STATEMENT、ROW、MIXED,从数据准确性考虑,推荐使用 ROW 格式

2、binlog 默认格式

MySQL 5.1.5 之前只支持 STATEMENT 格式的 binlog,5.1.5 开始支持 binlog_format=ROW,MySQL 5.7.7 之前,binlog 的默认格式都是 STATEMENT,在 5.7.7 及更高版本中,binlog_format的默认值才是 ROW

3、主从复制 bug(InnoDB 引擎)

MySQL 5.1.30及之后,InnoDB 下,开启 RC 隔离级别的话是不能启用 binlog_format=STATEMENT的

RC、RR 隔离级别,binlog_format=MIXED,主从复制仍会有数据不一致的问题(受系统函数影响)

RR 隔离级别,binlog_format=STATEMENT,主从复制仍会有数据不一致的问题(受系统函数影响)

binlog_format=ROW,不管是 RC 隔离级别,还是 RR 隔离级别,主从复制不会有数据不一致的问题

4、MySQL 为什么默认隔离级别是 RR

为了规避 MySQL5.0 以前版本的主从复制问题,然后一直被沿用了下来而已

5、引擎选择问题

MySQL 5.6 及之后,InnoDB 做了大量的优化,性能并不比MyISAM低,说没特别的理由,基本可以放弃 MyISAM 了

                                         资源获取:

大家点赞、收藏、关注、评论啦 、查看👇🏻👇🏻👇🏻微信公众号获取联系方式👇🏻👇🏻👇🏻

 精彩专栏推荐订阅:下方专栏👇🏻👇🏻👇🏻👇🏻

每天学四小时:Java+Spring+JVM+分布式高并发,架构师指日可待

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

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

相关文章

基于C#+SQL Server2008 开发三层架构(WinForm)图书管理系统【100010014】

图书管理系统 一、项目背景及意义 当今由于信息技术的飞速发展,图书馆作为社会知识信息媒介的功能日益重要,网络环境下的信息资源建设知识仓库的设计,开放存取学术交流模式,知识管理系统,智能检索,数字参…

SDE论文阅读

论文链接:Score-Based Generative Modeling through Stochastic Differential Equations 文章目录摘要引文背景基于郎之动力学的去噪分数匹配/SMLD去噪扩散概率模型/DDPMSDEs的基于分数的生成模型SDEs下的受扰动数据逆转SDE生成样本估计SDE的分数例子:VE…

spring——Spring自动装配——示例

1. 不使用自动装配(autowire"no") autowire"no" 表示不使用自动装配&#xff0c;此时我们必须通过 <bean> 元素的 <constructor-arg>和 <property> 元素的 ref 属性维护 Bean 的依赖关系。 2. 按名称自动装配(autowire"byName"…

【Qt入门第38篇】 网络(八)TCP(二)

导语 在上一节里我们使用TCP服务器发送一个字符串&#xff0c;然后在TCP客户端进行接收。在这一节将重新写一个客户端程序和一个服务器程序&#xff0c;这次实现客户端进行文件的发送&#xff0c;服务器进行文件的接收。有了上一节的基础&#xff0c;这一节的内容就很好理解了…

“为什么同样是跳槽,有些人薪资就能翻两三倍?“Java面试八股文是背错了方向吗?

“为什么同样是跳槽&#xff0c;有些人薪资能翻两三倍&#xff1f;” 最近遇到一个朋友跟我吐槽如上&#xff0c;其实类似这样的问题我也听到过很多次&#xff0c;身边也不乏有认识的同事、朋友们通过跳槽拿下高薪&#xff0c;这里我先说一个我身边真实的例子&#xff1a; 学…

智能家居服务发现实现

服务设备软件架构设计 代码复用 将网络通信框架移植到开发板&#xff0c;之后&#xff0c;可以使用框架中的组件实现 Response Task 和 Service Task。 框架移植注意事项 LWIP 是微型 TCP/IP 协议栈 (并非完整 TCP/IP 协议栈) 支持 socket 接口&#xff0c;但一些功能未实现…

面向对象编程的一个例子——减少代码重复

专注系列化、高质量的R语言教程推文索引 | 联系小编 | 付费合集本篇推文缘起于上篇推文plot3D | 三维数据绘图&#xff08;3&#xff09;&#xff1a;mesh函数、surf3D函数、spheresurf3D函数。学堂君在介绍surf3D()函数时举了两个例子。第一个例子是绘制球形&#xff1a;libra…

contains shards using both inmem and tsi1 indexes. 重构索引 influx

问题&#xff1a; 删除infludx表measurement时出错 参考: 记一次influxdb内存高耗的追踪 - 墨天轮 influxdb删除错误DB contains shards using both inmem and tsi1 indexes._宇宙全能王的博客-CSDN博客_influxdb删除shard Rebuild the TSI index | InfluxDB OSS 1.8 Docume…

【PCB专题】芯片比较大的焊盘,开钢网时都要设计成不同数量的小格吗?

大面积焊盘&#xff08;EPAD&#xff09;必须开栅格或线条孔&#xff0c;避免焊膏印刷时刮薄或焊接时把元件托起&#xff0c;使其他引脚开焊。这种开钢网的方法&#xff0c;多用于QFN封装和无线模块。比如非接芯片、电源芯片、语音功放、Modem芯片等需要加强散热的器件&#xf…

python之标准库使用

目录 一、标准库 二、字符串操作 三、字符串类型 四、 时间操作 五、文件基本方法及操作 文件基本方法 文件操作 一、标准库 Python 标准库非常庞大&#xff0c;所提供的组件涉及范围十分广泛&#xff0c;正如以下内容目录所显示的。这个库包含了 Python中的图标含义 c…

游戏开发44课 性能优化3

2.4 模型 模型特别是带有骨骼动画的模型在性能消耗中占据非常大的比重&#xff0c;它们会显著增加CPU/GPU/内存/显存的负担。所以&#xff0c;模型的优化尤为重要。模型涉及的数据比较多&#xff0c;包含了顶点/索引/材质等&#xff0c;而顶点又可能包含pos/color/uv/normal/t…

【Docker】Docker是什么?Docker从介绍到Linux安装图文详细教程

本期目录1. Docker介绍1.1 Docker解决的问题2. Docker和虚拟机的区别2.1 虚拟机的缺点2.2 Docker的优点2.3 比较3. Docker架构3.1 镜像和容器1&#xff09;镜像2&#xff09;容器3.2 Docker和DockerHub3.3 整体结构及底层通信原理4. 安装Docker4.1 安装条件4.2 卸载旧版本4.3 y…

【Windows环境下载安装MySQL、IDEA连接数据库】

MySQL安装配置一、Windows环境下载安装MySQL1.下载合适的MySQL安装包2.本地安装配置MySQL二、IDEA连接MySQL数据库1.设置数据库连接2.测试连接3.连接结果一、Windows环境下载安装MySQL 1.下载合适的MySQL安装包 官网链接https://www.mysql.com/&#xff0c;选择合适的版本&am…

JVM方法区的内部结构

JVM 中方法区的大致区域浏览图&#xff1a; 《深入理解 Java 虚拟机》书中对方法区&#xff08; Method Area) 存储内容描述如下&#xff1a;它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码缓存等。 类型信息 对每个加载的类型&#xff08;类 cla…

chatGPT 辣么火,你却不会注册

chatGPT 是什么&#xff1f; 一款目前超级火的 AI 对话聊天工具&#xff0c;只是不同于其他的智能聊天机器人那样&#xff0c;他非常的智能。 可以回答你的技术问题、帮你写代码、还能帮你写小说等等&#xff0c;发挥你的想象力&#xff0c;让他干点啥都行。 比如让他帮你用…

Spring循环依赖问题分析

文章目录一、什么是循环依赖&#xff1f;二、Spring内部解决的是那种情况下的循环依赖&#xff1f;三、一级、二级、三级缓存保存的是什么&#xff1f;四、如何使用三级缓存解决循环依赖&#xff1f;五、为什么是三级缓存&#xff0c;二级缓存不行么&#xff1f;六、二级缓存的…

小米AX6S刷OpenWrt,和刷回官网固件

文章目录背景刷成 OpenWrt刷回官网固件Ref简 述: 闲暇&#xff0c;折腾下新购 小米AX6S &#xff0c;刷下 OpenWrt&#xff0c;初次接触记录下。 本文初发于 “偕臧的小站”&#xff0c;同步转载于此。 背景 miwifi_rb03_firmware_3e872_1.0.54.bin [官方 2022.08.24] miwifi_r…

17. 权重衰退(weight_decay)

之前描述了过拟合的问题&#xff0c;现在介绍一些正则化模型的技术。 正则化&#xff1a;凡事可以减少泛化误差而不是减少训练误差的方法&#xff0c;都可以称作正则化方法。 我们总是可以通过去收集更多的训练数据来缓解过拟合。 但这可能成本很高&#xff0c;耗时颇多&#x…

【OpenCV-Python】教程:4-7 BRIEF( Binary Robust Independent Elementary Features)特征

OpenCV Python BRIEF &#xff08; Binary Robust Independent Elementary Features&#xff09; 【目标】 学习 BRIEF 算法理论 【理论】 我们知道SIFT使用128维向量作为描述符。因为它使用的是浮点数&#xff0c;所以需要512字节。类似地&#xff0c;SURF也需要最少256字…

堪称零瑕疵!仅用了365页直接封神,我要吹爆这份RocketMQ笔记

RocketMQ 是阿里巴巴在2012年开源的分布式消息中间件&#xff0c;作为经历过多次阿里巴巴双十一这种“超级工程”的洗礼并有稳定出色表现的国产中间件&#xff0c;以其高性能、低延时和高可靠等特性近年来已经也被越来越多的国内企业使用。 谁使用ApacheRocketMQ&#xff1f; …