MySQL-日志

MySQL-日志

MySQL中的日志文件,有这么两种与事务有关:undo日志与redo日志。
undo和redo: : 解决原子性、持久性
日志在内存即有缓存Log buffer,又有磁盘文件log file。
原子性(Atomicity):不全部成功,就全部恢复。
持久性**(Durability),一旦提交不可逆。
undo log 记录原始数据,用于保证事务原子性
redo log 记录修改数据,用于保证事务的持久性
redo log有自己的内存buffer,先写入到buffer,事务提交时(缓存满的时候)写入磁盘
redo log持久化之后,意味着事务是
可提交**的

Undo Log

原理:

  • 为了满足事务原子性,操作任何数据时,先将数据备份到undo_log,再进行数据的修改。如果出现了未知错误或者用户进行了ROLLBACK,db就可以利用undo_log 备份将数据恢复到事务开始之前的状态。
  • DB: 写入数据到磁盘之前,先将数据缓存到内存中,事务提交之前才会写入磁盘中

简化过程:

假设有A、B两个数据,值分别为1,2

  1. 事务开始.
  2. 记录A=1到undo log.
  3. 修改A=3.
  4. 记录B=2到undo log.
  5. 修改B=4.
  6. 将undo log写到磁盘。
  7. 将数据写到磁盘。
  8. 事务提交
保证持久性:
  • 事务提交前会将修改数据写到磁盘
  • 也就是说一旦事务提交,肯定持久性
保证原子性:
  • 每次对DB修改,都会把原始数据存到undo_log中,需要回滚时,直接读取undo_log,恢复数据
  • 系统在7和8之间挂了,事务未提交,直接回滚,通过undo_log(6已持久化)
  • 系统在7之前挂了,此时数据未持久化到硬盘(内存当中),挂了之后,内存清理,依然保存之前的状态。

缺陷:

cpu
磁盘(光盘) 激光探头读取数据,寻址—》读取数据
转速 4800 5200
顺序读写
随机读写 RAM
mysql索引 随机写

  1. 每个事务提交前数据和undo_log写入磁盘,造成大量磁盘IO,性能低

如果可以将数据缓存一段时间,就能减少IO提高性能。但是这样就会丧失事务的持久性。因此引入了另外一种机制来实现持久化,即Redo Log.

Redo Log

undo 记录旧数据,redo_log 记录修改之后的数据
在内存中
== 将数据写到磁盘(异步) == 随机写 寻址浪费大量时间
redo 与数据不太一样,redo_log是一种高性能写入方式,顺序写(连续空间),减少寻址的性能问题
真实场景:undo_log(随机写)写入redo_log.降低性能瓶颈

基本原理:

Undo + Redo事务的简化过程

  1. 事务开始.
  2. 记录A=1到undo log buffer.
  3. 修改A=3.
  4. 记录A=3到redo log buffer.
  5. 记录B=2到undo log buffer.
  6. 修改B=4.
  7. 记录B=4到redo log buffer.
  8. 将undo log写入磁盘(真实场景redo_log)
  9. 将redo log写入磁盘
  10. 事务提交

保证原子性:

  • 事务提交前一步故障,通过undo_log 日志恢复
  • 如果undo_log未写入,数据尚未持久化,无需回滚

保证持久性:

  • 数据已经写入redo log,而redo log持久化到了硬盘,
  • 只要到了步骤`9以后,事务可以提交的。

内存中的DB数据持久化到磁盘:

  • redo log已经持久化,因此数据库数据写入磁盘与否影响不大,
  • 为了避免出现脏数据(内存中与磁盘不一致),事务提交后也会将内存数据刷入磁盘(也可以按照固设定的频率刷新内存数据到磁盘中)。异步

redo log会在事务提交之前,或者redo log buffer满了的时候写入磁盘

极端问题

1、undo是写undo和数据库数据到硬盘,redo_是写undo和redo到磁盘,IO次数都是两次,没有减少
  • DB数据写入是随机IO,性能很差
  • redo log在初始化时会开辟一段连续的空间,写入是顺序IO,性能很好
  • 真实场景,undo log并不是直接写入磁盘,而是先写入到redo log buffer中,当redo log持久化时,undo log就同时持久化到硬盘了。
  • 故事务提交前,只需要对redo log持久化即可。
  • redo log并不是写入一次就持久化一次,redo log在内存中也有自己的缓冲池:redo log buffer。每次写redo log都是写入到buffer,在提交时一次性持久化到磁盘,减少IO次数。
2、redo log 数据是写入内存buffer中,当buffer满或者事务提交时,将buffer数据写入磁盘。redo log中记录的数据,有可能包含尚未提交事务,如果此时数据库崩溃,那么如何完成数据恢复?
  • 数据恢复有两种策略:
    • 恢复时,只重做已经提交了的事务(redo_log 中挑undo)
    • 恢复时,重做所有事务包括未提交的事务和回滚了的事务。然后通过Undo Log回滚那些未提交的事务(先redo_log顺序执行,后面在undo_log中找,再还原)

Inodb引擎采用的是第二种方案,因此undo log要在 redo log前持久化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值