吃透3大Binlog模式,MySQL数据零丢失
nanshan 2024-12-02 23:29 13 浏览 0 评论
用错 Binlog 模式,可能导致 MySQL 的数据不一致性、性能下降、存储空间浪费和数据恢复困难等问题。
在 MySQL 中,不管使用什么存储引擎,只要表数据更新,就会产生 Binlog(归档日志)。
而 MySQL 数据库的数据备份、主备、主主、主从等实现,也离不开 Binlog(归档日志)。
针对不同的应用场景,Binlog 推出了三种工作模式 Statement、Row、Mixed,以满足对数据库的需求。
大家好,我是宝妹儿。
今天我们就来深入 Binlog 的三种模式,包括它的原理、优缺点、适用场景、配置管理、切换方式等。
这也是 MySQL 的重要知识点及高频面试点,宝妹儿顺便将这个题目以及答案,整理到2023版《MySQL 大厂高频面试题大全》PDF了,方便系统学习、面试通关。
宝妹儿精编的2023版《MySQL 大厂高频面试题大全》,已收录100+道真题,近30000字,长期迭代、持续更新。吃透它,应付MySQL面试没问题。
公众号Java面试题宝,自取。
1. Binlog 概述
在 MySQL 中,Binlog 是一种二进制形式记录的日志文件,用于记录数据库的修改操作,包括插入、更新和删除等。
Binlog 的两个主要作用:
- 数据恢复:如果 MySQL 意外停止,可以通过该日志进行恢复、备份;
- 数据复制:master 把它的二进制日志传递给 slaves ,从而实现 master-slove 数据的一致性。
2. Binlog 的三种工作模式
Binlog 的三种工作模式分别是:Statement、Row、Mixed。
2.1 Statement 模式
Statement 模式的概念
Statement 是基于语句的复制模式。
Statement 模式将数据库中执行的修改操作记录为 SQL 语句,再从数据库上执行相同的 SQL 语句来实现数据同步。
Statement 模式的优缺点
Statement 模式的优点是简单明了,易于理解和实现。
但是,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 命令,从库删除过多数据。
Statement 模式的应用场景
Statement 模式适用于大多数情况下的数据库复制需求。
例如:
1)一次更新大量数据,如二十万数据。反之,在复制时,从库可能会追得太慢,然后导致延时;
2)使用 pt-table-checksum 工具时。
示例一:
update这个事物的开始是insert这个事物结束的点at1581;
update结束的点是commit之后的点at1842;
[root@Darren2 logs]# MySQLBinlog --start-position=1581 --stop-position=1842 MySQL-bin.000022;
......
BEGIN
/*!*/;
# at 1729
#170408 14:40:49 server id 330622 end_log_pos 1841 CRC32 0xb443cf1e Query thread_id=55 exec_time=0 error_code=0
use `testdb`/*!*/;
SET TIMESTAMP=1491633649/*!*/;
update t10 set c2='bbb' where c1=1
/*!*/;
# at 1841
#170408 14:40:49 server id 330622 end_log_pos 1872 CRC32 0xd06c40f5 Xid = 1756
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by MySQLBinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
示例二:
当查看commit之前的position点时,会看到rollback状态,说明这个截取的事物不完整:
[root@Darren2 logs]# MySQLBinlog --start-position=1581 --stop-position=1841 MySQL-bin.000022;
BEGIN
/*!*/;
# at 1729
#170408 14:40:49 server id 330622 end_log_pos 1841 CRC32 0xb443cf1e Query thread_id=55 exec_time=0 error_code=0
use `testdb`/*!*/;
SET TIMESTAMP=1491633649/*!*/;
update t10 set c2='bbb' where c1=1
/*!*/;
ROLLBACK /* added by MySQLBinlog */ /*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by MySQLBinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
2.2 Row 模式
Row 模式的概念
MySQL 5.7 默认的日志模式为 Row。
Row 模式是基于行的复制模式,它将数据库中实际修改的行记录写入 Binlog ,从数据库通过解析 Binlog 来逐行执行相应的修改操作。
相对 statement ,Row 模式更加精确、安全,能够确保数据的一致性。
Row 模式的优缺点
Row 模式的优点是能够准确复制修改的行记录,避免了语句复制模式下的不确定性问题。
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 修改的语句可以看到历史旧数据。
示例:
开启Binlog_rows_query_log_events参数,会显示执行的SQL语句,这个参数默认关闭,不显示执行的SQL
root@localhost [testdb]>set Binlog_rows_query_log_events=on;
[root@Darren2 logs]# MySQLBinlog -vv --base64-output=decode-rows MySQL-bin.000024
......
create table t10(c1 int,c2 varchar(50))
# insert into t10 values(1,now())
### INSERT INTO `testdb`.`t10`
### SET
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
### @2='2017-04-08 15:26:09' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
# insert into t10 values(2,now())
### INSERT INTO `testdb`.`t10`
### SET
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
### @2='2017-04-08 15:26:09' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
# at 1033
# insert into t10 values(3,sysdate())
### INSERT INTO `testdb`.`t10`
### SET
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
### @2='2017-04-08 15:26:09' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
# insert into t10 values(4,uuid())
### INSERT INTO `testdb`.`t10`
### SET
### @1=4 /* INT meta=0 nullable=1 is_null=0 */
### @2='a2b570b8-1c2c-11e7-bc58-000c29c1b8a9' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
# update t10 set c2='bbb' where c1=1
### UPDATE `testdb`.`t10`
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
### @2='2017-04-08 15:26:09' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
### SET
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
### @2='bbb' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
Row 模式的应用场景
Row 模式适用于对数据一致性要求较高的场景,特别是涉及一些复杂的数据库操作和业务逻辑。
例如,涉及触发器、存储过程和函数等的数据库操作。
使用Row 模式时需注意,Row 模式可能导致 Binlog 文件较大,需要合理设置 Binlog 文件大小和保留时间。
3.3 Mixed 模式
Mixed 模式的概念
Mixed 模式(混合模式)是将语句复制模式和行复制模式结合起来使用。
大多数的修改操作,通常使用 Statement 模式记录对应的 SQL 语句。
一些特殊的操作,涉及非确定性函数和存储过程等,则使用 Row 模式记录修改的行记录。
Mixed 模式的优缺点
Mixed 模式综合了语句复制模式和行复制模式的优点,能够在大多数情况下高效地记录修改操作,并在需要时使用行复制模式确保数据的准确性。
但是 Mixed 模式对一些特殊操作的处理可能会很复杂,特别需要注意下配置和管理。
总结:
1)innodb 引擎,如果隔离级别是 RU、RC,则 Mixed 模式会转成 Row 模式存储。
示例:
set tx_isolation='read-committed';
set Binlog_format='mixed';
flush logs;
create table t10(c1 int,c2 varchar(50));
insert into t10 values(1,now());
insert into t10 values(2,now());
insert into t10 values(3,sysdate());
insert into t10 values(4,uuid());
update t10 set c2='bbb' where c1=1;
[root@Darren2 logs]# MySQLBinlog -vv --base64-output=decode-rows MySQL-bin.000028
......
### UPDATE `testdb`.`t10`
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
### @2='2017-04-08 18:34:08' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
### SET
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
### @2='bbb' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
......
2)在以下几种情况下,Mixed 模式会自动将 Binlog 的模式 SBR 转化成 RBR 模式:
- 当更新一个 NDB 表时;
- 当函数包含 uuid() 函数时;
- 2个及以上包含 auto_increment 字段的表被更新时;
- 视图中必须要求使用 RBR 时。
示例:
set tx_isolation='repeatable-read';
set Binlog_format='mixed';
flush logs;
create table t10(c1 int,c2 varchar(50));
insert into t10 values(1,now());
insert into t10 values(2,now());
insert into t10 values(3,sysdate());
insert into t10 values(4,uuid());
update t10 set c2='bbb' where c1=1;
[root@Darren2 logs]# MySQLBinlog MySQL-bin.000029
......
update t10 set c2='bbb' where c1=1
......
Mixed 模式的应用场景
Mixed 模式适用于大多数情况下的数据库复制需求,尤其适合需要兼顾效率和准确性的场景。
在使用 Mixed 模式时,需要注意对特殊操作进行测试和验证,确保数据的一致性和正确性。
4. 如何查看、配置 Binlog 模式
查看 Binlog 模式
MySQL> show global variables like "%Binlog_format%";
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| Binlog_format | STATEMENT |
+---------------+-----------+
配置 Binlog 模式
vim my.cnf,在 MySQLd 模块中配置。
log-bin = /data/3306/MySQL-bin
Binlog_format="STATEMENT"
#Binlog_format="ROW"
#Binlog_format="MIXED"
不重启,使配置在 MySQL 中生效。
SET global Binlog_format='STATEMENT';
4. Binlog 模式的切换方法
4.1 修改配置文件
可以通过修改 MySQL 的配置文件来切换 Binlog 模式。
编辑 MySQL 的配置文件(通常是 my.cnf 或 my.ini ),找到 Binlog_format 参数,并将其设置为所需的模式。
Binlog_format = ROW
然后重新启动 MySQL 服务,使新的 Binlog 模式生效。
4.2 使用 SQL 语句切换
另一种切换 Binlog 模式的方法,是通过执行 SQL 语句来修改 Binlog_format 参数。
SET GLOBAL Binlog_format = 'ROW';
这会立即将 Binlog 模式切换为指定的模式。
这种修改在 MySQL 服务重启后会失效,因此需要在重启前进行相应的配置修改。
4.3 动态切换
MySQL 5.6 版本及以上提供了动态切换 Binlog 模式的功能,可以在不重启 MySQL 服务的情况下进行切换。
SET SESSION Binlog_format = 'ROW';
这将在当前会话中将 Binlog 模式切换为指定的模式
动态切换只对当前会话有效,不会影响其他会话或 MySQL 服务重启后的配置。
总结
通过本文,我们学习并掌握了 Binlog 三种模式 Statement、Row、Mixed,包括它们的特点、优缺点、应用场景、配置、切换等。
选型参考思路:
- 使用 MySQL 特殊功能较少,例如存储过程、触发器、函数等,用 Statement 模式。
- 使用 MySQL 特殊功能较多,用 Mixed 模式。
- 使用 MySQL 特殊功能较多,同时希望数据最大化一致,用 Row 模式。
在实际应用场景中,还是要结合具体情况来合理选择。
如果觉得有用,请顺手【点赞】支持下哦,这将是对宝妹儿的最大鼓励,谢谢~
最后
本文收录于宝妹儿精编的 2023版《MySQL 大厂高频面试题大全》PDF。
搞定这100道题,足以应对MySQL面试。
相关推荐
- 0722-6.2.0-如何在RedHat7.2使用rpm安装CDH(无CM)
-
文档编写目的在前面的文档中,介绍了在有CM和无CM两种情况下使用rpm方式安装CDH5.10.0,本文档将介绍如何在无CM的情况下使用rpm方式安装CDH6.2.0,与之前安装C5进行对比。环境介绍:...
- ARM64 平台基于 openEuler + iSula 环境部署 Kubernetes
-
为什么要在arm64平台上部署Kubernetes,而且还是鲲鹏920的架构。说来话长。。。此处省略5000字。介绍下系统信息;o架构:鲲鹏920(Kunpeng920)oOS:ope...
- 生产环境starrocks 3.1存算一体集群部署
-
集群规划FE:节点主要负责元数据管理、客户端连接管理、查询计划和查询调度。>3节点。BE:节点负责数据存储和SQL执行。>3节点。CN:无存储功能能的BE。环境准备CPU检查JDK...
- 在CentOS上添加swap虚拟内存并设置优先级
-
现如今很多云服务器都会自己配置好虚拟内存,当然也有很多没有配置虚拟内存的,虚拟内存可以让我们的低配服务器使用更多的内存,可以减少很多硬件成本,比如我们运行很多服务的时候,内存常常会满,当配置了虚拟内存...
- 国产深度(deepin)操作系统优化指南
-
1.升级内核随着deepin版本的更新,会自动升级系统内核,但是我们依旧可以通过命令行手动升级内核,以获取更好的性能和更多的硬件支持。具体操作:-添加PPAs使用以下命令添加PPAs:```...
- postgresql-15.4 多节点主从(读写分离)
-
1、下载软件[root@TX-CN-PostgreSQL01-252software]#wgethttps://ftp.postgresql.org/pub/source/v15.4/postg...
- Docker 容器 Java 服务内存与 GC 优化实施方案
-
一、设置Docker容器内存限制(生产环境建议)1.查看宿主机可用内存bashfree-h#示例输出(假设宿主机剩余16GB可用内存)#Mem:64G...
- 虚拟内存设置、解决linux内存不够问题
-
虚拟内存设置(解决linux内存不够情况)背景介绍 Memory指机器物理内存,读写速度低于CPU一个量级,但是高于磁盘不止一个量级。所以,程序和数据如果在内存的话,会有非常快的读写速度。但是,内存...
- Elasticsearch性能调优(5):服务器配置选择
-
在选择elasticsearch服务器时,要尽可能地选择与当前业务量相匹配的服务器。如果服务器配置太低,则意味着需要更多的节点来满足需求,一个集群的节点太多时会增加集群管理的成本。如果服务器配置太高,...
- Es如何落地
-
一、配置准备节点类型CPU内存硬盘网络机器数操作系统data节点16C64G2000G本地SSD所有es同一可用区3(ecs)Centos7master节点2C8G200G云SSD所有es同一可用区...
- 针对Linux内存管理知识学习总结
-
现在的服务器大部分都是运行在Linux上面的,所以,作为一个程序员有必要简单地了解一下系统是如何运行的。对于内存部分需要知道:地址映射内存管理的方式缺页异常先来看一些基本的知识,在进程看来,内存分为内...
- MySQL进阶之性能优化
-
概述MySQL的性能优化,包括了服务器硬件优化、操作系统的优化、MySQL数据库配置优化、数据库表设计的优化、SQL语句优化等5个方面的优化。在进行优化之前,需要先掌握性能分析的思路和方法,找出问题,...
- Linux Cgroups(Control Groups)原理
-
LinuxCgroups(ControlGroups)是内核提供的资源分配、限制和监控机制,通过层级化进程分组实现资源的精细化控制。以下从核心原理、操作示例和版本演进三方面详细分析:一、核心原理与...
- linux 常用性能优化参数及理解
-
1.优化内核相关参数配置文件/etc/sysctl.conf配置方法直接将参数添加进文件每条一行.sysctl-a可以查看默认配置sysctl-p执行并检测是否有错误例如设置错了参数:[roo...
- 如何在 Linux 中使用 Sysctl 命令?
-
sysctl是一个用于配置和查询Linux内核参数的命令行工具。它通过与/proc/sys虚拟文件系统交互,允许用户在运行时动态修改内核参数。这些参数控制着系统的各种行为,包括网络设置、文件...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- linux 查询端口号 (58)
- docker映射容器目录到宿主机 (66)
- 杀端口 (60)
- yum更换阿里源 (62)
- internet explorer 增强的安全配置已启用 (65)
- linux自动挂载 (56)
- 禁用selinux (55)
- sysv-rc-conf (69)
- ubuntu防火墙状态查看 (64)
- windows server 2022激活密钥 (56)
- 无法与服务器建立安全连接是什么意思 (74)
- 443/80端口被占用怎么解决 (56)
- ping无法访问目标主机怎么解决 (58)
- fdatasync (59)
- 405 not allowed (56)
- 免备案虚拟主机zxhost (55)
- linux根据pid查看进程 (60)
- dhcp工具 (62)
- mysql 1045 (57)
- 宝塔远程工具 (56)
- ssh服务器拒绝了密码 请再试一次 (56)
- ubuntu卸载docker (56)
- linux查看nginx状态 (63)
- tomcat 乱码 (76)
- 2008r2激活序列号 (65)