MySQL 日志
· redo log //重做日志
· undo log //回滚日志
· bin log //二进制日志
· error log //错误日志
· slow queryl og //慢查询日志
· general log // 一般查询日志
· relay log //中继日志
redo log
作用
- 确保事务的持久性。
- 防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性。
内容
物理格式的日志,记录的是物理数据页面的修改信息,是顺序写入 redo log file 中去的
开始写入时间
事务开始之后就开始写,而不是事务提交前。重做日志有一个缓存区Innodb_log_buffer,Innodb_log_buffer的默认大小为8M,Innodb存储引擎先将重做日志写入innodb_log_buffer。
写入方式
- 通过以下三种方式将innodb日志缓冲区的日志刷新到磁盘 · 1,Master Thread 每秒一次执行刷新Innodb_log_buffer到重做日志文件。 · 2,每个事务提交时会将重做日志刷新到重做日志文件。 · 3,当重做日志缓存可用空间 少于一半时,重做日志缓存被刷新到重做日志文件 · 由此可以看出,重做日志通过不止一种方式写入到磁盘,尤其是对于第一种方式,Innodb_log_buffer到重做日志文件是Master Thread线程的定时任务。 因此重做日志的写盘,并不一定是随着事务的提交才写入重做日志文件的,而是随着事务的开始,逐步开始的。
undo log
作用
- 保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读
内容
逻辑格式的日志,在执行undo的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,这一点是不同于redo log的。
产生时间
事务开始之前,将当前是的版本生成undo log,undo 也会产生 redo 来保证undo log的可靠性
释放时间
当事务提交之后,undo log并不能立马被删除, 而是放入待清理的链表,由purge线程判断是否由其他事务在使用undo段中表的上一个事务之前的版本信息,决定是否可以清理undo log的日志空间。
其他
undo是在事务开始之前保存的被修改数据的一个版本,产生undo日志的时候,同样会伴随类似于保护事务持久化机制的redolog的产生。 默认情况下undo文件是保持在共享表空间的,也即ibdatafile文件中,当数据库中发生一些大的事务性操作的时候,要生成大量的undo信息,全部保存在共享表空间中的。 因此共享表空间可能会变的很大,默认情况下,也就是undo 日志使用共享表空间的时候,被“撑大”的共享表空间是不会也不能自动收缩的。 因此,mysql5.7之后的“独立undo 表空间”的配置就显得很有必要了。
bin log
作用
1,用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步。
2,用于数据库的基于时间点的还原。
内容
逻辑格式的日志,可以简单认为就是执行过的事务中的sql语句。 但又不完全是sql语句这么简单,而是包括了执行的sql语句(增删改)反向的信息, 也就意味着delete对应着delete本身和其反向的insert;update对应着update执行前后的版本的信息;insert对应着delete和insert本身的信息。 在使用mysqlbinlog解析binlog之后一些都会真相大白。 因此可以基于binlog做到类似于oracle的闪回功能,其实都是依赖于binlog中的日志记录。
产生时间
事务提交的时候,一次性将事务中的sql语句(一个事物可能对应多个sql语句)按照一定的格式记录到binlog中。 这里与redo log很明显的差异就是redo log并不一定是在事务提交的时候刷新到磁盘,redo log是在事务开始之后就开始逐步写入磁盘。 因此对于事务的提交,即便是较大的事务,提交(commit)都是很快的,但是在开启了bin_log的情况下,对于较大事务的提交,可能会变得比较慢一些。 这是因为binlog是在事务提交的时候一次性写入的造成的,这些可以通过测试验证。
释放时间
binlog的默认是保持时间由参数expire_logs_days配置,也就是说对于非活动的日志文件,在生成时间超过expire_logs_days配置的天数之后,会被自动删除。
其他
- 二进制日志的作用之一是还原数据库的,这与redo log很类似,很多人混淆过,但是两者有本质的不同
1,作用不同:redo log是保证事务的持久性的,是事务层面的,binlog作为还原的功能,是数据库层面的(当然也可以精确到事务层面的),虽然都有还原的意思,但是其保护数据的层次是不一样的。
2,内容不同:redo log是物理日志,是数据页面的修改之后的物理记录,binlog是逻辑日志,可以简单认为记录的就是sql语句
3,另外,两者日志产生的时间,可以释放的时间,在可释放的情况下清理机制,都是完全不同的。
4,恢复数据时候的效率,基于物理日志的redo log恢复数据的效率要高于语句逻辑日志的binlog
关于事务提交时,redo log和binlog的写入顺序,为了保证主从复制时候的主从一致(当然也包括使用binlog进行基于时间点还原的情况),是要严格一致的, MySQL通过两阶段提交过程来完成事务的一致性的,也即redo log和binlog的一致性的,理论上是先写redo log,再写binlog,两个日志都提交成功(刷入磁盘),事务才算真正的完成。
relay log

区别与联系
-
innodb引擎中的redo/undo log与mysql binlog是完全不同的日志,它们主要有以下几个区别:
· 1、层次不同,redo/undo 是indodb层维护的,而binlog是mysql server层维护的,跟采用何种引擎没有关系,记录的是所有引擎的更新操作的日志记录
· 2、记录内容不同,redo/undo记录的是每个页的修改情况,属于物理加逻辑的方式(redo log到物理页,页内采用逻辑日志,undo log采用的是逻辑日志),目的是保证数据的一致性,binlog记录的是事物操作内容,比如一条语句DELETE FROM TABLE WHERE i > 1之类的,不管采用的是什么引擎,当然格式是二进制的,要解析日志内容可以用这个命令mysqlbinlog -vv BINLOG。
· 3、记录时机不同,redo/undo在事物执行过程中会不断的写入,binlog是在事物最终commit前写入,binlog什么时候刷新到磁盘跟参数sync_binlog相关。
显然,我们执行SELECT等不涉及数据更新的语句是不会记binlog的,而涉及到数据更新则会记录。要注意的是,对支持事务的引擎如innodb而言,必须要提交了事务才会记录binlog。
binlog刷新到磁盘的时机跟sync_binlog参数息息相关,如果此参数配置为0,表示MySQL不控制binlog的刷新,则直接由文件系统决定什么时候刷新到磁盘,如果设置为不为0,则表示隔多少个事物刷新到磁盘,设置为1是最安全,在系统故障时最多丢失一个事务的更新,但是会对性能有所影响。一般情况下会设置为100或者0,牺牲一定的一致性来获取更好的性能。