1、redo log(重做日志——InnoDB独有,让InnoDB
存储引擎拥有了崩溃恢复能力。)
MySQL 有个问题,如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程 IO 成本、查找成本都很高,为了解决这个问题,引入redo log。MySQL的WAL
( Write-Ahead Logging
)技术,它的关键点就是先写日志,再写磁盘。
当有一条数据需要更新,InnoDB 引擎就会先把记录写到 redo log 里面,并更新内存。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做。
InnoDB 的 redo log 是固定大小的,默认单个文件只有50 MB,3个日志文件循环写,容易导致日志频繁切换,因此建议调整。比如可以配置为一组 4 个文件,每个文件的大小是 1 GB,那么总共可以记录 4 GB 的操作。从头开始写,写到末尾就又回到开头循环写,如下面这个图所示:
1、write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。
2、checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到磁盘。write pos 和 checkpoint 之间的是空着的部分,可以用来记录新的操作。
3、如果 write pos 追上 checkpoint,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推进一下。
有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为 crash-safe。
2、binlog(归档日志——保证了MySQL
集群架构的数据一致性)
MySQL 整体来看,其实就有两块:一块是 Server 层,它主要做的是 MySQL 功能层面的事情;还有一块是引擎层,负责存储相关的具体事宜。上面我们聊到的粉板 redo log 是 InnoDB 引擎特有的日志,而 Server 层也有自己的日志,称为 binlog(归档日志)。
因为最开始 MySQL 里并没有 InnoDB 引擎。MySQL 自带的引擎是 MyISAM,但是 MyISAM 没有 crash-safe 的能力,binlog 日志只能用于归档。而 InnoDB 是另一个公司以插件形式引入 MySQL 的,只依靠 binlog 是没有 crash-safe 能力的,所以 InnoDB 使用另外一套日志系统 redo log 来实现 crash-safe 能力。
MySQL
数据库的数据备份、主备、主主、主从都离不开binlog
,需要依靠binlog
来同步数据,保证数据一致性。
redo log 与 binlog 区别:
1、redo log 是 InnoDB 引擎特有的;binlog 是 Server 层实现的,所有引擎都可以使用。
2、redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 id=2 这一行的 c 字段加 1 ”。
3、redo log 是循环写的,空间固定会用完;binlog 是可以追加写。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
4、在执行更新语句过程,会记录redo log
与binlog
两块日志,以基本的事务为单位,redo log
在事务执行过程中可以不断写入,而binlog
只有在提交事务时才写入,所以redo log
与binlog
的写入时机不一样。(redo log 两阶段提交,将 redo log 的写入拆成了两个步骤:prepare 和 commit;redo log 和 binlog 都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保持逻辑上的一致。)
3、undo log(回滚日志——提供回滚操作、提供多版本并发控制 MVCC)
undo log是一种用于撤销回退的日志,在事务没提交之前,MySQL 会先记录更新前的数据到 undo log日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退。原子性底层就是通过 undo log实现的。
undo log主要记录了数据的逻辑变化,比如一条INSERT语句,对应一条DELETE的undo log,对于每个UPDATE语句,对应一条相反的UPDATE的 undo log,这样在发生错误时,就能回滚到事务之前的数据状态。
undo log 的存储由 InnoDB 存储引擎实现,数据保存在 InnoDB 的数据文件中。在 InnoDB 存储引擎中,undo log 是采用分段(segment)的方式进行存储的。rollback segment 称为回滚段,每个回滚段中有 1024 个 undo log segment。在 MySQL 5.5之前,只支持1个 rollback segment,也就是只能记录 1024 个 undo 操作。在MySQL 5.5之后,可以支持 128 个 rollback segment,分别从 resg slot0 - resg slot127,每一个resg slot,也就是每一个回滚段,内部由1024个undo segment 组成,即总共可以记录128 * 1024个undo操作。