罪恶克星 发表于 2025-3-28 18:42:15

【数据库】MySQL中bin log、redo log、undo log详解

bin log、redo log、undo log简介



[*]bin log:归档日志。是逻辑日志,存储的是数据库变更的数据,包罗 INSERT、UPDATE、DELETE、DDL等操作。(数据库层面日志)
[*]redo log:重做日志。使得MySQL在崩溃后有了规复能力(innodb存储引擎日志)
[*]undo log:回滚日志。用于事务异常/自动回滚的场景(innodb存储引擎日志)
redo log(存储引擎日志)

MySQL中,查询一条数据,会将该数据相关页的所有数据一次性加载出来,放入 Buffer Pool中,后续都是从Buffer Pool中进行查找;对数据做修改时,如果数据在Buffer Pool中存在,则直接更新里面数据,然后将更新操作记载到 redo log buffer中,等候合适时间刷新到redo log 文件中。
落盘机遇



[*]提交事务:通过innodo_flush_log_at_trx_commit控制,在事务提交时,直接刷新到磁盘中

[*]innodo_flush_log_at_trx_commit = 0:提交事务时不进行刷盘操作,性能最高,安全性低
[*]innodo_flush_log_at_trx_commit = 1:每次提交都进行刷盘操作,性能最低,安全性最高
[*]innodo_flush_log_at_trx_commit = 2:每次提交,将log buffer 中数据写入page cache,

[*]buffer空间不足:当redo log buffer中存储的 redo log 超过容量的一半左右,会将日志存储的磁盘上。
[*]checkpoint:innodb有定期查抄的操作,会将内存中脏数据(已修改,但尚未落盘的数据)刷新到磁盘中,这时会将redo log 一同刷新
[*]后台刷新线程:innodb后台有个线程,周期性(1秒)的将脏页刷新到磁盘中,此时会将redo log 疫情通刷新
[*]正常关闭数据库:MySQL关闭时,redo log 会刷新到磁盘中
redo log 写入机遇



[*]开始事务
[*]执行SQL语句
[*]写入redo log日志
[*]提交事务
https://i-blog.csdnimg.cn/img_convert/7e398903e62f7d5413f6bb8684669507.png
日志组文件



[*] redo log的日志文件是以日志文件组的形式出现的,每个redo日志文件大小都是一样的,采用环形数组的形式,从头开始写,写到末端继承从头开始写。
[*] 日志文件组中有两个重要的属性

[*]write pos:当前记载的位置,边写边向后推移
[*]checkpoint:需要清除的位置,边清除边向后推移

[*] 当redo log记载到日志文件组中,write pos向后推移
[*] MySQL从日志文件组中规复数据时,会清空加载过得redo log,checkpoint 向后推移
[*] write pos和checkpoint中心的的差值就是可写的空间
为什么不直接刷盘?

前面提到过,数据是以数据页的形式加载的,数据修改可能仅修改了部分很小额数据就要把整个数据页进行刷盘,会造成大量IO。
binlog (数据库日志)

逻辑日志,记载的是SQL语句的原始逻辑,不管什么存储引擎,只要发生了表数据的更新,就会产生binlog日志。
重要用途

重要依赖binlog进行数据同步,保证数据一致性


[*]数据备份
[*]主备
[*]主主
[*]主从
记载格式



[*]statement:记载内容是SQL的原语句 select * from table where date = now()
[*]row:不但记载原始语句,还记载操作的具体数据,select * from table where date='20250317',不可直接检察,需要使用mysqlbinlog工具来解析
[*]mixed:会判定SQL语句在不同的时间执行是否结果不同

[*]相同:使用statement格式进行记载
[*]不相同:使用row格式进行记载

写入机遇



[*]开始事务
[*]记载操作变更语句和信息到binlog cache中
[*]事务提交阶段,先同步binlog到磁盘,再通知存储引擎提交事务
[*]提交事务
https://i-blog.csdnimg.cn/img_convert/63ab7eb93c998ef38ff03db662221a98.png
写入计谋



[*]sync_binlog

[*]1:事务每次提交后,同步binlog到磁盘,安全,性能低
[*]N:(N>1)每N次提交后同步一次
[*]0:异步同步,性能高,安全性低

两阶段提交

Innodb在执行更新语句时会记载redo log和binlog日志,两种日志在写入机遇不一样


[*]redo log:事务提交过程中随时都会写
[*]binlog:只有事务提交时才会写入
如果在执行一个更新语句期间,记载了redolog但是未记载binlog,会发生什么环境?
比方 update table set name = 'A1' where id=1,
[*]将id=1的名称改为 A1,此时redolog写完,写入binlog发生异常
[*]从库使用binlog进行规复时,id=1的数据name=A与主库 name=A1就会发生数据不一致的环境
为杜绝上述标题的出现,innodb使用两阶段提交的方法来进行办理
redo log的写入拆分成两步
[*]prepare:如果没有commit阶段,代表失败会进行回滚
[*]commit
https://i-blog.csdnimg.cn/img_convert/cf702676b17aee8b5c5646a73d0ff0f0.png
undo log

回滚日志,每个事务对数据的修改都会记载到undo log中,当事务执行过程中出现异常,MySQL使用undo log中的数据链进行数据追溯,将数据规复到开始之前的状态。
比方:
insert into table values(1,'A',15) 会在undo log中有一条记载
https://i-blog.csdnimg.cn/img_convert/ffcf539222a462e2473cd800ee8d7e0b.png
update table set name='A1' where id=1 也会在undo log中生成一条记载
https://i-blog.csdnimg.cn/img_convert/9fa0074009fa624e77e8abbaba8800b5.png
TX_ID=2记载中 ROL_POINT回滚指针指向的是 TX_ID记载的地址。
https://i-blog.csdnimg.cn/img_convert/d5e95c01e06fb691bfdccc2234167994.png
这样就能保证,更新失败后,能够通过记载找到原始数据进行规复

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【数据库】MySQL中bin log、redo log、undo log详解