binlog
用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。【逻辑日志】
-
逻辑日志
-
由Server层记录和引擎无关
-
应用场景 主从复制和数据恢复
-
追加的方式写入
-
max_binlog_size 设置每个binlog的大小
-
刷机时机 sync_binlog 0(系统决定) 1(每次提交) N (每N次)
-
主从复制
在 Master 端开启 binlog ,然后将 binlog 发送到各个 Slave 端, Slave 端重放 binlog 从而达到主从数据一致。 -
数据恢复
通过使用 mysqlbinlog 工具来恢复数据。
binlog的格式
- STATMENT
基于 SQL 语句的复制( statement-based replication, SBR ),每一条会修改数据的sql语句会记录到 binlog 中 。
缺点:时间或者随机数等不一致 - ROW
基于行的复制( row-based replication, RBR ),不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了 。
缺点:日志暴涨 【alter table 】 - MIXED
基于 STATMENT 和 ROW 两种模式的混合复制( mixed-based replication, MBR ),一般的复制使用 STATEMENT 模式保存 binlog ,对于 STATEMENT 模式无法复制的操作使用 ROW 模式保存 binlog
Redolog
只记录事务对数据页做了哪些修改 【物理日志】
- 实现事务持久性
- InnoDB引擎特有
它记录的是对物理磁盘上数据的修改,因此称之为物理日志
对比每次刷新所有修改的页,redolog提高了性能,将随机IO变成顺序IO,并且文件更小 - 包含内存中的redo log buffer 和磁盘上的redo log,谢谢buffer,合适时机刷新磁盘
- innodb_flush_log_at_trx_commit 0 不落盘 1 写入磁盘 调用fysnc 2 写入磁盘不调用fysnc
- 重做
当进行增删改操作时,MySQL 会在更新 Buffer Pool 中的缓存页数据时,会记录一条对应操作的 redo log 日志,这样如果出现 MySQL 宕机或者断电时,如果有缓存页的数据还没来得及刷入磁盘,那么当 MySQL 重新启动时,可以根据 redo log 日志文件,进行数据重做,将数据恢复到宕机或者断电前的状态,保证了更新的数据不丢失,因此 redo log 又叫做重做日志。它的本质是保证事务提交后,更新的数据不丢失。 - 循环写入
Undolog
undo log在事务开启之前就产生,当事务提交的时候,不会删除undo log,因为可能需要rollback操作,要执行回滚(rollback)操作时,从缓存中读取数据。InnoDB会将事务对应的日志保存在删除list中,后台通过purge线程进行回收处理
- undo log在事务开启之前就产生
- 当事务提交的时候,不会删除undo log
- 每条 ` INSERT语句,对应一条 DELETE 的 undo log
- 每个 UPDATE 语句,对应一条相反的 UPDATE
redo log 两阶段提交
最开始 MySQL 并没与 InnoDB 引擎( InnoDB 引擎是其他公司以插件形式插入 MySQL 的) ,MySQL 自带的引擎是 MyISAM,但是我们知道 redo log 是 InnoDB 引擎特有的,其他存储引擎都没有,这就导致会没有 crash-safe 的能力(crash-safe 的能力即使数据库发生异常重启,之前提交的记录都不会丢失),binlog 日志只能用来归档。
先写 redo log 后写 binlog。假设在 redo log 写完,binlog 还没有写完的时候,MySQL 进程异常重启。由于我们前面说过的,redo log 写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行。但是由于 binlog 没写完就 crash 了,这时候 binlog 里面就没有记录这个语句。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句。然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的 binlog 丢失,这个临时库就会少了这一次更新,恢复出来的这一行,与原库的值不同。
先写 binlog 后写 redo log。如果在 binlog 写完之后 crash,由于 redo log 还没写,崩溃恢复以后这个事务无效,但是 binlog 里面已经记录了修改这个日志。所以,在之后用 binlog 来恢复的时候就多了一个事务出来,,与原库的值不同。
崩溃恢复
- 判断 redo log 是否完整,如果判断是完整的,就立即提交。
- 如果 redo log 只是预提交但不是 commit 状态,这个时候就会去判断 binlog 是否完整,如果完整就提交 redo log, 不完整就回滚事务。
redo log和checkpoint
在InnoDB存储引擎内部,有两种Checkpoint,分别为:Sharp Checkpoint、Fuzzy Checkpoint
Sharp Checkpoint (全量检查点)发生在数据库关闭时将所有的脏页都刷新回磁盘,这是默认的工作方式,即参数innodb_fast_shutdown=1。但是若数据库在运行时也使用Sharp Checkpoint,那么数据库的可用性就会受到很大的影响。故在InnoDB存储引擎内部使用Fuzzy Checkpoint进行页的刷新,即只刷新一部分脏页,而不是刷新所有的脏页回磁盘。
Fuzzy Checkpoint(模糊检查点):1、Master Thread Checkpoint;2、FLUSH_LRU_LIST Checkpoint;3、Async/Sync Flush Checkpoint;4、Dirty Page too much Checkpoint
在Innodb事务日志中,采用了Fuzzy Checkpoint,Innodb每次取最老的modified page(last checkpoint)对应的LSN,再将此脏页的LSN作为Checkpoint点记录到日志文件,意思就是“此LSN之前的LSN对应的日志和数据都已经flush到redo log
当mysql crash的时候,Innodb扫描redo log,从last checkpoint开始apply redo log到buffer pool,直到last checkpoint对应的LSN等于Log flushed up to对应的LSN,则恢复完成
网友评论