bin log是MySQL server层记录的日志,所有存储引擎都可以使用该日志。undo log 和 redo log是InnoDB存储引擎的日志。

1. bin log

二进制日志(binary log),简称bin log,以事件的形式记录了对MySQL数据库执行更改的所有操作,还包括了执行数据库更改操作的时间等其他额外信息。bin log主要有以下两种作用:

  • 恢复:使用mysqlbinlog工具来恢复数据,其实就是使用mysqlbinlog工具将保存在bin log文件中的sql语句再执行一遍。
  • 复制:主服务器通过将bin log发送给从服务器来达到主从复制的目的。

命令

查看bin log存储目录:show global variables like '%log_bin%';
查看bin log日志列表:show master logs;
查看master状态,即(最新)一个binlog日志:show master status;
查看bin log记录的事件:show binlog events in 'xxxx';

使用mysqlbinlog查看日志文件内容:
mysqlbinlog --start-position=444 ../data/binlog.000003 -v
image.png

写磁盘

bin log什么时候同步到磁盘与参数sync_binlog有关:

  • sync_binlog = 1 表示采用同步磁盘的方式来写二进制文件。
  • sync_binlog = 0 表示由文件系统去控制缓存的刷盘时机。
  • sync_binlog = n 表示每写缓冲n次就同步到磁盘。

当sync_binlog=0或者n时,如果数据库所在的机器发生宕机,可能会有最后一部分数据没有写入到bin log文件中,会造成数据的不一致。所以推荐将该值设为1。在MySQL 5.7.7之前,sync_binlog的默认值是0,MySQL 5.7.7和更高版本使用默认值1。

日志格式

bin log有三种可选的格式,由binlog_format参数指定,分别是:

  • STATEMENT:记录的是逻辑SQL语句。
  • ROW:记录表的行更改情况
  • MIXED:默认采用STATEMENT格式进行bin log文件的记录,但是在一些特殊情况下会使用ROW格式。

2. redo log

重做日志(redo log),主要用于保证事务的持久性,例如,当数据库所在机器宕机时,InnoDB会使用重做日志将数据恢复到断电前的时刻。

缓冲池

InnoDB存储引擎是基于磁盘存储的,由于CPU速度和磁盘速度之间存在很大差距,所有基于磁盘的数据库系统通常会使用缓冲池技术来提高数据库的整体性能。在数据库中进行读取页的操作,会先将磁盘中读取到的页放到缓冲池中,下一次再读取相同的页时,会直接从缓冲池读取。对于数据库中的页的修改操作,首先会修改缓冲池中的页,再以一定的频率刷新到磁盘上。
如果每次一个页放生变化,就把页刷新到磁盘,这个开销是非常大的,而且如果在刷新到磁盘时发生了宕机,那么缓冲池中的数据就不能恢复了。为了避免数据丢失的问题,当前事务数据库系统普遍采用了Write Ahead Log策略,即当事务提交时,先写重做日志,再修改页。如果发生了宕机,就可以用重做日志来将数据恢复成宕机前的状态。

写磁盘

重做日志由两部分组成:一是内存中的重做日志缓冲,其是易失的;二是重做日志文件,其是持久的。

有两种情况会将重做日志缓冲写入磁盘的重做日志文件中:

  1. 主线程每秒会将重做日志缓冲写入重做日志文件,不论事务是否已经提交。
  2. 由参数innodb_flush_log_at_trx_commit控制在事务提交时,处理重做入职的方式

innodb_flush_log_at_trx_commit的取值:

  • 0:代表提交事务时不将重做日志缓冲写入重做日志文件,而是交由主线程去做。
  • 1:表示在执行事务提交时将重做日志缓冲同步写到磁盘,即会调用fsync。
  • 2:表示将重做日志缓冲异步写到磁盘,即写到文件系统的缓冲。

为了确保事务的持久性,当事务提交时,必须将该事务的重做日志写入到重做日志文件进行持久化,所以innodb_flush_log_at_trx_commit的值必须设为1。

3. undo log

undo log主要用作事务的回滚操作以及MVCC,如果用户执行的事务或语句由于某种原因失败了,或者通过rollback语句请求回滚,就可以使用undo log中记录的信息将数据回滚到修改之前的样子。当进行回滚操作时,实际上做的是与先前相反的工作,对于每个insert,会执行一个相反delete;对于每个delete,会执行一个相反的insert;对于每个update,会执行一个相反的update。
undo log 的另一个作用是帮助实现innodb存储引擎中的MVCC,当用户读取一行记录时,若该记录已经被其他事务占用,当前事务可以通过undo读取之前的版本信息,以此实现非锁定读取。

4. bin log 和 redo log区别

第一,bin log记录所有与MySQL数据库有关的日志,是server层产生的;redo log是InnoDB存储引擎特有的,仅记录InnoDB存储引擎有关的事务日志。

第二**,记录的内容不容,bin log记录的是关于一个事务的具体操作内容,即该日志是逻辑日志;redo log记录的是关于每个页的更改的物理情况。

第三,写入的时间不同,bin log仅在事务提交前进行提交,即只写磁盘一次。而redo log是在事务进行的过程中不断被写入的。

第四,redo log是可以循环使用的,空间一般是固定的;bin log是追加写入的,在写到一定大小之后会切换下一个,不会去覆盖之前的日志。