mysql-redo-log 、bin-log、undo-log

redo-log 和bin-log对比

Redo logBinlog
所属属于innoDB独有属于mysql Server层,所有存储引擎都可以使用
主要的使用场景崩溃恢复主从复制
备份方式循环写,会覆盖前面的日志追加写,全量备份
文件大小redo log 的大小是固定的。Binlog 文件的大小可调整
存储的内容记录更新操作(比如把某个字段从0改成了1)三个格式,statement:SQL语句,row:记录更新操作,mixed:二者结合

有了redo log 为什么还要bin log?

1.redolog是InnoDB独有的,别的引擎没有,所以mysql在server层实现bin log 供所有引擎使用
2.redolog是循环写的,无法记录所有的数据。而binlog能够记录全量数据
3. 主从模式中从库的数据同步依赖binlog;

bin log

binlog是一个二进制格式的文件,用于记录修改数据的SQL语句信息。

binlog主要用于主从复制和数据恢复这两个场景中,都是为了增强数据可靠性。

  • 主从服务器需要保持数据的一致性,通过binlog来同步数据。

  • 系统崩溃时 可以通过binlog来对数据进行恢复

bin log 的三种记录格式

Row
记录每一行数据被修改的形式
用到MySQL的特殊功能如存储过程、触发器、函数
优点:可以保证主从数据一致性,能清楚的记录每一行数据修改的细节。
缺点:记录每行数据的修改细节,所以数据量大
Statement
记录的是具体的sql语句和执行sql的上下文
优点:解决了 Row 数据量大的问题,bin-log日志量少,节约磁盘IO。
缺点:容易出现主从复制不一致,因为同一语句在主从服务器上的支持情况可能不同,导致执行的结果不一样。所以不建议主从模式下使用Statement

Mixed
Mixed格式并不是一种新的格式,而是根据不同的情况从Statement与Row中选择一种格式。
因为有些 statement 格式的 binlog 可能会导致主备不一致,所以要使用 row 格式。但 row 格式又很占空间。
所以,MySQL 就取了个折中方案,MySQL 自己会判断这条 SQL 语句是否可能引起主备不一致,如果有可能,就用 row 格式,否则就用 statement 格式。
所以说,mixed 格式既利用了statment 格式产生日志量少的优点,同时又避免了数据不一致的风险。

redo log

mysql是在内存中修改数据的,修改完之后需要将新数据刷到磁盘中,如果每一次修改数据都执行一次写磁盘操作,成本会很高。所以利用redo log减少落盘的次数
具体怎么做的?
只将事务对数据所做的修改记录下来,称之为redo日志。然后定期将redo log落盘,就无须每次发生数据修改都落盘,期间如果系统崩溃可以利用redo log恢复数据。

redo log 会把事务在执行过程中对数据库所做的所有修改都记录下来,当系统崩溃发生时,重启后可以把事务所做的任何修改都恢复出来。

redo log文件

redolog文件在磁盘中是环形存储的,写满之后日志是会被覆盖的;
在这里插入图片描述
write pos当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。

checkpoint 是当前可以擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。

write pos 和 checkpoint 之间还空着的部分,可以用来记录新的操作。如果 write pos 追上 checkpoint,表示环形文件区满了,这时候不能再执行新的更新,得停下来将一部分更新的数据页刷新到磁盘,使得 checkpoint能够向前 推进。

undo log

为了保证事务的原子性,当事务执行失败时,我们需要把数据库恢复成事务执行之前的状态,这个过程就称之为回滚,回滚需要记录很多数据,把这些为了回滚而记录的数据称之为撤销日志undo log

undo log主要有两个作用:事务回滚和多版本并发控制(MVCC)

回滚
在数据修改的时候,不仅记录了redo log,还记录undo log,如果因为某些原因导致事务失败或回滚了,可以用undo log进行回滚

MVCC
因为undo log存储着修改之前的数据,相当于一个前版本MVCC实现的是读写不阻塞,读的时候只要返回前一个版本的数据就行了。

例如:
你插入一条记录时,至少要把这条记录的主键值记下来,之后回滚的时候只需要把这个主键值对应的记录删掉就好了。
你删除了一条记录,至少要把这条记录中的内容都记下来,这样之后回滚时再把由这些内容组成的记录插入到表中就好了。
你修改了一条记录,至少要把修改这条记录前的旧值都记录下来,这样之后回滚时再把这条记录更新为旧值就好了。

自己的一些思考

1、如果整个数据库的数据都被删除了,可以用redo log的记录来恢复吗?
不能
因为redo log是覆盖写的,如果内存的数据已经刷到了磁盘,那么对应的redo log的数据就会被后来的redolog覆盖。
redo log不会存储所有历史数据的变更,所以无法恢复完整的数据库。

2、innodb存储引擎的刷脏策略是怎么样的呢?
通常而言会有两种策略:全量和部分
全量刷脏发生在关闭数据库时,部分刷脏发生在运行时。

3、当对一个表T中的字段t1做两次更新

update T set t1=2 where id=125;
update T set t1=2 where id=125;

记录几次binlog?
一次,相同就不写binlog了。如果T表中的t1值原来就等于2,则Binlog不会记录日志。

4、一个事务在执行到一半的时候实例崩溃了,怎么恢复?
先恢复undo log,然后由undo log 回滚在宕机前没有提交的事务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值