Mysql——MySql事务日志理解,包含redo_log,binlog与undo_log三者间关系等

一、redo log的概念

InnoDB引擎对数据的更新,是先将更新记录写入redo log日志,然后会在系统空闲的时候或者是按照设定的更新策略再将日志中的内容更新到磁盘之中。这就是所谓的预写式技术(Write Ahead logging)。这种技术可以大大减少IO操作的频率,提升数据刷新的效率。

redo log包括两部分:一是内存中的日志缓冲(redo log buffer),该部分日志是易失性的;二是磁盘上的重做日志文件(redo log file),该部分日志是持久的。

在概念上,innodb通过force log at commit机制实现事务的持久性,即在事务提交的时候,必须先将该事务的所有事务日志写入到磁盘上的redo log file和undo log file中进行持久化。

为了确保每次日志都能写入到事务日志文件中,在每次将log buffer中的日志写入日志文件的过程中都会调用一次操作系统的fsync操作(即fsync()系统调用)。因为MariaDB/MySQL是工作在用户空间的,MariaDB/MySQL的log buffer处于用户空间的内存中。要写入到磁盘上的log file中(redo:ib_logfileN文件,undo:share tablespace或.ibd文件),中间还要经过操作系统内核空间的os buffer,调用fsync()的作用就是将OS buffer中的日志刷到磁盘上的log file中。

也就是说,从redo log buffer写日志到磁盘的redo log file中,过程如下: 

二、binlog与redolog的区别

redo log 是InnoDB 引擎特有的日志,而 Server 层也有自己的日志,称为 binlog (归档日志)

这两种日志有以下三点不同:
            1. redo log 是 InnoDB 引擎特有的; binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用,MySQL数据库中的任何存储引擎对于数据库的更改都会产生binlog。
            2. redo log 是物理日志,记录的是 “ 在某个数据页上做了什么修改 ” ; binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如 “ 给 ID=2 这一行的 c 字段加 1 ”。

binlog 记录的都是事务操作内容,binlog 有三种模式:Statement(基于 SQL 语句的复制)、Row(基于行的
复制) 以及 Mixed(混合模式)。具体这三种模式的区别请看主从同步和主备同步专栏

           3. redo log 是循环写的(类似一个循环队列),因为它的空间固定会用完; binlog 是可以追加写入的。 “ 追加写 ” 是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

            4.redo在 事务执行过程中 会不断的写入,而 binlog 是在 事务最终提交前 写入的

两阶段提交:

为了让两份日志之间的逻辑一致, redo log 的写入拆成了两个步骤: prepare 和commit ,这就是 " 两阶段提交 "。

三、Undo Log日志

Undo log记录了数据每个操作前的状态,如果事务执行过程中需要回滚,就可以根据undo log进行回滚操作。

数据库崩溃重启后,需要先从redo log中把未落盘的脏页数据恢复回来,重新写入磁盘,保证用户的数据不丢失。当然,在崩溃恢复中还需要把未提交的事务进行回滚操作。由于回滚操作需要undo log日志支持,undo log日志的完整性和可靠性需要redo log日志来保证,所以数据库崩溃需要先做redo log数据恢复,然后做undo log回滚。
 

四、undo log和redo log

二者可以理解为都是对数据的备份,其中undo log是对旧数据(原始数据)的备份,redo log是对新数据(事物所要提交的数据)的备份。对数据的备份首先是会存储在各自的buffer中,即undo buffer和redo buffer,至于如何持久化到磁盘,即写入到undo log和redo log文件中,要根据设置的具体落盘策略而定。

五、数据库事务流程

事务进行过程中,每次sql语句执行,都会记录undo log和redo log,然后更新数据形成脏页,然后redo log会根据时间和空间进行落盘,undo log和脏页会按照checkpointer机制落盘,落盘后相应的redo log就可以删除了。此时,事务还未COMMIT,如果发生崩溃,则首先检查checkpointer记录,使用相应的redo log进行数据恢复和undo log事务回滚。事务执行COMMIT操作时,会将本事务相关的所有redo log进行落盘,只有所有的redo log落盘成功,才算COMMIT成功。然后内存中的undo log和脏页会继续按照checkpointer进行落盘。如果此时发生崩溃,则只使用redo log恢复数据

 

六、Mysql 保证主从一致性:

  • 主库接收到客户端的更新请求后,执行内部事务的更新逻辑,同时写binlog。
  • 备库B跟主库A之间维持了一个长连接。主库A内部有一个线程,专门用于服务备库B的这个长连接。一个事务日志同步的完整过程是这样的:
  1. 在备库B上通过change master命令,设置主库A的IP、端口、用户名、密码,以及要从哪个位置开始请求binlog,这个位置包含文件名和日志偏移量。
  2. 在备库B上执行start slave命令,这时候备库会启动两个线程,就是图中的io_thread和sql_thread。其中io_thread负责与主库建立连接。
  3. 主库A校验完用户名、密码后,开始按照备库B传过来的位置,从本地读取binlog,发给B。
  4. 备库B拿到binlog后,写到本地文件,称为中转日志(relay log)。
  5. sql_thread读取中转日志,解析出日志里的命令,并执行。

七、undolog、redolog以及binlog关系:

Mysql 中常见的三个日志文件分别是 undolog、redolog以及binlog,redolog 主要是负责 crash-safe,也就是崩溃恢复的工作,binlog主要是做一个归档的作用,redolog和binlog是两阶段提交的,这也是常用的分布式的手段吧,大家都okay了才commit,redolog是可擦除的,存储的是物理日志,但是binlog是顺序写,存储的是逻辑日志,并且 redolog 是 Innodb 独有的,binlog则是 server端有的。undlog 主要是负责 mvcc 和回滚,在数据修改的时候,不仅记录了redo,还记录了相对应的undo,如果因为某些原因导致事务失败或回滚了,可以借助该undo进行回滚。undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。

八、事务的四个特性,如何实现原子性、隔离性、一致性、持久性的,内部机制具体如何实现

原子性(Atomicity)

语句要么全执行,要么全不执行,是事务最核心的特性,事务本身就是以原子性来定义的;实现主要基于undo log日志实现的。利用 undolog,回滚机制,完成要么全部成功,要么全部失败;

持久性(Durability)

保证事务提交后不会因为宕机等原因导致数据丢失;实现主要基于redo log日志。redolog保证crash-safe,bin-log保证归档

隔离性(Isolation)

保证事务执行尽可能不受其他事务影响。

InnoDB默认的隔离级别是RR。

RR的实现主要基于:

  1. 锁机制(行锁,表锁,页锁)
  2. 类next-key lock机制。
  3. MVCC机制:主要是靠一致性视图+当前行的 row_id_transaction,来完成的。

一致性(Consistency) 

主要靠加锁防止事务冲突,一致性是另外三个的顶层

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值