Buffer Pool
Buffer Pool就是一块用于缓存MySQL磁盘数据的内存空间。
Buffer Pool避免每个SQL操作直接io操作,通过批量操作从而提高效率。
redo log
redo log解决MySQL服务器宕机导致Buffer Pool数据丢失的问题。如果出现宕机后启动可以根据redo log重新恢复。
过程如下:
redo log是磁盘顺序写,数据刷盘是磁盘随机写。
预写式日志:先预写日志后面再将数据刷盘的机制。
redo log buffer
redo log的刷盘机制由参数innodb_flush_log_at_trx_commit控制。 落盘/刷盘机制:
- innodb_flush_log_at_trx_commit = 1:实时写(os cache),实时刷(os cache -> 磁盘)。【这种策略会在每次事务提交之前,每次都会将数据从redo log刷到磁盘中去,理论上只要磁盘不出问题,数据就不会丢失。】
- innodb_flush_log_at_trx_commit = 0:延迟写,延迟刷。【这种策略在事务提交时,只会把数据写到redo log buffer中,然后让后台线程定时去将redo log buffer里面的数据刷到磁盘。这种策略是最高效的,但是我们都知道,定时任务是有间隙的,但是如果事务提交后,后台线程没来得及将redo log刷到磁盘,这个时候不管是MySQL进程挂了还是操作系统挂了,这一部分数据都会丢失。】
- innodb_flush_log_at_trx_commit = 2:实时写,延迟刷。【这种策略在事务提交之前会把redo log写到os cache中,但并不会实时地将redo log刷到磁盘,而是会每秒执行一次刷新磁盘操作。这种情况下如果MySQL进程挂了,操作系统没挂的话,操作系统还是会将os cache刷到磁盘,数据不会丢失,如下图:】
所以,这种redo log刷盘策略是上面两种策略的折中策略,效率比较高,丢失数据的风险比较低,绝大多情况下都推荐这种策略。
回滚 - undo log
InnoDB是支持事务的,而事务是可以回滚的。
假如一个事务将age=1修改成了age=2,在事务还没有提交的时候,后台线程已经将age=2刷入了磁盘。这个时候,不管是内存还是磁盘上,age都变成了2,如果事务要回滚,找不到修改之前的age=1,无法回滚了。
binlog
记录过程是先写Binlog Buffer,然后通过刷盘时机,控制刷入OS Buffer,控制fsync()进行写入Binlog File日记磁盘的过程。
binlog以追加方式记录修改之后的数据,用于归档。 和redo log日志类似,binlog也有着自己的刷盘策略,通过sync_binlog参数控制:
- sync_binlog = 0 :每次提交事务前将binlog写入os cache,由操作系统控制什么时候刷到磁盘。
- sync_binlog =1 :采用同步写磁盘的方式来写binlog,不使用os cache来写binlog。
- sync_binlog = N :当每进行n次事务提交之后,调用一次fsync将os cache中的binlog强制刷到磁盘。
刷盘时机
对于Binlog,MySQL是通过参数sync_binlog参数来控制刷盘时机,取值是0、1和N三种值。简单理解为刷盘时机控制的是数据从 buffer区 -> os cache -> 磁盘。
Binlog 记录格式
作用
- 主从复制场景:在Master主端开启Binlog,将Binlog发生到各个Slave从端,Slave从端重放Binlog从而达到主从数据一致。
- 数据恢复场景:通过使用 mysqlbinlog 工具来恢复数据。
binlog & redo log 区别
- binlog是逻辑日志,记录的是对哪一个表的哪一行做了什么修改;redo log是物理日志,记录的是对哪个数据页中的哪个记录做了什么修改,如果你还不了解数据页,你可以理解成对磁盘上的哪个数据做了修改。
- binlog是追加写;redo log是循环写,日志文件有固定大小,会覆盖之前的数据。
- binlog是Server层的日志;redo log是InnoDB的日志。如果不使用InnoDB引擎,是没有redo log的。
最终图示为: