天天看点

为什么有了binlog还要有redo log

为什么有了binlog还要有redo log?

  1. binlog会记录所有与MySQL数据库有关的日志记录,包括InnoDB, MyISAM,Heap等其他存储引起的日志。而redo log只记录innodb引擎本身的日志。
  2. binlog记录的是关于一个事务的具体操作内容,即该日志是逻辑日志。而redolog记录的是关于每个页的更改的物理情况。
  3. 写入时间不同。binlog仅在事务提交前提交,只写磁盘一次,不论这个事务有多大。而redolog在事务进行过程中会不停的写入。

它们分工是不同的。binlog用来做数据归档,但不具备崩溃恢复的能力,也就是说如果系统突然崩溃,重启后可能会有部分数据丢失。

innodb将所有对页面的修改操作写入一个专门的文件,并在数据库启动时从此文件进行恢复操作。

redolog扩展:

每个innodb引擎至少有1个重做日志文件组(group),每个文件组下面至少有2个重做日志文件。为了提高可靠性,可以设置多个组,放到不同的磁盘中。在日志组中每个重做日志文件大小一致,并以循环写入的方式运行。先写入文件1,写满后写入文件2,2写满再切换到1.

写入redolog不是直接写磁盘,而是先写入一个重做日志缓冲(redo log buffer),然后按一定的条件写入。

所谓的条件:

  1. 主线程每秒刷新
  2. 其实是基于配置的:

    参数:innodb_flush_log_at_trx_commit

    值:0、1、2 (0-表示事务提交的时候,不主动将事务的重做日志写入磁盘,而是等待主线程刷新;1- 事务提交,将重做日志刷入磁盘,并伴有fsync调用;2- 将重做日志异步写入磁盘,即写入到文件系统的缓存中。因此并不能完全保重写入到磁盘)

    为了保证事务的持久性,应该将innodb_flush_log_at_trx_commit设置为1。

其他影响redolog的参数

  • innodb_log_file_size 指定每个重做日志文件大小
  • innodb_log_files_in_group 指定了日志文件组中重做日志文件的数量,默认为2;
  • innodb_mirrored_log_groups 指定了日志镜像文件组的数量,默认为1,表示只有一个日志文件组,没有镜像。若磁盘本身有高可用方案,可不开启镜像。
  • innodb_log_group_home_dir 指定了日志文件组所在路径,默认为./ 表示在MYSQL数据目录下。

binlog扩展:

binnlog记录数据库执行更改的操作。默认关闭,需要手动开启。

影响binlog的参数

  • max_binlog_size: 单个二进制日志文件的最大值,如果超过这个值,产生新的二进制文件,后缀名+1;
  • binlog_cache_size: 当数据库使用支持事务的存储引擎(例如innodb),所有未提交的二进制日志会被记录到缓存中,等待事务提交时直接写到文件中。这个缓冲区大小是由binlog_cache_size决定的。如果事务记录大于缓冲区大小(默认32k),会写入到临时文件,影响效率。

判断binlog_cache_size是否合适:

mysql> show global status like 'binlog_cache%'

Binlog_cache_disk_use	0
Binlog_cache_use	1
           

如上,Binlog_cache_disk_use为0,使用临时文件次数为0,这个缓冲区够大,不需要增加。

默认binlog不是每次写的时候都同步磁盘(缓冲写),当系统宕机时,可能会有一部分数据没写入binlog中。参数sync_binlog = [N] 表示写入缓冲多少次就同步到磁盘。N=1表示同步写。不会用到操作系统的缓冲。

如果将sync_binlog设置为1,在一个事务发出commit之前,binlog被写入磁盘,这时候宕机,事务没有提交。下次启动的时候,这个事务没有提交,应该回滚,但是binlog被写入磁盘了,就不能回滚。将innodb_support_xa设置为1可以解决这个问题。能确保binlog和redolog文件的同步。

姜承尧·MySQL技术内幕InnoDB存储引擎·机械工业出版社

继续阅读