mysql的几种日志工作原理

mysql的几种日志工作原理

redo log

InnoDB引擎层日志,属于物理日志,从5.5.5版本开始加入,记录每次操作的行为,用于宕机恢复。它的空间是固定的, 所以会用完。

binlog

server层日志,采用增量写入方式,主要用于备份数据库或恢复数据库

undo log

回滚日志,用于事务提交失败回滚或其他错误回滚。

redo log和binlog的两阶段提交:

在update操作中,server层的执行器先找引擎层,用查询操作找到要修改的数据,然后用行锁锁定这一行数据(mysql8.0之前可以不调用执行器,先从内存缓存中取数据,如果没找到再找引擎层。8.0之后删除了内存缓存不会有这一步)。
然后
1.准备好redo log, redo log 处于 prepare 状态。
2.执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
3.执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。
当在2之前崩溃时
重启恢复:后发现没有commit,回滚。备份恢复:没有binlog 。一致
当在3之前崩溃时
重启恢复:虽没有commit,但满足prepare和binlog完整,所以重启后会自动commit。备份:有binlog. 一致

我们假象没有这两个阶段提交,会有什么后果?
第一步直接提交redo log,写数据,第二部生成bin log ,完成更新操作。
如果服务在第一步后宕机了,那么数据被成功写入,而bin log中不存在对此次操作的记录,在主从同步或者是恢复数据库时就会丢失这一条数据。数据丢失很严重的大兄嘚,所以需要两段提交。

mysql的MVCC

Mysql的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑,他们一般都同时实现了MVCC.实现了非阻塞的读操作,写操作也只锁定必要的行。

MVCC的实现,是通过保存数据在某个时间点的快照来实现的。即为:不管需要执行多长时间,每个事务看到的数据都是一致的。

不同的存储引擎的MVCC实现不同,典型的有乐观并发控制和悲观并发控制。

innodb的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个是行的创建时间,一个保存行的过期时间。存储的是系统版本号,不是真实的时间。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。

在REPEATABLE READ隔离级别下,MVCC具体操作:

SELECT

innodb会根据以下两个条件检查每行记录:

a.innodb只查找版本号早于当前事务版本的数据行,<=当前事务版本号,这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的

b.行的删除版本要么未定义,要么大于当前的事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。

INSERT

INNODB为新插入的每一行保存当前系统版本号作为行版本号

DELETE

innodb为删除的每一行保存当前系统版本号作为行删除标识

UPDATE

innodb为插入一行新纪录,保存当前系统版本号为行版本号,同时保存当前系统版本号到原来的行作为行删除标识

MVCC只在repeatable read和read committed两个隔离级别下工作。其他两个隔离级别和MVCC不兼容。因为READ UNCOMMITTED 总是读取最新的数据行,而不是符合当前事务版本的数据行。而SERIALIZABLE 则会对所有读取的行都加锁。

猜你喜欢

转载自blog.csdn.net/w4187402/article/details/104662146
今日推荐