重要日志模块
-
- 日志文件
-
- [bin log](#bin log)
- [redo log](#redo log)
-
- [**关于循环写入和擦除的checkpoint 规则**](#关于循环写入和擦除的checkpoint 规则)
- [redo log 怎么刷入磁盘的](#redo log 怎么刷入磁盘的)
- [binlog 和 redo log 有什么区别?](#binlog 和 redo log 有什么区别?)
- [undo log](#undo log)
日志文件
- 错误日志(error log): 错误日志文件对 MySQL 的启动、运行、关闭过程进行了记录,能帮助定位 MySQL 问题。
- 慢查询日志(slow query log): 慢查询日志是用来记录执行时间超过 long_query_time 这个变量定义的时长的查询语句。通过慢查询日志,可以查找出哪些查询语句的执行效率很低,以便进行优化。
- 一般查询日志(general log): 一般查询日志记录了所有对 MySQL 数据库请求的信息,无论请求是否正确执行。
- 二进制日志(bin log): 关于二进制日志,它记录了数据库所有执行的 DDL 和 DML 语句(除了数据查询语句 select、show 等),以事件形式记录并保存在二进制文件中。
还有两个 InnoDB 存储引擎特有的日志文件:
- 重做日志(redo log): 重做日志至关重要,因为它们记录了对于 InnoDB 存储引擎的事务日志。
- 回滚日志(undo log): 回滚日志同样也是 InnoDB 引擎提供的日志,顾名思义,回滚日志的作用就是对数据进行回滚。当事务对数据库进行修改,InnoDB 引擎不仅会记录 redo log,还会生成对应的 undo log 日志;如果事务执行失败或调用了 rollback,导致事务需要回滚,就可以利用 undo log 中的信息将数据回滚到修改之前的样子。
bin log
-
bin log(归档日志)是Server层实现的,所有引擎都可以使用。bin log是逻辑日志,记录的是这个语句的原始逻辑,比如:"给ID=2这一行的c字段加1"
-
bin log 是追加写入的,"追加写"指的是bin log 文件写到一定大小后会切换下一个,并不会覆盖以前的日志。
-
bin log 只在事务提交前进行提交,也就是只写磁盘一次。
redo log
- redo log 是InnoDB引擎特有的,只记录InnoDB存储引擎的日志。
- redo log 是物理日志,记录的是关于每个页(Page)的更改的物理情况。
- redo log是固定大小的,它是循环写入和擦除的。
- bin log 在事务进行的过程中,不断有redo ertry被写入redo log中。
关于循环写入和擦除的checkpoint 规则
重做日志缓存、重做日志文件都是以块(block)的方式进行保存的,称之为重做日志块(redo log block),块的大小是固定的 512 字节。我们的 redo log 它是固定大小的,可以看作是一个逻辑上的 log group
,由一定数量的log block
组成。
它的写入方式是从头到尾开始写,写到末尾又回到开头循环写。
其中有两个标记位置:
write pos
是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。checkpoin
t是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到磁盘。
write pos
和checkpoin
t之间的是空着的部分,可以用来记录新的操作。如果write pos
追上checkpoint
,表示 redo log 日志已经写满。这时候就不能接着往里写数据了,需要执行checkpoint规则 腾出可写空间,把checkpoint
推进一下。
所谓的checkpoint 规则,就是 checkpoint 触发后,将 buffer 中日志页都刷到磁盘。
有了redo log,InnoDB就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为crash-safe.
redo log 怎么刷入磁盘的
redo log 的写入不是直接落到磁盘,而是在内存中设置了一片称之为redo log buffer
的连续内存空间,也就是redo 日志缓冲区
。
什么时候会刷入磁盘?
在如下的一些情况中,log buffer 的数据会刷入磁盘:
-
log buffer 空间不足时
log buffer 的大小是有限的,如果不停的往这个有限大小的 log buffer 里塞入日志,很快它就会被填满。如果当前写入 log buffer 的 redo 日志量已经占满了 log buffer 总容量的大约一半左右,就需要把这些日志刷新到磁盘上。
-
事务提交时
在事务提交时,为了保证持久性,会把 log buffer 中的日志全部刷到磁盘。注意,这时候,除了本事务的,可能还会刷入其它事务的日志。
-
后台线程输入
有一个后台线程,大约每秒都会刷新一次log buffer中的redo log到磁盘。
-
正常关闭服务器时
-
触发 checkpoint 规则
binlog 和 redo log 有什么区别?
- bin log 会记录所有与数据库有关的日志记录,包括 InnoDB、MyISAM 等存储引擎的日志,而 redo log 只记 InnoDB 存储引擎的日志。
- 记录的内容不同,bin log 记录的是关于一个事务的具体操作内容,即该日志是逻辑日志。而 redo log 记录的是关于每个页(Page)的更改的物理情况。
- 写入的时间不同,bin log 仅在事务提交前进行提交,也就是只写磁盘一次。而在事务进行的过程中,却不断有 redo ertry 被写入 redo log 中。
- 写入的方式也不相同,redo log 是循环写入和擦除,bin log 是追加写入,不会覆盖已经写的文件。
undo log
Undo Log是InnoDB十分重要的组成部分,它的作用横贯InnoDB中两个最主要的部分,并发控制(Concurrency Control)和故障恢复(Crash Recovery).
-
undo log是一种用于撤销回退的日志,在事务没提交之前,MySQL会先记录更新前的数据到 undo log日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退。
-
与 redo log 用于数据的灾后重新提交不同,undo log 主要用于数据修改的回滚。
-
与 redo log 记录的是物理页的修改不同,undo log 记录的是逻辑日志。
-
数据库事务四大特性中有一个是原子性,具体来说就是 原子性是指对数据库的一系列操作,要么全部成功,要么全部失败,不可能出现部分成功的情况。
实际上,原子性底层就是通过undo log实现的。当 delete 一条记录时,undo log 中会记录一条对应的 insert 记录,反之亦然,当 update 一条记录时,它记录一条对应相反的 update 记录,如果 update 的是主键,则是对先删除后插入的两个事件的反向逻辑操作的记录。