1、redo log(重做日志)和 binlog(归档日志)的区别
与执行流程不一样的地方是,更新了流程还涉及两个重要的日志模块:① redo log (重做日志);② binlog (归档日志) 。 它们有三点不同:
- redo log 是 InnoDB 引擎特有的日志,而 binlog 是 Server 层的日志,所有引擎都可以使用。(MySQL 整体来看,有两块:一块是 Server 层,主要做的是 MySQL 功能层面的事;还有一块是引擎层,负责存储相关的事情)
- redo log 是物理日志,记录的是在某个数据页上做了什么修改;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如给 id = 2 这行的 a 字段加 1 。
- redo log 是循环写的,空间固定 会用完;binlog 是可以追加写入的,也就是写到一定大小后会切换到下一个,并不会覆盖以前的日志。
- redo log 是两阶段提交的,在更新数据时,先将新数据更新到内存中,同时将更新操作 记录到 redo log 里,此时 redo log 处于 prepare 状态;然后生成这个操作的 binlog,并将 binlog 写入磁盘;最后将 redo log 改成提交状态,更新完成。这么做的目的是让两份日志的逻辑一致
2、redo log 原理 (InnoDB 引擎特有的日志)
在Mysql中如果每次更新操作都需要写进磁盘,磁盘也要找到对应的那条记录,然后再更新,这样的话整个IO成本、查找成本都很高。为了解决这个问题,Mysql采用了 WAL(Write - Ahead Logging)技术,它的关键点是先写日志,再写磁盘。比如当有一条记录需要更新时,InnoDB 引擎就会先把记录写到 redo log 日志中,并更新内存,这个时候更新就算完成了。然后 InnoDB 引擎会在系统比较空闲的时候,再将这个操作记录更新到磁盘里。所以InnoDB 还可以保证即使数据库发生异常重启,之前提交的记录也不会丢失,可以通过 redo log 日志找回。
InnoDb 的 redo log 是固定大小的,比如可以配置为一组4个文件,每个文件的大小是 1GB,那么总共就可以记录 4GB 的操作,写的时候是从头开始写,写到末尾就又回到开头循环写
- write pos 是当前记录的位置,一边写一边往后移,写到3号文件的末尾时就回到0号文件的开头
- checkpoint 是当前要擦除的位置,也是往后推移并且循环,擦除记录前要把记录更新到数据文件
- write pos 和 checkpoint 之间代表的是空闲部分,用来记录新的操作,如果 write pos 追上了 checkpoint,就表示文件已存满记录,此时就不能执行新的更新了,得停下来先擦掉一些记录,把 checkpoint 推进一下
有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失
3、binlog (Server 层的日志)
binlog 的使用场景是:主从复制 和 数据恢复
- 主从复制:在 Master 端开启 binlog ,然后将 binlog 发送到各个 Slave 端, Slave 端重放 binlog 从而达到主从数据一致。
- 数据恢复 :重放 binlog 来恢复数据。
4、相关配置参数
- redo log :innodb_flush_log_at_trx_commit 控制写入 redo log file 的时机
- binlog :sync_binlog 控制刷盘时机
- 0:不去强制要求,由系统自行判断何时写入磁盘;
- 1:每次 commit 的时候都要将 binlog 写入磁盘;
- N:每N个事务,才会将 binlog 写入磁盘。