MySQL学习笔记-MySQL的日志系统

MySQL的日志系统

更新流程涉及两个重要的日志模块

  • redo log(重做日志)
  • binlog(归档日志)

 

 

redo log(InnoDB特有的日志)

设计的原因

如果每一次的更新操作都写进磁盘,磁盘需要找到对应的记录再更新。

整个过程的IO成本,查找成本很高

实现原理

1.当有一条记录更新时,InnoDB引擎会先将记录写到redo log里面

2.当MySQL空闲时,才将操作记录保存到磁盘里面

注意

3.如果redo log此时保存的记录不多,就先写进去,空闲时间再存储到磁盘

4.如果redo log此时已经快满,就需要停下更新操作(此时就会影响系统的性能了,应尽量避免此类情况的发生),先想redo log一部分记录保存到磁盘,再继续更新操作

img

 

设计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)更新完成

img

 

 

两阶段提交

原因:

需要日志将数据库恢复到半个月任意一秒的状态

让临时库与与线上库保持一致

使用两阶段提交的好处

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

posted @ 2020-10-04 15:35  大梦方觉寺  阅读(147)  评论(0)    收藏  举报