首页 > 数据库 >MySQL的三大日志及事务

MySQL的三大日志及事务

时间:2024-04-16 20:58:52浏览次数:36  
标签:事务 log undo MySQL 日志 redo 三大 刷盘

标题其实不太准确,应该是MySQL的bin log,InnoDB的redo log和undo log

 

事务的四大特征: ACID,  其中原子性A)、隔离性I)和持久性D)是手段, 一致性C)是目标

Atomicity      原子性  == 》由undo log实现

Consistency 一致性  ==》 最终的目标,由AID共同来保证

Isolation       隔离性  == 》 由mvcc共同实现,要结合具体的隔离级别来看

Durability     持久性  == 》 由redo log来实现

 

 

bin log:归档日志

是MySQL server层逻辑日志,记录内容是语句的原始逻辑,只要有数据的变动,都会产生binlog

记录格式:

1.statement      sql语句原句,对于字段设置值为系统时间的情况下,会有问题

2.row                记录改动行各字段的值,比较占空间

3.mixed             以上两种形式的混合

 

 

写入过程:

事务执行过程中,先把日志写入binlog cache,事务提交时再把binlog cache写入文件系统缓存page cache,根据选择的刷盘策略调用fsync完成刷盘,最终写到binlog文件。

 

刷盘策略

sync_binlog 默认为1

0:每次事务提交都只写入到文件系统的page cache,系统自己判断何时fsync

1:(默认)每次提交事务都会执行fsync,即每次都会执行fsync,安全

N:N>1, 每次事务提交都写到文件系统的page cache,N个事务提交后才fsync,最多丢N个事务的bin log

 

名词解释

binlog cache:每个线程都会分配一块内存,用于临时存储binlog

page cache:文件系统的缓存,系统会自动决定何时将缓存中的数据写到磁盘,但是如果系统挂了,缓存中的内容会丢失,在上面的场景中就会丢失binlog

fsync:将page cache中的数据持久化到磁盘

 

 

 

 

 

 

redo log重做日志

是InnoDB存储引擎独有的,是一种物理日志,让MySQL拥有崩溃恢复的能力,保证了事务的持久性

默认情况下不丢数据,因为提交事务就会将该事务redo log刷盘,即使脏页还未刷盘,也能在下次MySQL启动的时候,根据checkpoint和redolog进行数据的恢复

 

当你进行查询的时候,InnoDB会以页为单位将数据从硬盘加载出来,加载出来的数据较数据页,放入Buffer Pool

后续的查询都是先从Buffer Pool中找,没有命中再从硬盘加载,减少硬盘的IO,提升性能

更新数据,如果数据再BufferPool中,会直接更新BufferPoolli的数据,然后将做了什么修改记录到重做日志缓存(redo log buffer)中,然后根据刷盘策略和刷盘时机,将数据

 

脏页刷盘时机

内存不足:Buffer Pool已满,而查询时需要加载新的数据页,就必须淘汰一些数据页(未改过的就是干净页,改过的就是脏页),如果淘汰的是脏页,就需要将脏页刷盘

redo log写满:此时更新操作会停下来,知道redo log和check point 与write pos指向一块

MySQL空闲时

MySQL正常退出时

 

log刷盘时机

事务提交(默认刷盘策略时)

正常关闭服务器

log buffer空间不足

事务日志缓冲区满

Checkpoint:定期执行检查点操作,将脏页刷盘

后台刷新线程:后台线程周期性将脏页刷盘(每隔一秒)

log刷盘策略

innodb_flush_log_at_trx_commit有如下三个值(选项)

0:事务提交不进行刷盘操作,后台线程会周期性(1s)进行刷盘。  性能最高,安全性最低,可能会丢失最近1s的事务。

1:(默认)每次事务提交都会刷盘操作。                                          性能最低,安全性最高,不会丢数据。

2:事务提交只会把log buffer的redo log内容写入page cache(文件系统缓存)。性能和安全性折中。

 

为什么提交事务的时候不直接刷数据页,而是要刷redolog?

数据页大小是16KB,里面包含了多行数据,可能一次就改了其中的几个Byte的数据,没必要全部刷盘,而且数据页的刷盘是随机写,性能很差

而一行改动的redo log可能就几十Btye,redo log的刷盘是磁盘顺序写,性能高

 

名词解释

Buffer Pool: 缓冲池,将磁盘上的数据页加载出来后缓存在缓冲池,相当于一个缓存,为了减少磁盘IO

数据页:存在Buffer Pool中的数据,以页的形式存储在内存中

干净页:未修改过的数据页

脏页:修改过,但未刷盘的数据页

checkpoint: 用日志逻辑序列号记录最新的刷回磁盘的最新页的版本

redo log buffer: 存储重做日志的缓冲区,会根据log刷盘策略和时机进行刷盘,默认是事务提交就会刷盘

 

 

 

undo log:回滚日志

是InnoDB存储引擎独有的,是一种逻辑日志(和redo log不一致),保证事务的原子性

 

用途

事务回滚

MVCC(多版本并发控制):InnoDB存储引擎中MVCC的实现是通过undo来完成。当用户读取一行记录时,若该记录已经被其他事务占用,当前事务可以通过undo读取之前的行版本信息,以此实现非锁定读取

 

原理

根据原始sql,解析并生陈反向sql,并存储在undo段内,记录的是某条数据的历史版本

 

log类型

insert undo log    在insert操作时产生的undo log

update undo log  在update/delete操作时产生的undo log

  • 对于每个INSERT,InnoDB存储引擎会完成一个DELETE
  • 对于每个DELETE,InnoDB存储引擎会执行一个INSERT
  • 每个UPDATE,InnoDB存储引擎会执行一个相反的UPDATE,将修改前的行放回去

 

存储位置

undo存放在数据库内部的一个特殊段(segment)中,这个段称为undo段

undo段位于共享表空间内

 

最后也是最为重要的一点是,undo log会产生redo log,也就是undo log的产生会伴随着redo log的产生,这是因为undo log也需要持久性的保护

 

两阶段提交

redo log(重做日志)让InnoDB存储引擎拥有了崩溃恢复能力

binlog(归档日志)保证了MySQL集群架构的数据一致性

他们都是持久化的保证,但侧重点不同

 

为什么采取两阶段提交?

为了解决bin log和redo log的逻辑一致性问题

 

哪两阶段?哪个日志?

redo log的写入分为 prepare阶段和commit阶段

 

事务中各个日志的写入过程如下图

 

对于异常情况

写完redo log 的prepare 但是还没有写bin log,数据库/服务器挂了  = 》 因为找不到和redo log prepare阶段对应的bin log,MySQL会回滚这个事务

写完redo logd prepare 和写入了bin log,但没写redo log 的commit,数据库/服务器挂了 = 》 因为能找到redo log prepare 和对应的bin log, MySQL认为数据完整,会提交事务恢复数据

 

如将redo log和bin log联系起来 = 》 通过事务id

 

 

MVCC

是一种并发控制机制,在多个并发事务同时读写数据库的情况下保持数据的一致性和隔离性。

读操作(select)

当一个事务执行读取操作时,会使用快照读。快照读是基于事务开始时间,读取到的是事务开始前最新的那个版本的数据

 

写操作(insert、update、delete)

当一个事务执行写操作时,会产生一个新的版本的数据写入数据库,原始版本的数据仍然会存在,不影响别的事务使用快照读来读取历史版本数据,保证了其他事务不受当前事务写操作的影响。

 

事务提交和回滚

当一个事务提交时,它的写操作产生的新版本数据会成为当前数据的最新版本,并对其他事务可见

当一个事务回滚时,它的修改会被撤销,对其他事务不可见

 

版本的回收

MVCC会定期进行版本回收,删除不再需要的旧版本数据,从而释放空间

 

 

锁定读(Locking Reads)

select ... lock in share mode

select ... for update(又称为当前读)

insert、update、delete 操作

 

对于锁定读,在RC和RR隔离级别下,在一个事务内,执行的时候能读取到基于当前时间的最新的已提交的事务的数据  (使用的是锁定读这个不算是幻读)

 

 

四种隔离级别以及对应存在的问题

MySQL锁、事务和索引

 

 

参考:

MySQL三大日志(binlog、redo log和undo log)详解

MySQL(InnoDB剖析):40---事务之(事务的实现:undo log(回滚日志))

标签:事务,log,undo,MySQL,日志,redo,三大,刷盘
From: https://www.cnblogs.com/huainanyin/p/18136969

相关文章

  • Linux安装MySQL
    Linux安装MySQL下载安装包下载.rpm文件sudowgethttps://repo.mysql.com//mysql80-community-release-el7-11.noarch.rpm执行rpm命令,安装rpm数据库sudorpm-Uvhmysql80-community-release-el7-11.noarch.rpm安装mysqlsudoyuminstallmysql-servermysql服务......
  • ubuntu安装mysql详细教程
    安装环境:VMwareWorkstationPro16系统:ubuntu64位 点击左下角应用程序 继续点击终端有的系统版本不同可以能也叫terminal 点击进入过后输入sudoaptupdate来升级sudo 第一次使用sudo命令会要管理员密码也就是你登录ubuntu的密码(输入密码时是不会显示出来的!) 下载......
  • mysql sql优化
    1select*杜绝使用不会走索引增加资源消耗2小表驱动大表大表不仅仅是现在大更可能是以后大的表一直新增数据的表3提升groupby效率给groupby字段设置索引4一行一行的插入改为批量插入5大数据表查询时使用limit限制数据的条数深翻页优化1》使用自增id2......
  • ros 日志
    ros网址http://wiki.ros.org/roscpp/Overview/Logginghttps://www.jianshu.com/p/8d23b4c12f6f日志消息等级debuginfowarnerrorfatal日志消息查看/更改工具rqt_console查看日志rqt_logger_level更改日志等级命令行更改日志等级:rosservicecall/node-name/set_logg......
  • mysql Explan命令 如何分析语句
    MySQL中的EXPLAIN命令是一种用于分析查询语句执行计划的强大工具,它可以帮助您了解MySQL优化器如何处理SQL查询,揭示查询执行过程中的关键细节,如表的读取顺序、数据读取操作的操作类型、所使用的索引等。通过EXPLAIN分析查询语句,您可以找出潜在的性能瓶颈,进行针对性的......
  • Mysql:canal 客户端 client java包依赖 v1.1.5+
     Cao!<dependencies><dependency><groupId>com.alibaba.otter</groupId><artifactId>canal.client</artifactId><version>1.1.7</version></dependency><dependency>......
  • CentOS 7.9 python 虚拟环境安装mysqlclient失败
    目录环境懵懂安装报错原因解决完结撒花......
  • MySQL之磁盘I/O过高排查
    导读有个MySQL服务器的磁盘I/O总有过高报警,怎么回事?有哪些原因MySQL服务器最近总是报告磁盘I/O非常高,出现这种问题,一般来说,磁盘I/O很高无非是下面几个原因引起:磁盘子系统设备性能差,或采用ext2/ext3之类文件系统,或采用cfq之类的ioscheduler,所以IOPS提上不去;SQL效率不高,......
  • mysql5.7 dump GTID一致性的问题
    利用mysqldump导出数据时提示warning,ApartialdumpfromaserverthathasGTIDsubt@ubt-All-Series:~$mysqldump-uroot-psdxdb>sdxdb.sqlWarning:ApartialdumpfromaserverthathasGTIDswillbydefaultincludetheGTIDsofalltransactions,eventhoseth......
  • 数据库的基本使用-mysql
    https://blog.csdn.net/weixin_50964512/article/details/1246452121.showdatabases;//显示当前已有的数据库2.createdatabasetest2;//创建新的数据库3.usetest1;//使用test1数据库,接下来的操作基于该数据库4.exit;//退出sql//数据表增删改查select*......