MySQL三大日志的作用及流程

BinLog

属于逻辑日志,记录的是对数据库的数据进行操作(如update、insert)的原始逻辑属于server层

作用:

  • 数据备份
  • 主从节点数据同步、

binlog以顺序追加写的方式在日志文件写入新的日志

记录格式

  • statement:记录操作数据库的原始的SQL 如:

    UPDATE user SET name='new' WHERE id=1

  • row:记录每行数据数据变化前后的值 如:

    id=1的name从'old'→'new'

  • mixed:动态切换row和statement,默认下使用statement

优缺点

statement:

优点:

  • 只记录SQL,日志体积小

  • 可读性强,排查日志时更方便

缺点:

  • 当SQL有用到函数如NOW()这种带上下文的信息时,会出现数据不一致的情况

row:

优点:

  • 不依赖上下文,能够保障数据的一致性
  • 使用索引快速定位数据行,并发大时性能更佳

缺点:

  • 记录了每行数据的变更,导致占用内存高,传输带宽需求及磁盘IO需求更高,会带来更高的主从同步延时。

    例:在批量操作 如 update user set sex =1 where sex=0 时,一条SQL将产生大量的日志记录

  • 可读性差,需要配合工具解析

mixed:
优点:

  • 平衡了row和mixed的日志大小和数据一致性

缺点:

  • 有可能出现数据不一致

写入机制

  1. 事务执行期间,将日志写入binglog cache(在内存上,不涉及磁盘IO,写入速度快)
  2. 事务提交时,再将binlog cache通过追加写方式(减少磁盘随机IO消耗)写入binlog文件(即落盘)

binlog cache:每个客户端线程都会被分配一个独立的binlog cache(默认大小32KB)

fsync:

  • 0:依赖OS自动控制落盘时机
  • 1:每次事务提交后强制刷盘,数据安全但影响吞吐性能
  • N: N个事务提交后进行落盘

RedoLog

记录数据页的物理变化,如某行的num+1,则记录:在对应行所存在的xx物理页内的num数据进行了+1

在存储引擎层工作,由InnoDB独占

应用场景:

  • 在mysql崩溃后实现数据恢复
  • 实现ACID中D(事务提交后数据变动是永久的)的特性

写入机制

MySQL读取数据是以页为单位的,在查询记录时,会将记录存在的页拷贝至buffer pool(在内存上)中进行读取

  1. 当更新表数据时,会先去buffer pool中查找数据是否存在,不在则取
  2. 在则将该页上的数据进行修改,同时写入redolog buffer中,将日志状态置为prepared(两阶段提交)
  3. 事务提交后将日志状态改为commit

redolog buffer的数据将按刷盘策略写入到redolog

刷盘策略:

Innodb默认开后台每秒进行一次redolog刷盘,初次之外还可通过配置策略实现额外刷盘时机

  1. 0:事务提交时不主动刷盘,依赖后台线程​​每秒​​将RedoLog Buffer中的数据写入Page Cache并调用fsync刷入磁盘
  2. 1(默认策略):每次事务提交时​​强制​​将Redo Log Buffer写入Page Cache,并调用fsync刷入磁盘
  3. 2:事务提交时将Redo Log Buffer写入Page Cache,但​​不调用fsync​,由操作系统决定何时刷盘(通常每秒一次)

其他刷盘时机:

  1. redolog buffer占用过半
  2. MySQ正常退出

数据丢失

  1. 策略0 时,宕机时最多丢失1s的数据
  2. 策略1 时,宕机也不会丢失数据
  3. 策略2 时,由于写入了OS的缓存,当MySQL宕机,OS没宕机时,则不会产生数据丢失。OS宕机则最多丢失1s数据

为什么不将每次修改后的数据页直接刷盘,而是写到Redolog里

  1. 数据页大小为16KB,而我们修改的数据往往只有几B,每次都刷浪费系统IO资源
  2. 每个数据页的位置是随机的,写入会触发磁盘随机IO,性能差
  3. redoLog一行记录大部分最多只占几十B,且是顺序写,刷盘数据更快,也能让数据库的并发写性能更高

两阶段提交

将redolog分为prepared和commited状态

配合binlog提交保障数据一致性

Redolog和binlog逻辑不一致会怎么样

当对一行数据的某个字段值为0的加一,这时候redolog写入完毕,但是binlog异常,且mysql出现宕机

redolog将这条数据进行了加一,而binlog没有。

mysql服务重启后因为原库使用的是redolog进行恢复数据,而从库则是按binlog进行的同步,从而出现主从数据不一致的情况。

通过两阶段提交:

当mysql使用redolog进行数据恢复时,发现事务的redolog还在prepare阶段,且没有数据没有对应的binlog,则回滚这个事务

当redolog在commit阶段出错,也不会影响,因为能在binlog找到相应的事务,并将prepare改为commit并进行刷盘,数据恢复

UndoLog

属于逻辑日志,记录的是每次数据修改前的值

作用:

  1. 保障事务的原子性:当事务执行失败或回滚时,通过undolog记录的旧值撤销操作,恢复到事务执行前的状态,如

    insert回滚:记录id值,回滚时delete id=x

    delete回滚:记录行,回滚时insert

    update回滚:记录修改前字段值,回滚则update对应字段回旧值

  2. 实现MVCC的视图:通过undolog版本链,实现多个事务能够拥有独立的读视图,保障了ACID的I特性,事务通过ReadView和版本链实现了RR,RC的事务隔离

  3. 减少锁的使用:通过维护多个版本实现快照读来实现了视图隔离,减少锁的使用,提高性能

流程:

  1. 在执行数据变更操作前,将数据旧值写入undo buffer
  2. 生成一个新的undolog节点,将roll_pointer指向已存在的最新undolog节点
  3. 事务提交后,undolog标记为可清理,由后台线程回收
  4. 事务回滚则根据版本链进行逆向操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值