MySQL学习笔记-MySQL的日志系统
MySQL的日志系统
更新流程涉及两个重要的日志模块
- redo log(重做日志)
- binlog(归档日志)
redo log(InnoDB特有的日志)
设计的原因
如果每一次的更新操作都写进磁盘,磁盘需要找到对应的记录再更新。
整个过程的IO成本,查找成本很高
实现原理
1.当有一条记录更新时,InnoDB引擎会先将记录写到redo log里面
2.当MySQL空闲时,才将操作记录保存到磁盘里面
注意:
3.如果redo log此时保存的记录不多,就先写进去,空闲时间再存储到磁盘
4.如果redo log此时已经快满,就需要停下更新操作(此时就会影响系统的性能了,应尽量避免此类情况的发生),先想redo log一部分记录保存到磁盘,再继续更新操作

设计redo log的技术WAL技术:Write-Ahead Logging
先写日志,再写磁盘
crash-safe
有了redo log,InnoDB可以保证数据库发生异常重启时,提交的记录也不会丢失,此技术称之为crash-safe
binlog(server层自带的)
binglog日志只能用于归档,没有crash-safe能力,这也是redo log出现的原因
redo log日志与binlog日志的不同点
1.redo log是InnoDB引擎特有的;binlog是MySQL的Server层实现的,所有引擎都可使用
2.redo log是物理日志,记录的是“在某个数据页上做了什么修改”;binlog是逻辑日志,记录语句的原始逻辑
3.redo log是循环写的,空间固定;binlog可追加写,不会覆盖以前的日志
一个更新语句在MySQL内部的实现
例如:
mysql> create table T(ID int primary key,c int);
mysql> update T set c=c+1 where ID=2;
1.执行器找引擎取ID=2行,ID是主键,所以直接主键索引查找。如果ID=2这一行在内存中,则直接返回给执行器;如果不在内存中,需要从磁盘读入内存,再返回。
2.执行器拿到数据,将这个值+1,得到新的数据,再调用引擎接口写入
3.引擎将新数据写入内存中,同时将操作记录记录到redo log中,此值redo log处于prepare状态(随时可以提交状态)
4.执行器生成操作的binlog,并把binlog写入磁盘(顺序写入,i/o少)
5.执行器调用引擎的提交事务接口,将刚写入的redo log改成提交状态(commit)更新完成

两阶段提交
原因:
需要日志将数据库恢复到半个月任意一秒的状态
让临时库与与线上库保持一致
使用两阶段提交的好处
1.先写redo log后写binlog时。当redo log写完,binlog还没写,系统崩溃。再重启时,
系统由redo log与binlog两个备份恢复的数据会不一致
2.先写binlog,后写redo log。如果binlog写完crash,由于redo log还没写,崩溃后这个事务无效,所以系统的值与binlog里面记录的不一致
3.使用两阶段提交可以很好的避免上述问题
4.redo log和binlog都可以表示事务的提交状态,而两阶段提交可以让这两个状态保持逻辑上的一致
redo log保证crash-safe能力的参数
表示每次事务的redo log都直接持久化到磁盘,保证MySQL异常重启后数据不丢失
innodb_flush_log_at_trx_commit 参数设置为1
表示每次事务的binlog都持久化到磁盘,保证MySQL异常重启后binlog不丢失
sync_binlog 参数设置为1

浙公网安备 33010602011771号