为什么有了binlog还要有redo log?
- binlog会记录所有与MySQL数据库有关的日志记录,包括InnoDB, MyISAM,Heap等其他存储引起的日志。而redo log只记录innodb引擎本身的日志。
- binlog记录的是关于一个事务的具体操作内容,即该日志是逻辑日志。而redolog记录的是关于每个页的更改的物理情况。
- 写入时间不同。binlog仅在事务提交前提交,只写磁盘一次,不论这个事务有多大。而redolog在事务进行过程中会不停的写入。
它们分工是不同的。binlog用来做数据归档,但不具备崩溃恢复的能力,也就是说如果系统突然崩溃,重启后可能会有部分数据丢失。
innodb将所有对页面的修改操作写入一个专门的文件,并在数据库启动时从此文件进行恢复操作。
redolog扩展:
每个innodb引擎至少有1个重做日志文件组(group),每个文件组下面至少有2个重做日志文件。为了提高可靠性,可以设置多个组,放到不同的磁盘中。在日志组中每个重做日志文件大小一致,并以循环写入的方式运行。先写入文件1,写满后写入文件2,2写满再切换到1.
写入redolog不是直接写磁盘,而是先写入一个重做日志缓冲(redo log buffer),然后按一定的条件写入。
所谓的条件:
- 主线程每秒刷新
- 其实是基于配置的:
参数: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存储引擎·机械工业出版社