MySql 事务ACID与log

归档日志 bin log

回滚日志 undo log

重做日志 redo log

原子性:

undo log日志记录sql操作,当发生回滚时,逆序执行逆操作来完成回滚

持久性:

bin log & redo log日志,

redo log: 为了避免每次读取数据都进行磁盘IO,MySQL的InnoDB引擎采用缓存buffer方式

redo log分为两个部分:缓冲区的redolog buffer和磁盘上的redologfile

磁盘上的redo log不受宕机影响,在每次真正执行DML操作之前先更新redo log(称为预写式日志),也就是WAL技术

WAL技术(Write-Ahead Logging):在真正把数据写入到磁盘前,先记录日志

redo log(undo log跟redo log的机制一样)都经历一次写,一次刷

写过程将引擎用户层buffer记录的数据写入核心层buffer

刷过程将核心层buffer数据真正写入磁盘

由此分为三种写刷时机,同样由参数控制:延迟写 / 实时写,实时刷 / 实时写,延迟刷

bin log有类似的刷盘时机机制,同样由参数控制:不强制要求 / 每次提交都刷盘(默认) / 集齐N次提交后刷盘

由于redo log采用循环写的方式记录下最近的操作,但要用到更久以前的操作来完成恢复时,就需要另一种日志对更久之前的操作归档

这个日志就是bin log, 两者要配合使用才能保证当数据库发生宕机重启时,数据不会丢失

MySQL提交时,分为两阶段提交,第一阶段提交时,执行器先写redo log(prepare),再写bin log,第二阶段提交时正式更新redo log(commit),保证两个日志数据的安全与同步

bin log与redo log区别:

redo log循环写,大小固定,会丢失;bin log追加写,大小通过配置参数决定,追加写到超过文件大小后会将后续日志记录到新的bin log不丢失

redo log 适用于崩溃恢复,只有redo log是crush-safe的;binlog 除了配合崩溃恢复保证持久性之外,还适用于主从复制(也是重点)

bin log所有引擎都支持,server层实现,redo log仅InnoDB支持,引擎层实现

bin log支持三种记录方式(Statement / Row / Mixed),日志类型为逻辑日志;

redo log日志类型为物理日志(物理日志用于恢复速度会快很多)

一致性:

bin log 也有类似的缓冲区,binlog刷盘时机同样是靠配置参数来控制

可以选择不实时更新,牺牲一定的一致性来换取更好的性能,默认每次提交都刷盘(保证一致性)

隔离性:

事务隔离级别:      防脏读  防不可重复读  防幻读

read uncommitted       N                N                N                 

read committed            Y                N                N         

repeatable read            Y                Y                N

serializable                   Y                Y                Y

脏读:读未提交

不可重复读:同一事务两次读的结果不同(针对update)

幻读:前后多次读取,数据总量不一致(针对insert、delete)

MVCC:多版本并发控制,不同事务的读–写、写–读操作并发执行,从而提升系统性能

读未提交:就全读最新的就是读未提交,不加任何判断

读已提交和可重复读的实现:

核心处理逻辑就是判断所有版本中哪个版本是当前事务可见的,称为 ReadView

这个过程通过事务IDtrx_id来判断,这个ID严格递增

读已提交:仅判断trx_id,在本次事务之前的都有效修改,可查

可重复读:利用undo log,配合ReadView,当该事务执行相同读操作的时候,依据undo log恢复到开始时的数据,保证永远是第一次查询时的结果

串行化的实现:锁实现串行化,牺牲并发,保证ACID

注意:以上三大日志都仅记录写入性操作,不包括查询操作(因为查询不更改数据库,也就没必要记录了)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容