快照读:
SQL读取的数据是快照版本,也就是历史版本,普通的select查询的就是快照。innodb存储引擎的快照读,读取的数据将由cache(原始数据)+undo(事物修改过的数据)两部分组成。
当前读:
SQL读取的数据是最新版本,可以通过锁的机制来保证读取的数据无法被其它的事物修改。update,delete,insert,select ... lock in share mode,select ... for update都是当前读。
mysql在事物开始操作数据之前,会先将原始数据备份到一个undo log的地方,这样做的目的有两个。
- 第一是为了保证事物的原子性,如果事物在执行的过程中出现了某些错误,或者是用户执行了rollback的操作,mysql可以利用undo log中的备份将数据恢复到事物开始之前的状态。
- 第二是为了实现多版本的并发控制,事物在提交之前,undo log中保存了未提交之前的数据版本,undo log可以作为旧版数据的快照供其他并发访问的事物实现快照读。
除了undo log,Mysql数据库还有一个redo log的概念,mysql在事物开始之后,事物中操作的任何数据,会将最新的数据备份到一个地方(redo log),就是在事物执行的过程中,开始将数据写入redo buffer中,最后写入redo log中,具体的落盘策略可以自行配置。这样做的目的是:为了实现事物的持久性,防止在发生故障的时间点,尚有脏页未写入磁盘,在mysql重启的时候,根据redo log重做,从而使事物未入磁盘的数据达到持久化这一特定。