MySQL事务原理,日志

MySQL事务原理,日志,第1张

事务原理

先把图片奉上

事务是一组 *** 作的集合,它是一个不可分割的工作单位,事务会把所有的 *** 作作为一个整体一起向系统提交或撤销 *** 作请求,即这些 *** 作要么同时成功,要么同时失败。

事务四大特征

原子性(Atomicity)︰ 事务是不可分割的最小 *** 作单元,要么全部成功,要么全部失败。
一致性(Consistency): 事务完成时,必须使所有的数据都保持一致状态。
隔离性(lsolation) ∶ 数据库系统提供的隔离机制,保证事务在不受外部并发 *** 作影响的独立环境下运行。
持久性(Durability): 事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

redo log【持久性】
https://www.bilibili.com/video/BV1Kr4y1i7ru?p=139

简单了解一下InnoDB 的底层原理:
https://mp.weixin.qq.com/s/-puz311svMVbBAdRioPrnQ

https://zhuanlan.zhihu.com/p/346970015

重做日志,记录的是事务提交时数据页的物理修改,是用来实现事务的持久性。
该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log file),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都存到该日志文件中,用于在刷新脏页到磁盘,发生错误时,进行数据恢复使用。

这种先写日志,再写磁盘的技术就是MySQL里经常说到的WAL(Write-Ahead Logging) 技术。

undo log【原子性】
回滚日志,用于记录数据被修改前的信息,作用包含两个:提供回滚和MVCC(多版本并发控制)。

undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。

Undo log销毁:undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些日志可能还用于MVCC。
Undo log存储:undo log采用段的方式进行管理和记录,存放在前面介绍的 rollback segment 回滚段中,内部包含1024个undo logsegment。

MVCC(多版本并发控制) 概念

当前读
读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录, 会 对 读 取 的 记 录进行 加锁。对于我们日常的 *** 作,如:select … lock in share mode(共享锁),select … for update、update、insert、delete(排他锁)都是一种当前读。

快照读
简单的select(不加锁)就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。
● Read committed:每次select,都生成一个快照读。
● Repeatable Read:开启事务后第一个select语句才是快照读的地方。
● Serializable:快照读会退化为当前读。

MVCC
全称Multi-version Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写 *** 作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段、undo log日志、readView.

1、隐藏字段


主要是事务ID和回滚指针

undo log日志
回滚日志,在insert. update、delete的时候产生的便于数据回滚的日志。
当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。
而update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。

2、undo log 版本链


不同事务或相同事务对同一条记录进行修改,会导致该记录的undo log生成一条记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。

3、readView.

ReadView(读视图)是 快照读 SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的) id,Readview中包含了四个核心字段:


不同的隔离级别,生成ReadView的时机不同:
READ COMMITTED:在事务中每一次执行快照读时生成Readview.
REPEATABLE READ:仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。

MVCC实现原理

https://www.bilibili.com/video/BV1Kr4y1i7ru?p=145
在读已提交的事务隔离级别下,MVCC在进行快照读的提取过程

RR隔离级别下,仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView.

小结

事务原理:
原子性 – undo log
一致性 – undo log + redo log
隔离性 – 锁+ MVCC
持久性 – redo log

MVCC
记录隐藏字段、
undo log版本链 、
readView

日志

上面提到了Redo log,这一小节就专门来讲一讲日志,日志分为如下两个维度。

MySQL层面

InnoDB层面

MySQL日志

MySQL的日志可以分为错误日志、二进制文件、查询日志和满查询日志。

  • 错误日志 很好理解,就是服务运行过程中发生的严重错误日志。当我们的数据库无法启动时,就可以来这里看看具体不能启动的原因是什么
  • 二进制文件 它有另外一个名字你应该熟悉,叫Binlog,其记录了对数据库所有的更改。
  • 查询日志 记录了来自客户端的所有语句
  • 慢查询日志 这里记录了所有响应时间超过阈值的SQL语句,这个阈值我们可以自己设置,参数为long_query_time,其默认值为10s,且默认是关闭的状态,需要手动的打开。
InnoDB日志

InnoDB日志就只有两种,Redo Log和Undo Log,

  • Redo Log 重做日志,用于记录事务 *** 作的变化,且记录的是修改之后的值。不管事务是否提交都会记录下来。例如在更新数据时,会先将更新的记录写到Redo Log中,再更新缓存中页中的数据。然后按照设置的更新策略,将内存中的数据刷回磁盘。
  • Undo Log 回滚日志,记录的是记录的事务开始之前的一个版本,可用于事务失败之后发生的回滚。

Redo Log记录的是具体某个数据页上的修改,只能在当前Server使用,而Binlog可以理解为可以给其他类型的存储引擎使用。这也是Binlog的一个重要作用,那就是主从复制,另外一个作用是数据恢复。

上面提到过,Binlog中记录了所有对数据库的修改,其记录日志有三种格式。分别是Statement、Row和MixedLevel。

  • Statement 记录所有会修改数据的SQL,其只会记录SQL,并不需要记录下这个SQL影响的所有行,减少了日志量,提高了性能。但是由于只是记录执行语句,不能保证在Slave节点上能够正确执行,所以还需要额外的记录一些上下文信息
  • Row 只保存被修改的记录,与Statement只记录执行SQL来比较,Row会产生大量的日志。但是Row不用记录上下文信息了,只需要关注被改成啥样就行。
  • MixedLevel 就是Statement和Row混合使用。

具体使用哪种日志,需要根据实际情况来决定。例如一条UPDATE语句更新了很多的数据,采用、Statement会更加节省空间,但是相对的,Row会更加的可靠。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/905373.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-15
下一篇 2022-05-15

发表评论

登录后才能评论

评论列表(0条)

保存