数据库通常借助日志来实现事务,常见的有undo log、redo log

undo/redo log都能保证事务特性,undo log实现事务原子性,redolog实现事务的持久性。

为了最大程度避免数据写入时io瓶颈带来的性能问题,MySQL采用了这样一种缓存机制:

  • 当query修改数据库内数据时,InnoDB先将该数据从磁盘读取到内存中,修改内存中的数据拷贝,并将该修改行为持久化到磁盘上的事务日志(先写redo log buffer,再定期批量写入),而不是每次都直接将修改过的数据记录到硬盘内,等事务日志持久化完成之后,内存中的脏数据可以慢慢刷回磁盘,称之为Write-Ahead Logging
  • 事务日志采用的是追加写入,顺序io会带来更好的性能优势。
  • 为了避免脏数据刷回磁盘过程中,掉电或系统故障带来的数据丢失问题,InnoDB采用事务日志(redo log)来解决该问题。

先简单了解几个概念
数据库数据存放的文件称为data file
日志文件称为log file;
数据库数据是有缓存的,如果没有缓存,每次都写或者读物理disk,那性能就太低下了。数据库数据的缓存称为data buffer,日志(redo)缓存称为log buffer。

内存缓冲池

buffer pool如果mysql不用内存缓冲池,每次读写数据时,都需要访问磁盘,必定会大大增加I/O请求,导致效率低下。所以Innodb引擎在读写数据时,把相应的数据和索引载入到内存中的缓冲池(buffer pool)中,一定程度的提高了数据读写的速度。

buffer pool
占最大块内存,用来存放各种数据的缓存包括有索引页、数据页、undo页、插入缓冲、自适应哈希索引、innodb存储的锁信息、数据字典信息等。工作方式总是将数据库文件按页(每页16k)读取到缓冲池,然后按最近最少使用(lru)的算法来保留在缓冲池中的缓存数据。如果数据库文件需要修改,总是首先修改在缓存池中的页(发生修改后即为脏页dirty page),然后再按照一定的频率将缓冲池的脏页刷新到文件。

表空间

表空间可看做是InnoDB存储引擎逻辑结构的最高层。

  • 表空间文件:InnoDB默认的表空间文件为ibdata1。
  • 段:表空间由各个段组成,常见的段有数据段、索引段、回滚段(undo log段)等。
  • 区:由64个连续的页组成,每个页大小为16kb,即每个区大小为1MB。
  • 页:每页16kb,且不能更改。常见的页类型有:数据页、Undo页、系统页、事务数据页、插入缓冲位图页、插入缓冲空闲列表页、未压缩的二进制大对象页、压缩的二进制大对象页。

redo log 和undo log

为了满足事务的持久性,防止buffer pool数据丢失,innodb引入了redo log。为了满足事务的原子性,innodb引入了undo log。

undo log

Undo log 是为了实现事务的原子性。还用Undo Log来实现多版本并发控制(简称:MVCC)。
delete/update操作的内部机制
当事务提交的时候,innodb不会立即删除undo log,因为后续还可能会用到undo log,如隔离级别为repeatable read时,事务读取的都是开启事务时的最新提交行版本,只要该事务不结束,该行版本就不能删除,即undo log不能删除。
但是在事务提交的时候,会将该事务对应的undo log放入到删除列表中,未来通过purge来删除。并且提交事务时,还会判断undo log分配的页是否可以重用,如果可以重用,则会分配给后面来的事务,避免为每个独立的事务分配独立的undo log页而浪费存储空间和性能。
通过undo log记录delete和update操作的结果发现:(insert操作无需分析,就是插入行而已)
delete操作实际上不会直接删除,而是将delete对象打上delete flag,标记为删除,最终的删除操作是purge线程完成的。
update分为两种情况:update的列是否是主键列。
如果不是主键列,在undo log中直接反向记录是如何update的。即update是直接进行的。
如果是主键列,update分两部执行:先删除该行,再插入一行目标行。

1.事务的原子性

事务的所有操作,要么全部完成,要不都不做,不能只做一半。如果在执行的过程中发生了错误,要回到事务开始时的状态,所有的操作都要回滚。

2.原理

Undo Log的原理很简单,为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为Undo Log)。然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。
假设有A、B两个数据,值分别为1,2。 进行+2的事务操作。

A.事务开始.
B.记录A=1到undo log.
C.修改A=3.
D.记录B=2到undo log.
E.修改B=4.
F.将undo log写到磁盘。
G.将数据写到磁盘。
H.事务提交

这里有一个隐含的前提条件:‘数据都是先读到内存中,然后修改内存中的数据,最后将数据写回磁盘’。
之所以能同时保证原子性和持久化,是因为以下特点:
A. 更新数据前记录Undo log。
B. 为了保证持久性,必须将数据在事务提交前写到磁盘。只要事务成功提交,数据必然已经持久化。
C. Undo log必须先于数据持久化到磁盘。如果在G,H之间系统崩溃,undo log是完整的,可以用来回滚事务。
D. 如果在A-F之间系统崩溃,因为数据没有持久化到磁盘。所以磁盘上的数据还是保持在事务开始前的状态。
缺点:每个事务提交前将数据和Undo Log写入磁盘,这样会导致大量的磁盘IO,因此性能很低。

Redo Log

redo log就是保存执行的SQL语句到一个指定的Log文件,当mysql执行数据恢复时,重新执行redo log记录的SQL操作即可。引入buffer pool会导致更新的数据不会实时持久化到磁盘,当系统崩溃时,虽然buffer pool中的数据丢失,数据没有持久化,但是系统可以根据Redo Log的内容,将所有数据恢复到最新的状态。redo log在磁盘上作为一个独立的文件存在。默认情况下会有两个文件,名称分别为 ib_logfile0和ib_logfile1。
参数innodb_log_file_size指定了redo log的大小;

innodb_log_file_in_group指定了redo log的数量,默认为2; innodb_log_group_home_dir指定了redo log所在路径。
123456789101112
innodb_additional_mem_pool_size = 100M
innodb_buffer_pool_size = 128M
innodb_data_home_dir = /home/mysql/local/mysql/var
innodb_data_file_path = ibdata1:1G:autoextend
innodb_file_io_threads = 4
innodb_thread_concurrency = 16
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size = 8M
innodb_log_file_size = 128M
innodb_log_file_in_group = 2
innodb_log_group_home_dir = /home/mysql/local/mysql/var

为了满足事务的原子性,在操作任何数据之前,首先将数据备份到Undo Log,然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。与redo log不同的是,磁盘上不存在单独的undo log文件,它存放在数据库内部的一个特殊段(segment)中,这称为undo段(undo segment),undo段位于共享表空间内。
Innodb为每行记录都实现了三个隐藏字段:
6字节的事务ID(DB_TRX_ID)
7字节的回滚指针(DB_ROLL_PTR)
隐藏的ID
redo log的记录内容
undo log和 redo log本身是分开的。innodb的undo log是记录在数据文件(ibd)中的,而且innodb将undo log的内容看作是数据,因此对undo log本身的操作(如向undo log中插入一条undo记录等),都会记录redo log。undo log可以不必立即持久化到磁盘上。即便丢失了,也可以通过redo log将其恢复。因此当插入一条记录时:
向undo log中插入一条undo log记录。
向redo log中插入一条”插入undo log记录“的redo log记录。
插入数据。
向redo log中插入一条”insert”的redo log记录。
redo log的io性能
为了保证Redo Log能够有比较好的IO性能,InnoDB 的 Redo Log的设计有以下几个特点:
尽量保持Redo Log存储在一段连续的空间上。因此在系统第一次启动时就会将日志文件的空间完全分配。以顺序追加的方式记录Redo Log。
批量写入日志。日志并不是直接写入文件,而是先写入redo log buffer,然后每秒钟将buffer中数据一并写入磁盘
并发的事务共享Redo Log的存储空间,它们的Redo Log按语句的执行顺序,依次交替的记录在一起,以减少日志占用的空间。
Redo Log上只进行顺序追加的操作,当一个事务需要回滚时,它的Redo Log记录也不会从Redo Log中删除掉。

1.原理

和Undo Log相反,Redo Log记录的是新数据的备份。在事务提交前,只要将Redo Log持久化即可,不需要将数据持久化。当系统崩溃时,虽然数据没有持久化,但是Redo Log已经持久化。系统可以根据Redo Log的内容,将所有数据恢复到最新的状态。

2.Undo+Redo事务的简化过程
A.事务开始.
B.记录A=1到undo log.
C.修改A=3.
D.记录A=3到redo log.
E.记录B=2到undo log.
F.修改B=4.
G.记录B=4到redo log.
H.将redo log写入磁盘。
I.事务提交

小结
A-G的过程是在内存中进行的,相应的操作记录在redo log buffer(B&E),redo log buffer(E&G)中,事务执行结果(此时未提交)也存在db buffer中(C&F),buffer满了就写入磁盘当中,如果buffer存储的事务数量都是1个,也就意味着是将日志立即刷入磁盘,那么数据的一致性很好保证。如果存储多个的话,是一次事务完成就会先将redo log同步到磁盘当中并有一个状态位来记录是否提交,再去真正的提交事务,将db buffer 中的数据同步到DB的磁盘当中去。要保证在db buffer中的内容写入磁盘数据库文件之前,应当把log buffer的内容写入磁盘日志文件。这种方式可以减少磁盘IO,增加吞吐量。 不过,这种方式适用于一致性要求不高的情景。因为如果出现断电等系统故障,log buffer、db buffer中的完成的事务还没同步到磁盘会丢失。 像银行这种要求事务较高的一致性,就一定要保证每次事务都要记录到磁盘中,如果服务器down了的时候去redo log中恢复,重做一次已经提交的事务。

redo & undo log的作用

数据持久化

buffer pool中维护一个按脏页修改先后顺序排列的链表,叫flush_list。根据flush_list中页的顺序刷数据到持久存储。按页面最早一次被修改的顺序排列。
正常情况下,dirty page什么时候flush到磁盘上呢?
当redo空间占满时,将会将部分dirty page flush到disk上,然后释放部分redo log。
当需要在Buffer pool分配一个page,但是已经满了,这时候必须 flush dirty pages to disk。一般地,可以通过启动参数 innodb_max_dirty_pages_pct控制这种情况,当buffer pool中的dirty page到达这个比例的时候,把dirty page flush到disk中。
检测到系统空闲的时候,会flush。

数据恢复

随着时间的积累,Redo Log会变的很大。如果每次都从第一条记录开始恢复,恢复的过程就会很慢,从而无法被容忍。为了减少恢复的时间,就引入了Checkpoint机制。假设在某个时间点,所有的脏页都被刷新到了磁盘上。这个时间点之前的所有Redo Log就不需要重做了。系统记录下这个时间点时redo log的结尾位置作为checkpoint。在进行恢复时,从这个checkpoint的位置开始即可。Checkpoint点之前的日志也就不再需要了,可以被删除掉。

恢复(Recovery)

恢复策略

前面说到未提交的事务和回滚了的事务也会记录Redo Log,因此在进行恢复时,这些事务要进行特殊的处理.
有2种不同的恢复策略:

  • 进行恢复时,只重做已经提交了的事务。(返回给客户端的是已经提交一定保证数据的可恢复持久性)
  • 进行恢复时,重做所有事务包括未提交的事务和回滚了的事务。然后通过Undo Log回滚那些未提交的事务。比如在B-E过程中down机了,那么恢复时根据undo log去重新模拟当时的情景(但是如果log buffer的空间很大,log没有同步到磁盘这个过程就没有办法来进行,同时由于事务没有提交,返回给客户端的值是未提交成功,所以也没有关系)

undo和redo日志相关推荐

  1. 关于undo和redo日志的区别

    一.undo和redo日志的区别 undo:撤销,也就是取消之前的操作 redo:重做,重新执行一遍之前的操作 二.什么是redo redo记录transaction logs,分为online和ar ...

  2. 数据库的UNDO和REDO

    2020年的第一篇博客,哈哈哈 Undo日志记录某数据被修改前的值,可以用来在事务失败时进行rollback(回滚): Redo日志记录某数据块被修改后的值,可以用来恢复未写入data file的已成 ...

  3. MySQL系列: undo和redo工作原理

    ACID 首先来讨论事务的四大特性ACID 原子性(Atomicity):事务作为一个整体来执行,要不都执行,要不都不执行 一致性(Consistency):事务必须保证数据库从一个一致状态转移到另一 ...

  4. Oracle 中UNDO与REDO的差别具体解释

    一 为了更清楚的看出2者差别,请看下表:                                               UNDO                             ...

  5. undo和redo介绍

    在数据库系统中,既有存放数据的文件,也有存放日志的文件.日志在内存中也是有缓存Log buffer,也有磁盘文件log file. MySQL中的日志文件,有这么两类与事务有关:undo日志与redo ...

  6. 认真学习MySQL的事务日志-Redo日志

    事务有4种特性:原子性.一致性.隔离性和持久性.那么事务的四种特性到底是基于什么机制实现呢? 事务的隔离性由锁机制执行. 事务的原子性.一致性和持久性由事务的redo日志和undo日志来保证. red ...

  7. 假事务之名,深入研究UNDO与REDO

    "有道无术,术尚可求:有术无道,止于术".今天让我们一起来看看DBA+社群联合发起人郭耀龙大师如何布道. 专家简介 郭耀龙 DBA+社群联合发起人 超过5年Oracle数据库经验, ...

  8. oracle undo与redo的区别

    首先看一下undo与redo的字面意思:   undo:撤销,也就是取消之前的操作.   redo:重做,重新执行一遍之前的操作. 什么是REDO REDO记录transaction logs,分为o ...

  9. oracle中redo和undo实验,REDO与UNDO几个实验

    1.IMU模式与非IMU模式下REDO的区别 1.1.IMU模式 REDO RECORD - Thread:1 RBA: 0x000004.0000000b.0010 LEN: 0x0374 VLD: ...

  10. [20160223]检查redo日志的完整性.txt

    [20160223]检查redo日志的完整性.txt --在论坛里问的问题: http://www.itpub.net/thread-2053302-1-1.html 1.直接检查dump logfi ...

最新文章

  1. spring MVC使用自定义的参数解析器解析参数
  2. 导入myql库的操作方式
  3. ubuntu16 redis5.0以前版本集群部署示例
  4. elm的 java包_README.md
  5. 测试人如何高效地设计自动化测试框架?
  6. 你必须掌握的Python数据分析工具之Numpy
  7. SPSS编程-统计自动化-Python脚本开发
  8. 科赫雪花曲线 matlab编程,科赫雪花曲线的MATLAB编程实现.doc
  9. mysql回收站恢复数据恢复_回收站清空了如何恢复?金山数据恢复大师恢复回收站清空文件的方法...
  10. 多媒体系统导论 实验一:基于Photoshop的图像处理
  11. 不同环境间FSG报表组件的传输
  12. STM32 通过定时器产生PPM信号
  13. 视频拍摄技巧——构图
  14. 数字图像处理实验八图像的傅里叶变换
  15. 手机版本考试系统载图
  16. 移动硬盘安装Ubuntu,并确保在任何电脑都可用
  17. logstash filter 过滤器详解
  18. linux磁盘分区方法 重新分区方法 新建分区方法
  19. Springboot启动报错[ main] o.s.boot.SpringApplication: Application run failed
  20. 外包程序员:软件开发人员派遣进行IT人员驻场开发的好处有哪些?

热门文章

  1. JavaProject-IP归属地查询
  2. 技术赋能广告策略全升级,爱奇艺开启框内广告营销新篇章
  3. 疫情下的大数据力量:多地政府借力大数据技术,多家企业上马大数据产品
  4. 11月14日Fluent建模笔记
  5. Android笔记之系统软键盘布局
  6. 循序渐进ActiveMQ(6)----使用zookeeper实现activemq的主从环境搭建
  7. 记录学习历程-----游戏编程
  8. AMiner发布2022 AI 2000人工智能最具影响力学者名单
  9. 可变焦、聚焦摄像头驱动程序-瑞盟 MS41908M
  10. 获取小猪民宿(短租)数据