mysql日志

MySql 三大日志

binlog-mysql-server层

redolog-innodb-存储引擎层

redolog-崩溃恢复

比如 MySQL 实例挂了或宕机了,重启时,InnoDB存储引擎会使用redo log恢复数据,保证数据的持久性与完整性。

每条 redo 记录由“表空间号+数据页号+偏移量+修改数据长度+具体修改的数据”组成

  1. MySQL 中数据是以页为单位,你查询一条记录,会从硬盘把一页的数据加载出来,加载出来的数据叫数据页,会放入到 Buffer Pool 中。
  2. 后续的查询都是先从 Buffer Pool 中找,没有命中再去硬盘加载,减少硬盘 IO 开销,提升性能。
  3. 更新表数据的时候,也是如此,发现 Buffer Pool 里存在要更新的数据,就直接在 Buffer Pool 里更新。
  4. 然后会把“在某个数据页上做了什么修改”记录到重做日志缓存(redo log buffer)里,接着刷盘到 redo log 文件里。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GLy6VN4B-1647952157678)(C:/Users/Administrator/Desktop/%E6%96%B0%E5%BB%BA%E6%96%87%E4%BB%B6%E5%A4%B9/03.png)]
    InnoDB 内部维护了一个缓冲池,用于减少对磁盘数据的直接IO操作,并配合 redo log、内部的 change buffer 来实现异步的落盘,保证程序的高效执行。redo log 大小固定,采用循环写write pos 表示当前正在记录的位置,会向后记录, checkpoint 表示数据落盘的边界,也就是 checkpoint 与 write pos中间是已记录的,当 write pos写完 id_logfile_3后,会回到id_logfile_0循环写,而追上 checkpomnit 后则需要先等数据进行落盘,等待 checkponit向后面移动一段距离再写。redo log存储的内容是对数据页的修改逻辑。
    在这里插入图片描述

刷盘时机

InnoDB 存储引擎为 redo log 的刷盘策略提供了 innodb_flush_log_at_trx_commit 参数,它支持三种策略:

  • 0 :设置为 0 的时候,表示每次事务提交时不进行刷盘操作。如果MySQL挂了或宕机可能会有1秒数据的丢失
  • 1 :设置为 1 的时候,表示每次事务提交时都将进行刷盘操作(默认值)。如果事务执行期间MySQL挂了或宕机,这部分日志丢了,但是事务并没有提交,所以日志丢了也不会有损失。
  • 2 :设置为 2 的时候,表示每次事务提交时都只把 redo log buffer 内容写入 page cache。如果仅仅只是MySQL挂了不会有任何数据丢失,但是宕机可能会有1秒数据的丢失。

innodb_flush_log_at_trx_commit 参数默认为 1 ,也就是说当事务提交时会调用 fsync 对 redo log 进行刷盘

另外,InnoDB 存储引擎有一个后台线程,每隔1 秒,就会把 redo log buffer 中的内容写到文件系统缓存(page cache),然后调用 fsync 刷盘。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RZyG1eNI-1647952157681)(C:/Users/Administrator/Desktop/%E6%96%B0%E5%BB%BA%E6%96%87%E4%BB%B6%E5%A4%B9/10.png)]
除了后台线程每秒1次的轮询操作,还有一种情况,当 redo log buffer 占用的空间即将达到 innodb_log_buffer_size 一半的时候,后台线程会主动刷盘。

日志文件组

redolog以日志文件组 环形链表的方式存在

在个日志文件组中还有两个重要的属性,分别是 write pos、checkpoint
在这里插入图片描述

  • write pos 是当前记录的位置,一边写一边后移
  • checkpoint 是当前要擦除的位置,也是往后推移

binlog 逻辑日志,记录内容是语句的原始逻辑

MySQL数据库的数据备份、主备、主主、主从都离不开binlog,需要依靠binlog来同步数据,保证数据一致性。

binlog会记录所有涉及更新数据的逻辑操作,并且是顺序写。(append的速度比较快)

记录格式

binlog 日志有三种格式,可以通过binlog_format参数指定。

  • statement

  • row

  • mixed

    指定statement,记录的内容是SQL语句原文,比如执行一条update T set update_time=now() where id=1
    在这里插入图片描述
    指定为row,记录的内容不再是简单的SQL语句了,还包含操作的具体数据


update_time=now()变成了具体的时间update_time=1627112756247,条件后面的@1、@2、@3 都是该行数据第 1 个~3 个字段的原始值(假设这张表只有 3 个字段)。

折中方案 mixed

MySQL会判断这条SQL语句是否可能引起数据不一致,如果是,就用row格式,否则就用statement格式

写入机制

  1. 事务执行过程中先把日志写到binlog cache
  2. 事务提交的时候,再把binlog cache写到binlog文件中。

因为一个事务的binlog不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一个块内存作为binlog cache

我们可以通过binlog_cache_size参数控制单个线程 binlog cache 大小,如果存储内容超过了这个参数,就要暂存到磁盘(Swap)。

刷盘

在这里插入图片描述

  • 上图的 write,是指把日志写入到文件系统的 page cache,并没有把数据持久化到磁盘,所以速度比较快
  • 上图的 fsync,才是将数据持久化到磁盘的操作

writefsync的时机,可以由参数sync_binlog控制,默认是0

0的时候,表示每次提交事务都只write,由系统自行判断什么时候执行fsync

为了安全起见,可以设置为1,表示每次提交事务都会执行fsync,就如同 redo log 日志刷盘流程 一样

最后还有一种折中方式,可以设置为N(N>1),表示每次提交事务都write,但累积N个事务后才fsync

两段提交——将redo log的写入拆成了两个步骤preparecommit,这就是两阶段提交

在这里插入图片描述

redo log(重做日志)让InnoDB存储引擎拥有了崩溃恢复能力。

binlog(归档日志)保证了MySQL集群架构的数据一致性。

举例 证明为什么要有prepare阶段

  • **先写redo log后写binlog:**假设在redolog写完,binlog还没有写完的时候,mysql进程异常重启。由于我们前面说过的,redolog写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行c的值是1。但是由于binlog没写完就crash了,这时候binlog里面就没有记录这个语句。因此,之后备份日志的时候,存起来的binlog里面就没有这条语句。然后就会发现,如果需要用这个binlog来恢复临时库的话,由于这个语句的binlog丢失,这个临时库就会少了一次更新,恢复出来的这一行c的值就是0,与原库的值不同
  • **先写binlog 后写redolog:**如果在binlog写完 之后crash,由于redolog还没写,崩溃恢复以后这个事务无效,所以这一行c的值是0.但是binlog里面已经记录了“把c从0改成1 ”这个日志。所以,在之后用binlog来恢复的时候就多了一个事务出来,恢复出来的这一行c的值就是1,与原库的值不同。
    在这里插入图片描述

undolog (回滚日志-保存历史版本状态)

undo log 主要有两个作用:

  • 当事务回滚时用于将数据恢复到修改前的样子

  • 另一个作用是 MVCC ,当读取记录时,若该记录被其他事务占用或当前版本对该事务不可见,则可以通过 undo log 读取之前的版本数据,以此实现非锁定读

在 InnoDB 存储引擎中 undo log 分为两种: insert undo log 和 update undo log:

  1. insert undo log :指在 insert 操作中产生的 undo log。因为 insert 操作的记录只对事务本身可见,对其他事务不可见,故该 undo log 可以在事务提交后直接删除。不需要进行 purge 操作
  2. update undo log :update 或 delete 操作中产生的 undo log。该 undo log可能需要提供 MVCC 机制,因此不能在事务提交时就进行删除。提交时放入 undo log 链表,等待 purge线程 进行最后的删除
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值