mysql中的三种日志
mysql中有三种日志,分别是:
- redo log:InnoDB引擎的重做日志,为了事务的持久性
- undo log:InnoDB引擎的回滚日志,为了实现事务的原子性
- binlog:Mysql Sever的归档日志,用于数据备份和主从同步
下面具体说明各种日志的原理
Redo Log
mysql的数据都存在磁盘中,当操作数据的时候,都需要从磁盘获取,然后在内存里操作,为了提交效率,Mysql通过Buffer Pool来将索引、数据都缓存起来,而在更新的时候,也会先更新Buffer Pool再将更新过的内存数据刷到磁盘中,而为了避免在刷新到磁盘之前宕机之类的故障导致内存数据丢失,在更新内存的时候,也会采用WAL(Write Ahead Logging)技术将数据先写入到日志中,这个日志就是Redo Log。
什么是Redo Log?
redo log是物理日志,记录的是某个数据页做了什么修改,对某个表空间的某个数据页的某个偏移量做了某个更新,每当执行一个事务就会增加一条redo log。
Undo Log
mysql的事务的原子性,就是保证事务要么成功要么失败,失败是需要回滚的,而undo log就是记录了事务提交前的数据,事务回滚时可以利用undo log进行回滚,回滚的方式则不同的操作有不同的策略:
insert
将主键值记录下来,如果要回滚则以主键为条件删除
delete
将待删除数据记录下来,如果要回滚则将数据插入回去
update
将待更新数据的旧值记录下来,如果要回滚则将数据更新为旧值
不同操作下 undo log的格式也不一样,但是每一条undo log都有一个roll_pointer指针和一个trx_id事务ID:
- 通过trx_id可以看出数据是哪个事务变更的
- 而roll_pointer则可以将undo log串联成一个链表,这个链表称为版本链
undo log还有一个作用:ReadView + undoLog实现MVCC
undo log也是需要记录redo log的,当修改undo页的时候,会先写入到redo log中,再真正修改Undo 页面
RedoLog和UndoLog的区别:
- Redo Log是记录操作完成后的数据,事务提交之后崩溃,需要redo log会做故障恢复
- Undo Log是记录操作开始前的数据,事务提交之前崩溃,需要通过undo log回滚数据
Redo Log也不是直接写入到磁盘中的,因为每产生一条redo log就写入一次会导致很高的磁盘IO,所以会先写入到redo log buffer
中,redo log的刷盘时机:
- Mysql正常关闭时
- 事务提交时
- redo log buffer写入量大于分配的内存空间的一半时
- 每隔1秒,定时刷盘
redo log有两个文件,当一个log文件满了后会在另一个log文件上继续写入,写满后再切换回来,而且redo log是一个环形结构,写到末尾后又会从开头写。
故障恢复的时候,先执行redo log,将数据恢复到最新状态,同时也会恢复undo log,再将未提交的事务回滚掉。
BinLog
redo log和undo log都是InnoDB存储引擎产生的,而binlog则是server层产生的。
mysql完成一个更新操作后,server会生成一条binlog日志,当事务提交后,该事务产生的binlog会一起写入到binlog文件。
binlog会记录所有数据表结构的变更以及数据的修改,有3种格式:
STATEMENT
每一条操作的sql都会记录到binlog中,主从复制中,slave拿到binlog后需要重放sql来同步数据,当sql中含有动态函数时,同步出来的数据可能会不一致
ROW
记录了每一条数据变更后的样子,如果是修改表机构或者是批量修改的语句,则会产生大量的变更,导致binlog文件过大
MIXED
根据情况动态选择使用STATEMENT还是ROW
BinLog的刷盘时机:
- 事务提交时,会将写入binlog cache的日志持久化到磁盘
- 当binlog cache写入量达到binlog_cache_size参数规定的大小后会进行刷盘
事务提交时,binlog cache日志持久化到磁盘的方式有3种,由sync_binlog参数控制:
sync_binlog=0(默认)
每次提交事务时,只将binlog cache写入到文件缓存,由系统决定什么时候fsync到磁盘
sync_binlog=1
每次提交时,都将binlog cache写入到文件缓存并执行fsync,将数据刷到磁盘
sync_binlog=N(N>1)
每次提交时,只将binlog cache写入到文件缓存,积累到N个事务时,执行fsync,将数据刷到磁盘
RedoLog和BinLog的区别:
- RedoLog是覆盖写,将文件写满后会从头进行覆盖,BinLog则是追加写,写满了就创建新的文件,不会覆盖之前的数据
- RedoLog是物理日志,记录的是对数据页的修改,而BinLog则是有3种不同的格式
- ReadLog用于故障恢复,BinLog用于备份恢复,主从同步
二阶段提交
从上面的介绍中,可以看出,redo log会影响主库数据,binlog会影响从库数据,如果两者不一致的话,会导致主从数据不一致。
为了避免这个问题,mysql采用了二阶段提交的方式:
- Prepare(准备阶段):将日志写入到redo log,并设置事务为prepare状态
- Commit(提交阶段):将日志写入binlog,再设置redolog中事务状态为commit
你的才华横溢,让人敬佩。 http://www.55baobei.com/e6zAogvPoM.html
你的文章让我感受到了不一样的风景,谢谢分享。 http://www.55baobei.com/AeFW6mSvbR.html
你的文章让我心情愉悦,真是太棒了! https://www.yonboz.com/video/94524.html
看到你的文章,我仿佛感受到了生活中的美好。 https://www.4006400989.com/qyvideo/23447.html
你的文章让我学到了很多知识,非常感谢。 https://www.4006400989.com/qyvideo/31250.html
你的文章让我感受到了不一样的视角,非常精彩。 https://www.yonboz.com/video/37874.html
你的文章让我学到了很多技能,非常实用。 https://www.4006400989.com/qyvideo/85401.html
你的文章让我感受到了不一样的视角,非常精彩。 https://www.yonboz.com/video/37874.html
你的文章让我感受到了不一样的视角,非常精彩。 https://www.yonboz.com/video/37874.html
《瞌睡的磐音》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/1261.html
不错不错,我喜欢看 www.jiwenlaw.com
不错不错,我喜欢看 https://www.ea55.com/
想想你的文章写的特别好https://www.237fa.com/
想想你的文章写的特别好