事务的隔离性由锁机制实现。
而事务的原子性、一致性和持久性由事物的redo日志和undo日志来保证。
- redo日志(重做日志):提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性(如在内存中修改还没来得及写入磁盘中,此时系统宕机,就需要redo日志来保证修改写入到磁盘中)
- undo日志(回滚日志):回滚行记录到某个特定版本,用来保证事务的原子性、一致性
undo日志不是redo日志的逆过程,redo和undo都可以是看作是恢复操作:
- redo日志:是存储引擎层生成的日志,记录的是物理级别上的页修改操作,主要为了保证数据的可靠性
- undo日志:是存储引擎层生成的日志,记录的是逻辑操作日志,如对某个表进行了INSERT操作,那么undo日志就记录一条与之相反的DELETE操作。主要用于回滚和一致性非锁定读
redo日志
InnoDB是以页为单位来管理存储空间的。在访问页面时,需要先把磁盘上的页缓存到内存中的缓冲池中,所有的修改必须先更新缓冲池中的数据,然后缓冲区中的脏页(写入缓冲池但还没有写回磁盘的页)以一定频率被刷新到磁盘中。
为什么需要redo日志
若有这样一种场景,当事务提交后,刚写完缓冲池还没来得及将修改写回磁盘,数据库宕机了,那么这段数据就丢失了。
但是,事务包含了持久性的特点,对于一个已经提交的事务,在事务提交后即使系统发生了崩溃,这个事务对数据库中所做的更改也不能丢失。
所以,这就引入了redo日志:只需要把修改了哪些东西记录一下就好。InnoDB的事务采用了WAL(Write-Ahead Logging)技术,这种技术的思想就是先写日志(redo日志),再写磁盘,只有日志成功写入,事务才算提交成功。当服务器宕机还未刷新磁盘时,可以通过redo日志恢复,以保证事务的持久性。