MySQL整体来看,其实就有两块:一块是Server层,它主要做的是MySQL功能
层面的事情;还有一块是引擎层,负责存储相关的具体事宜。
binlog(归档日志)和redo log(重做日志),server 层对应的是binlog,InnoDB对应的是redo log
redo log
redo log利用了WAL技术,也就是Write-Ahead Logging(预习日志,也叫写之前先写日志),它的核心就是先写日志,等不忙的时候再写磁盘
使用流程
具体来说,当有一条记录需要更新时,InnoDB引擎会先将记录写到redo log,并更新内存,此时更新就已经完成了,InnoDB会在适当的时候将数据从内存更新回磁盘,,InnoDB的redo log是固定大小的,比如可以配置为一组4个文件,每个文件的大小是1GB
存储位置
默认情况下,对应的物理文件位于数据库的data目录下的ib_logfile1&ib_logfile2
一是内存中的日志缓冲(redo log buffer),该部分日志是在内存,容易丢失;二是磁盘上的重做日志文件(redo log file),该文件在磁盘,该部分日志是持久的。
binlog
存储格式
binlog的格式有三种:STATEMENT、ROW、MIXED 。
1、STATMENT模式:基于SQL语句的复制(statement-based replication, SBR),每一条会修改数据的sql语句会记录到binlog中。
优点:不需要记录每一条SQL语句与每行的数据变化,这样子binlog的日志也会比较少,减少了磁盘IO,提高性能。
缺点:在某些情况下会导致master-slave中的数据不一致(如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会出现问题)
2、基于行的复制(row-based replication, RBR):不记录每一条SQL语句的上下文信息,仅需记录哪条数据被修改了,修改成了什么样子了。
优点:不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。
缺点:会产生大量的日志,尤其是alter table的时候会让日志暴涨。
redo log和binlog的区别
- redo log是InnoDB引擎特有的;binlog是MySQL的Server层实现的,所有引擎都可以使用。
- redo log是物理日志,记录的是“在某个数据页上做了什么修改”;binlog是逻辑日志,记录的
是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1 ”。 - redo log是循环写的,空间固定会用完;binlog是可以追加写入的。“追加写”是指binlog文件
写到一定大小后会切换到下一个,并不会覆盖以前的日志。
分析
redo log用于保证crash-safe能力。innodb_flush_log_at_trx_commit这个参数设置成1的时候,
表示每次事务的redo log都直接持久化到磁盘。这个参数我建议你设置成1,这样可以保证
MySQL异常重启之后数据不丢失。
sync_binlog这个参数设置成1的时候,表示每次事务的binlog都持久化到磁盘。这个参数我也建
议你设置成1,这样可以保证MySQL异常重启之后binlog不丢失。
小结
因为数据库一般都是一周一备,重要的时候会一天一备,所以假如今天12点数据库误删了一个表,那么可以先找最近的备份,先将数据恢复到最近的备份,然后再重放binlog就可以实现半月内恢复到任何时刻的数据库了。