赞
踩
事务是一个不可分割的数据库操作序列,也是数据库并发控制的基本单位,其执行的结果必须使数据库从一种一致性状态到另一种一致性状态。事务是逻辑上的一组操作,要么都执行,要么都不执行。
事务的 具体实现内容 在下文进行更为详细的介绍。
鉴于后文与日志息息相关,因此单独整理一个章节来介绍MySQL中三种重要的日志。
MySQL的Redo Log(重做日志)是一种用于持久化事务操作的机制,它记录了对数据库进行的修改操作,以确保数据的持久性和一致性。Redo Log的底层原理如下:
Redo Log的结构:Redo Log是一个循环的、固定大小的日志文件,通常由多个物理文件组成。每个物理文件称为一个Redo Log组成员(Log Group Member),每个组成员都有一个唯一的标识符。
Redo Log的写入过程:当事务执行修改操作时,MySQL首先将修改操作记录到内存中的Redo Log缓冲区(Redo Log Buffer)。Redo Log Buffer是一个内存区域,用于临时存储待写入Redo Log文件的日志记录。
Redo Log的刷写过程:为了保证数据的持久性,MySQL会定期将Redo Log Buffer中的日志记录刷写(Flush)到磁盘上的Redo Log文件中。这个过程称为Redo Log的刷写。
Redo Log的重做过程:当数据库发生崩溃或意外关闭时,MySQL可以通过Redo Log来恢复数据的一致性。在数据库重启时,MySQL会根据Redo Log文件中的日志记录,重新执行未完成的事务操作,将数据恢复到崩溃前的状态。
需要注意的是,Redo Log是顺序写入的,这使得它具有高性能和低延迟的特点。通过将修改操作记录到Redo Log中,MySQL可以将磁盘随机写入操作转换为顺序写入操作,从而提高写入性能。
此外,MySQL还使用了一种叫做Checkpoints的机制来优化Redo Log的刷写过程。Checkpoints是一种定期将内存中的数据刷写到磁盘的操作,它可以减少数据库崩溃时的恢复时间。
MySQL的Undo Log(回滚日志)是一种用于实现事务的回滚和MVCC(多版本并发控制)机制的日志。它记录了对数据库进行的修改操作的逆操作,以便在事务回滚或读取旧版本数据时使用。Undo Log的底层原理如下:
Undo Log的结构:Undo Log是一个逻辑日志,它以事务为单位进行记录。每个事务都有一个对应的Undo Log,其中包含了该事务所做的修改操作的逆操作。
Undo Log的写入过程:当事务执行修改操作时,MySQL首先将修改前的数据记录到Undo Log中。这样,在事务回滚时,可以通过Undo Log将数据恢复到事务开始之前的状态。
Undo Log的回滚过程:当事务需要回滚时,MySQL会根据Undo Log中的逆操作,将数据恢复到事务开始之前的状态。通过逆向执行Undo Log中的操作,可以撤销事务所做的修改。
Undo Log的读取过程:在MVCC机制中,当一个事务读取数据时,MySQL会根据事务的隔离级别和数据的版本号来决定读取哪个版本的数据。如果需要读取旧版本的数据,MySQL会通过Undo Log来获取旧版本的数据。
需要注意的是,Undo Log的数据是存储在磁盘上的,而不是存储在内存中。这使得Undo Log可以支持大量的并发事务和大量的修改操作。
Undo Log在MySQL中的作用非常重要,它不仅用于事务的回滚和数据的恢复,还支持MVCC机制,提供了高并发的读写操作。
undo log只负责记录事务开始前要修改数据的原始版本。
非擦除:
bin log记录了数据库所有修改操作,它不会像redo log那样循环写擦除之前的记录,而是会一直记录日志。一个bin log日志文件默认最大容量1G,单个日志超过最大值,则会新创建一个文件继续写日志。
记录反向逻辑:
和undo log类似,bin log记录的是执行SQL命令的反向逻辑,另外,bin log日志文件需要设置过期时间。
作用:
用处一:主从模式中主从节点间的数据同步;
用处二:数据还原。
bin log是人工使用(数据恢复、主从复制和增量备份等场景),redo log、undo log是事务使用。
undo log: 当一个事务需要回滚时,MySQL会使用undo log将修改的数据恢复到原始状态。
redo log: 事务持久化。
bin log: 数据库持久化。
MySQL的事务隔离性是通过 上锁+MVCC 实现的。
MySQL事务隔离级别 默认是可重复读。
MySQL 提前一级 解决并发读写问题。
快照读: InnoDB 通过 MVCC(多版本控制)将数据库在过去某个时刻的快照应用在查询上,使得:
这次查询 只能看到 别的事务生成快照前提交的数据,而不能看到 别的事务生成快照后提交的数据或者未提交的数据。
MySQL默认事务隔离级别是可重复读,在这一隔离级别,已经基于锁+MVCC解决了幻读问题,因此 不会出现幻读现象。
具体: 事务1插入前事务2读到的是没有插入的数据(并且是快照读),事务1插入后,事务1 会生成新的快照,但是事务2读的还是自己之前读的那个快照,并不是这个事务1新产生的快照。
特殊情况: 在一些特殊情况下,仍然可能会发生幻读。例如,如果事务1在执行完插入操作后,立即提交并释放锁,而事务2在执行查询操作时,会重新获取锁并读取最新的数据快照版本。这种情况下,事务2就有可能发生幻读现象,因为它读取的数据快照版本已经更新,包含了事务1插入的新数据。
两阶段锁协议: InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,需要等事务结束时才释放,这就是两阶段锁协议。遵循此协议可能带来事务 死锁 问题。
解决: ①超时等待之后事务退出;②设置死锁检测,发现死锁之后主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。