事务原理
持久性
持久性本质就是有redo.log来保证的
redo.log
redo.log重做日志记录的是事务提交是数据也的物理修改,用来实现事务的持久性。
该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log file),前者是在内存中,后者是在磁盘中。当事务提交后会把所有修改信息都存在该日志文件中,用于刷新脏页到磁盘发生错误时,进行数据恢复使用。
流程
redo.log出现前
Buffer pool(缓冲池):缓冲池中缓冲数据页的信息
当客户端发起事务操作时, 首先去缓冲区中查找是否有要更新的数据,若没有,会通过后台线程去磁盘中读取出对应的数据,然后缓存到缓冲区中。
然后直接操作缓冲区中的数据,缓冲区中的数据发生变更,但磁盘中的数据并未发生变更。此时的数据也称之为脏页,一定时间后,要通过后台线程将脏页中的数据刷新到磁盘中,缓冲区中的数据就与磁盘中的数据保持一致了。
若脏页数据往磁盘中刷新时出错了,此时会导致内存中的数据并没有刷新到磁盘中,持久性无法得到保障。
redo.log出现后
当我们对缓冲区中的数据进行增删改之后,首先会将这些数据记录到Redolog buffer(重做日志缓冲区)中,记录数据页的物理变化,事务在提交时,会将Redolog Buffer中数据页的变化直接刷新到磁盘中,持久化的保存到磁盘文件中。一段时间后会进行脏页刷新,如果出错,可以通过redo.log进行恢复,因为在redo.log中记录了单次数据变化,所以可根据redo.log在脏页刷新数据到磁盘发生错误时进行数据恢复。
为什么不每次直接将Buffer Pool中变更的数据页直接刷新到磁盘中?
- 可以这么做,但是会存在严重的性能问题。因为事务的一组操作同时会操作多条记录,这些记录是随机的去操作数据页的,会涉及大量的随机磁盘IO,性能较低。
- 借助Redolog的话,日志文件是追加的,是顺序磁盘IO,性能高于随机磁盘IO,这种机制称之为WAL
- 脏页的数据顺利刷新到磁盘中时,Redolog也就不需要了,所以redolog日志每隔一段时间都会去清理
原子性
事务原子性的实现,需要依赖于undo.log日志
undo.log
回滚日志,用于记录数据被修改前的信息,作用包含:提供回滚和MVCC(多版本并发控制)
undo.log和redo.log记录物理日志不一样,他是逻辑日志。可以认为当delete一条记录时,undo.log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条与之相反的update。当执行rollback时,就可以从undo.log中的逻辑记录到相应的内容并进行回滚。
undo.log销毁:undo.log在事务执行时产生,事务提交时,并不会立即删除undo.log,因为这些