Mysql笔记(二)-Mysql的日志系统
mysql 有两个重要的日志模块,redo log (重做日志) 和 bin log(归档日志)。
一、redo log
redo log 是innoDB的日志,用于记录数据的更新信息。在更新数据时,如果每一次的操作都需要写进磁盘的话,程序需要在磁盘中找到相对的数据,然后进行更新。整个过程的IO消耗,查找成本很高。
为了解决这个问题,Merysql采用了WAL(Write-Ahead Logging)技术,它的关键点就是先写日志,再写磁盘。
在innoDB中,将参数innodb_flush_log_at_trx_commit 这个参数设置为1 的时候表示每次事务的redo log都直接持久化到磁盘,它用于保证crash-safe能力,mysql异常重启的数据不会丢失。
二、bin log
binlog 是mysql server层的日志模块,在早期mysql的存储引擎用的是MyISAM,而sql及引擎不具备 crash-safe的能力,所以 binlog只能用于归档。后面InnoDB 以插件的形式引入mysql,由于binlog 不能实现InnoDB的crash-safe。所以InnoDB才会使用另外一套日志系统--redo Log。 PS:crash-safe 保证了数据库异常重启时,之前提交的数据不会丢失。
因为binlog是记录所有的逻辑操作并且是追加写的,所以mysql可以恢复到数据库规定时间内的任意一秒的状态。如果你需要半个月的数据可恢复,那么就需要备份半个月的binlog,同时需要定期做整库的备份,其操作可根据业务需要 一天一备或者一周。
比如在十点的时候你误删了一个表,那你可以这样子操作:
1、找到最近一次的整库备份;
2、从备份时间开始,将备份的binlog 依次取出来,重放到你误删表的那一刻。
在mysql中 将sync_binlog这个参数设置为1 的时候,表示每次事务的binlog都会持久化至磁盘,这样子保证了mysql异常重启的数据不会丢失。
三、redo log与bin log的区别
1、redo log 是InnoDB特有的日志模块,具有rash-safe的能力。binlog 是mysql server层的日志模块,适用于所有的引擎。
2、redo log 是物理日志,记录的是具体某个数据页做了哪一些修改;binlog 是逻辑日志,记录的是这个语句的原始逻辑。
3、redo log 是循环重复写的,其大小也是固定的。binlog是追加写的,当一个文件达到一定大小时,将切换至下一个文件,并不会覆盖之前的数据。
四、两阶段提交
mysql的两阶段提交是为了保证两份日志的逻辑一致。下面是mysql执行一条update语句的流程图:
两阶段提交原理描述:
阶段1:InnoDB redo log 写盘,InnoDB 事务进入 prepare 状态
阶段2:如果前面prepare成功,binlog 写盘,那么再继续将事务日志持久化到binlog,如果持久化成功,那么InnoDB
事务 则进入 commit 状态(实际是在redo log里面写上一个commit记录)