redo log
概念
概念 : 记录innodb存储引擎的事务日志。当mysql宕机或者断电后innodb存储引擎会使用重做日志恢复之前正常时刻的状态,以此来保证数据的完整性。
实现机制
innoDB 至少有一个重做日志文件组,每个文件组下至少有两个重做日志文件,并以循环写入的方式写入。
重做日志文件的操作不是直接写,而是先写入一个重做日志缓冲(redo log buffer)中,然后按照一定的条件顺序写入日志文件。
从重做日志缓冲写入时按照512个字节(一个扇区)写入。可以保证时必须写入必定时成功的。因此重做日志的写入过程中不需要有doublewrite。
重做日志有个capacity变量,该值代表了最后的检查点不能超过这个阈值,如果超过则必须将缓冲池中脏页列表中的部分脏数据写回磁盘,这时会导致用户现场的阻塞。
两次写 (doublewrite)
在对缓冲池的脏页进行刷新时,并不直接谢磁盘,而是通过memcpy函数将脏页先复制到内存中doublewrite buffer,之后通过double write buffer在分两次每次1Mb顺序的写入共享表空间的物理磁盘上,然后调用fsync函数,同步磁盘,避免缓冲写带来的问题。
结构
- redo_log_type : 占用一个字节,表示日志的类型
- space : 表示空间的ID,但是采用压缩的方式,因此占用的空间可能小于4字节
- page_no : 表示页的偏移量,同样采用压缩的方式
- redo_log_body :表示重做日志的数据部分,回复是需要条用相应的函数进行解析。
配置参数
-
innodb_log_file_size : 指定重做日志文件的大小。
适宜设置大小 大了恢复时间长 过小 频繁发生 saynccheckpoint,导致性能抖动。 -
innoDB_log_files_in_group : 指定了日志文件组中重做日志的数量。默认为2
-
innoDB_mirrored_log_groups : 指定日志镜像文件组的数量,默认为1
-
innoDB_log_group_home_dir : 指定日志文件组所在路径,默认为./ 表示在数据库的数据目录下
-
innodb_flush_log_at_trx_commit :表示在事务提交操作时,处理重做日志的方式。
- 0 代表当提交事务时,不将事务的重做日志写入磁盘上的日志文件,而是等待主线程每秒的刷新。
- 1表示在执行commit时将重做日志缓冲同步写道磁盘,即伴有fsync的调用。
- 2表示将重做日志异步写道磁盘,即写道文件系统的缓存中。因此不能完全保证执行commit时肯定会写入重做日志文件,只是有这个动作发生。
必须设为1 确保事务已经写入重做日志文件。避免宕机后的数据恢复。 0或2都会发生恢复时部分事务的丢失。 设置为2时 数据库宕机而操作系统没宕机,此时写入磁盘的事务日志保存在文件系统缓存中时,可以保证数据不丢失。
binlog
概念
概念 :二进制文件记录了对MySQL数据库执行更改的所有操作,但是不包含select和show这类操作,因为这类操作对数据库本身并没有修改。 mysqlbinlog 仅支持statement格式下的查看。
作用
二进制日志主要有以下几种作用:
- 恢复:某些数据的恢复需要二进制日志。
- 复制:其原理与恢复类似,通过复制和执行二进制日志使一台远程的mysql数据库与一台MySQL数据进行实时同步。
binlog-do-db参数来实现。innoDB默认为可重复读是根据二进制日志文件格式的关系,如果使用已提交读会出现数据丢失更新的现象,从而导致主从数据库数据不一致。 - 审计:用户通过二进制日志中的信息来进行设计,判断是否有对数据库进行注入的攻击。
二进制日志文件默认情况下并没有启动,需要手动指定参数来启动。官方手册中测表明开启后性能下降1%。
过配置参数log-bin[=name]可以启动二进制日志。如果不指定name,则默认为日志文件名为主机名,后缀名为二进制日志的序列号,所在路径为数据库所在目录(datadir)
配置参数
影响二进制日志记录的配置参数:
-
max_binlog_size : 指定单个日志文件的的最大值,
-
binlog_cache_size:所有未提交的二进制日志会被记录到一个缓存中去,等该事务提交时会直接将缓冲中的二进制日志写入二进制日志文件,缓冲大写设定为改参数,默认为32k。
-
sync_binlog : 表示每写缓冲多少次就同步到磁盘。默认值为0
-
binlog-do-db :需要写入那些库的日志,为空则需要同步所有库的日志到二进制日志。
-
binlog-ignore-db:忽略写入那些库的日志。
-
log-slave-update:当前数据是复制中的slave角色,则它不会将从master取得并执行的二进制日志写入自己的二进制日志文件中去。如果需要写入,需要设置该参数。
二进制日志文件的格式
通过binlog_format:指定二进制日志文件的格式。此参数为动态参数
-
statement :逻辑sql语句
-
row : 记录表的行更改情况,如果设置了row,可将事务隔离级别设为读已提交,以获得更好的并发性。产生文件比较大耗费空间,恢复和复制有更好的可靠性。
-
mixed :
- 默认采用statement格式进行二进制日志文件的记录。
- 有一些情况下会使用row格式,可能的情况:
- 存储引擎为ndb,这是表的DML操作都会以ROW格式记录
- 使用UUID(),USER(),CURRENT_USER(),FOUND_ROWS(),ROW_COUNTER等不确定函数
- 使用insert delay语句
- 使用用户定义函数
- 使用临时表
区别V2
-
二进制记录所有相关的日志记录,重做日志只记录innoDB自身的事务日志。
-
二进制文件可以为statement,row,mixed记录的都是具体操作内容即逻辑日志。innoDB记录的是关于每个页的物理情况
-
二进制文件仅在事务提交前进行提交,即只写磁盘一次,不论这时该事务多大。重做日志却是在事务进行的过程中不断的被写入到重做日志文件中。