45讲 第二讲 附加篇

113 阅读6分钟

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记录的是关于每个页的物理情况

  • 二进制文件仅在事务提交前进行提交,即只写磁盘一次,不论这时该事务多大。重做日志却是在事务进行的过程中不断的被写入到重做日志文件中。