文章目录
1. redo log(重做日志)
redo log叫做重做日志,记录InnoDB的更改后的值,用来恢复数据(数据库宕机后数据恢复)。redo log用于保证已经提交事务的持久性。
redo log是用来恢复数据的 用于保障,已提交事务的持久化特性
redo log有两种类型:
- 位于内存中 redo log buffer 重做日志缓冲,类似于之前的缓冲池用于提升性能
- 位于磁盘中 redo log 重做日志文件,最终持久化的地方。
记录redo log的时机:
事务开始之后就产生redo log,redo log的落盘并不是随着事务的提交才写入的,而是在事务的执行过程中,便不断写入redo log文件中。
缓冲写入磁盘时机:
-
redo log buffer的日志占据redo log buffer总容量的一半
-
一个事务提交时 ,他的redo log都刷入磁盘
-
后台线程定时刷新
-
MySQL关闭时 ,redo log都被写入磁盘
释放redo log的时机:
当对应事务的脏页写入到磁盘之后,redo log的使命也就完成了,重做日志占用的空间就可以重用(被覆盖)。
redo log存储结构
innodb存储引擎中,redo log以块为单位进行存储的,每个块占512字节。redo log block由3部分组成:日志块头、日志块尾和日志主体
innodb恢复行为
无论是正常或宕机重启,则innodb都会通过重做日志进行恢复,基于checkpoint的LSN,通过对比磁盘的数据页LSN找到redo log对应LSN 从而进行恢复,最后扫描binglog日志对于Prepare状态的事务,如果该事务对应的binlog已经记录,则提交,否则回滚事务。
2. undo log(撤销日志)
undo log叫做撤销日志,undo log存在的意义是确保数据库事务的原子性
- 对记录做了变更操作的时候就需要产生undo log,其中记录的是老版本的数据,当旧事务需要读取数据时,可以顺着undo链找到满足其可见性的记录。
- undo log通常以逻辑日志的形式存在。我们可以认为当delete一条记录时,undo log会产生一条对应的insert记录,反之亦然。当update一条记录时,会产生一条相反的update记录。
- **undo log采用段segment的方式来记录,每个undo操作在记录的时候占用一个undo log segment。
- 存放在rollback segment(回滚段)中每个回滚段中有1024个undo log segment
- undo log也会产生redo log,因为undo log也要实现持久性保护。
- undo log 也有对应的buffer分为:插入撤消缓冲区和更新撤消缓冲区。
- Undo记录中存储的是老版本数据,当一个旧的事务需要读取数据时,为了能读取到老版本的数据,需要顺着undo链找到满足其可见性的记录,这是InnoDB各种读(脏读、不可重复读、幻读)的体现。
purge操作
innodb中delete语句是在改记录中设置delete_flag =1 同理update操作是旧记录设置删除标识,再创建一条新记录。InnoDB使用undo日志进行旧版本的删除操作,这个操作称为purge操作。
3. bin log(二进制日志)
binlog 二进制日志文件,这个文件记录了MySQL所有的DML操作(或者内容)。通过binlog日志我们可以做数据恢复,增量备份,主主复制和主从复制等等。
不管用什么存储引擎,只要发生了表数据更新,都会产生 binlog 日志,与存储引擎无关,一旦缓冲池 或者磁盘产生数据则即会生成二进制日志。
binlog的模式有三种:STATEMENT、ROW、MIXED 。
1、STATMENT模式:基于SQL语句的复制,每一条会修改数据的sql语句会记录到binlog中。
优点:不需要记录每一条SQL语句与每行的数据变化,这样子binlog的日志也会比较少,减少了磁盘IO,提高性能。
缺点:在某些情况下会导致master-slave(主从复制模式)中的数据不一致(如sleep(暂停指定时间执行)函数, last_insert_id(自增)等情况下会出现问题)
2、ROW模式:基于行的复制,不记录每一条SQL语句的上下文信息,仅记录哪条数据被修改了,修改后的结果是什么
优点:不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。
缺点:会产生大量的日志,尤其是alter table的时候会让日志暴涨。
3、MIXED模式,混合模式的复制方式:如上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的相关操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式。
三种log添加时机
在概念上,innodb通过***force log at commit***机制实现事务的持久性,即在事务提交的时候,必须先将该事务的所有事务日志写入到磁盘上的redo log file和undo log file中进行持久化。
从redo log buffer写日志到磁盘的redo log file中,过程如下:
4. bin log 与redo log的区别
- 记录的范围不同
- binlog,是基于MySQL数据库的,记录InnoDB、MYISAM等所有存储引擎的修改记录。
- redo log,只记录跟InnoDB有关的事务日志
- 记录的内容不同
- binlog是逻辑日志,记录的是 ROW 或 STATEMENT ,具体的操作内容,或完整的sql。
- redo log是物理日志,记录的是页的修改信息。例如:偏移量80,写‘ddd’操作。
- 写入时间不同
- binlog,只在事务提交前进行写入,不论事务多大,只写入一次
- redo log,在事务进行过程中,不断被写入重做日志文件中。
- 日志文件本身
- binlog:MySQL服务重启、FLUSH LOGS、超过文件大小都会切换新的日志文件。文件名会递增+1
- redo log,默认只有一个组,组内有两个重做日志,ib_logfile0 和 id_logfile1。循环写入,不会增加
- 释放时间不同
- binlog:binlog的默认是保持时间由参数expire_logs_days配置,也就是说对于非活动的日志文件,在生成时间超过expire_logs_days配置的天数之后,会被自动删除。默认为0,不自动删除
- redo log:对应事务的脏页刷新到磁盘后,该事务所占的空间就可以被覆盖。可以理解为被释放。Write指针会覆盖这段空间。
- 文件大小限制
- binlog的最大限制不严格,假设临近最大值,来了一个大事务,此时不会截断该事务的日志。会完整的记录到二进制文件中。允许超过最大限制。
- redo log是循环利用的,所以,一旦超过文件限定大小,便切换另一个重做日志
- 作用不同
- binlog作为还原的功能,是数据库层面的(当然也可以精确到事务层面的),虽然都有还原的意思,但是其保护数据的层次是不一样的,主要用于主从复制、POING-IN-TIME的恢复和审计
- redo log是保证事务的持久性的,是事务层面的。
- 恢复数据的效率不同
- redo log是记录页的修改信息,恢复效率高于bin log
- 幂等性
- undo log具有幂等性,所以多次操作得到同一结果的行为在日志中只记录一次。
- bin log不具有幂等性,多次操作会全部记录下来,在恢复的时候会多次执行二进制日志中的记录,速度就慢得多。
- 例如,某记录中id初始值为2,通过update将值设置为了3,后来又设置成了2,在事务日志中记录的将是无变化的页,根本无需恢复;而二进制会记录下两次update操作,恢复时也将执行这两次update操作,速度比事务日志恢复更慢。
二、change buffer
1. 简介
更改缓冲区是一种特殊的数据结构,数据不在缓冲池中时在不影响数据一致性的前提下,InooDB 会将这些更新操作缓存在 change buffer 中。
缓冲的更改可能由插入、更新或删除操作(DML)引起,稍后当其他读取操作将页面加载到缓冲池中时,这些更改会被合并。或满足一定条件时,合并成一次IO,刷新到磁盘上。