Loading

mysql 三大日志

转自:https://blog.csdn.net/qq_50596778/article/details/123232708

1、undo log

undo log 记录数据被修改前的信息。

作用:防止丢失数据,用于事务失败后的回滚,Innodb 存储引擎的最大特点就是支持事务,如果本次更新失败,那么该事务中的所有的操作都必须回滚到执行前的样子,也就是说当事务失败的时候,也不会对原始数据有影响。

添加时机:在mysql将要更新的数据加载到缓冲区Buffer pool 时,同时往 undo 日志文件中插入一条数据初始状态记录的日志。

 2、redo log

redo 记录的是数据修改之后的值,不管事务是否提交都会记录下来.。

在MySQL中,redo log是一个文件组,一般是3个文件,循环写入,写满的时候会做redo log层面的checkpoint,然后覆盖之前的redo log;而binlog是有归档功能的,每个binlog写满之后,都会重新开启下一个binlog开始写入,这也是为什么可以使用binlog来进行数据恢复的一个原因,就是因为它的归档功能。

  1. MySQL 为了提高效率,所以先从磁盘读取数据放在内存中去完成,然后直接在内存对数据进行操作,这些操作会在某个时机将其持久化到磁盘中。
  2. 除了从磁盘中加载文件和将操作前的记录保存到 undo 日志文件中,其他的操作是在内存中完成的。
  3. 内存数据断电丢失:如果此时 MySQL 所在的服务器宕机了,那么 Buffer Pool 中的数据会全部丢失的。这个时候就需要 redo 日志文件来恢复数据。

注意:

  • redo log持久化前,mysql会认为本次事务失败,利用undo log日志恢复到更新前的样子。
  • redo log持久化后,mysql下次重启的时候会自动将redo log日志文件内容恢复到缓冲区中。

更新流程:

  1. 准备更新一条 SQL 语句。
  2. MySQL(innodb)会先去缓冲池(BufferPool)中去查找这条数据,没找到就会去磁盘中查找,如果查找到就会将这条数据加载到缓冲池(BufferPool)中。
  3. 在加载到 Buffer Pool 的同时,会将这条数据的原始记录保存到 undo 日志文件中。
  4. innodb 会在 Buffer Pool 中执行更新操作,更新后的数据会记录在 redo log buffer 中。
  5. 将 redo log buffer 中的数据写入到 redo log 磁盘文件中(innodb_flush_log_at_trx_commit 参数决定)。
  6. 提交事务,数据修改永久保存到数据库。

 3、bin log

binlog用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。

binlog是通过追加的方式进行写入的,可以通过max_binlog_size参数设置每个binlog文件的大小,当文件大小达到给定值之后,会生成新的文件来保存日志。

在实际应用中,binlog的主要使用场景有两个,分别是主从复制和数据恢复。

  1. 主从复制:在Master端开启binlog,然后将binlog发送到各个Slave端,Slave端重放binlog从而达到主从数据一致。
  2. 数据恢复:通过使用mysqlbinlog工具来恢复数据。

bin log刷入磁盘策略
bin log 的刷盘是有相关的策略的,通过sync_bin log来修改

对于InnoDB存储引擎而言,只有在事务提交时才会记录binlog,此时记录还在内存中,那么biglog是什么时候刷到磁盘中的呢?mysql通过sync_binlog参数控制biglog的刷盘时机,取值范围是0-N:

0:先写入 os cache,由系统自行判断何时写入磁盘,宕机数据会丢失;(MySQL 5.7.7之前版本的默认值)
1:每次commit的时候都要将binlog写入磁盘;(MySQL 5.7.7之后版本的默认值)
N:每N个事务,才会将binlog写入磁盘。

bin log是在什么时候记录数据的呢?
其实 MySQL 在提交事务的时候,

不仅仅会将 redo log buffer 中的数据写入到redo log 文件中,同时也会将本次修改的数据记录到 bin log文件中,
也会将本次修改的bin log文件名和修改的内容在bin log中的位置记录到redo log中,
最后还会在redo log最后写入 commit 标记,表示**事务成功提交**了

  • 只要redo log最后没有 commit 标记,说明本次的事务一定是失败的
  • 但是数据没有丢失,因为已经被记录到redo log的磁盘文件中了。在 MySQL 重启的时候,就会将 redo log 中的数据恢复(加载)到Buffer Pool中

其实 MySQL 会有一个后台线程,它会在某个时机将我们Buffer Pool中的脏数据刷到 MySQL 数据库中,这样就将内存和数据库的数据保持统一了。

redo日志与bin日志的区别

redo log是 InnoDB 存储引擎特有的日志文件,而bin log属于是 MySQL 级别的日志

redo log记录的东西是偏向于物理性质的,如:“对什么数据,做了什么修改”。

bin log是偏向于逻辑性质的,类似于:“对 students 表中的 id 为 1 的记录做了更新操作” 两者的主要特点总结如下:

 

性质redo Logbin Log
文件大小 redo log 的大小是固定的(配置中也可以设置,一般默认的就足够了) bin log 可通过配置参数max_bin log_size设置每个bin log文件的大小(但是一般不建议修改)。
实现方式 redo log是InnoDB引擎层实现的(也就是说是 Innodb 存储引起过独有的) bin log是 MySQL 层实现的,所有引擎都可以使用 bin log日志
记录方式 redo log 采用循环写的方式记录,当写到结尾时,会回到开头循环写日志。 bin log 通过追加的方式记录,当文件大小大于给定值后,后续的日志会记录到新的文件上
使用场景 redo log适用于崩溃恢复(crash-safe)(这一点其实非常类似与 Redis 的持久化特征) bin log 适用于主从复制和数据恢复

 

本文总结

Buffer Pool 是 MySQL 的一个非常重要的组件,因为针对数据库的增删改操作都是在 Buffer Pool 中完成的
Undo log 记录的是数据操作前的样子
redo log 记录的是数据被操作后的样子(redo log 是 Innodb 存储引擎特有)
bin log 记录的是整个操作记录(这个对于主从复制具有非常重要的意义)

准备更新到事务提交全过程

 

posted @ 2022-09-13 20:15  Allfuture  阅读(92)  评论(0编辑  收藏  举报