MySQL 的三大日志分别是哪三种?它们各自的作用是什么?
undolog是提供回滚和mvcc的一种日志,当事务失败或者用户回滚的时候,可以将数据回滚成原来的样子
mvcc支持:主要是读取的时候通过undo log的历史版本来实现读不加锁,简单来说就是让多个事务可以并发读写同一个数据,但是互不阻塞
redolog 是InnoDB的物理日志,保证事务的持久性
在提交事务之前,先将修改写入到redo log中,即使宕机也能恢复到提交状态
只记录数据页的修改,不记录具体的sql
属于InnoDB特有的日志
binlog 记录了所有的DML,DDL语句,所以我们称他为逻辑日志,用于主从复制,数据恢复,增量备份
总结:
Undo log 用于回滚和 MVCC,Redo log 保证持久性防止宕机丢数据,Binlog 用于主从复制和备份。
MVCC是怎么实现的?
InnoDB 的 MVCC 是基于 Undo Log 实现的。通过保存数据修改前的旧版本,其他事务可以读取“历史版本”,从而避免加锁,提高并发性能。
解释:
靠undolog实现历史版本快照,不会因为某个事务没有提交而阻塞线程
就比如说
事务T1读取A,事务T2修改了A的数据,但是没有提交,但是事务T1一直读到都是没被T2修改的数据
再深入一点
每行事务都会有两个隐藏字段,一个是trix_id,也就是最近修改他的事务id,
还有一个roll_pointer:指向undolog的旧版本记录,指向签一个版本的记录,这样我们能够根据查询事务的不同的trix_id回退到之前的旧版本
对于一个查询语句,首先通过本事务的 trx_id
与行数据的 trx_id
进行比较,判断是否能够读取这行数据。如果当前事务的 trx_id
小于行数据的 trx_id
,且该行数据对应的事务 未提交,则当前事务 不能读取 该行数据。此时,系统会通过 roll_pointer
追溯到 Undo Log 中,读取历史版本的数据,从而实现一致性快照读(Snapshot Read)
再深入一点,在一个事务A执行的过程,一个数据很可能被修改了很多次,我们需要怎么去比较一个数据可不可读,这个时候就要用到readView,readView里面有所有事务id和活跃事务id
现在就变成:
当我们要查询一个数据的时候,我们会返回当前数据行的readView,会与最小的活跃事务id进行比较,如果当前事务id小于这个最小活跃事务,我们需要通过roll_pointer沿着undolog找到合适的事务id