关于事务的简单介绍,参考 MySQL进阶之InnoDB事务原子性实现原理
持久性实现原理
持久性是指在事务操作完成后,对数据的修改将被持久化即保存到永久性的存储中。即事务一旦提交成功,它对数据库的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
- 缓冲池(Buffer Pool)
InnoDB存储引擎是基于磁盘存取数据的,磁盘IO是比较消耗资源的,如果每次读写数据都进行磁盘IO,则效率会很低。为了解决这个问题,InnoDB设计了缓冲池(Buffer Pool)来提升存储效率。当要从数据库读取数据时,InnoDB会首先从缓冲池中读取,如果缓冲池中没有,则从磁盘读取后并放入缓冲池;当向数据库写入数据时,会首先写入缓冲池,缓冲池中修改的数据会定期刷新到磁盘中即写入到磁盘中。将缓冲池中的数据定期刷新到磁盘是通过检查点机制(CheckPoint)完成的,检查点机制有多种策略,比如主线程定时(每秒或没十秒)刷新、脏页过多、空闲页不足、重做日志不可用时都会发生数据落盘。
- 重做日志(redo log)
由于缓冲池是建立在内存中的,效率提升了,但带来了数据可能丢失的问题,比如宕机时内存中还未落盘的数据将可能丢失。为此,InnoDB引入了重做日志。重做日志文件保存了对数据库操作(增删改)的记录,在发生故障的时间点,如尚有脏页数据未写入磁盘,宕机重启mysql服务时,InnoDB可以根据重做日志重做数据,从而达到事务的持久性。
实现原理
当对数据进行增删改时,除了操作缓冲池中的数据,还会将这次增删改操作写入重做日志缓冲中;定时或当事务提交时,对重做日志缓冲进行刷盘,将其保存到重做日志文件中。InnoDB采用了WAL(Write-ahead logging,预写式日志)策略和Force Log at Commit机制,要求在将数据更新或写入缓冲池(或磁盘)之前以及每次提交事务时先将增删改操作写入重做日志中。如果MySQL宕机,重启时可以读取重做日志中的操作记录,对缓冲池中未来得及落盘的数据(检查点之后的数据)进行恢复,保证了数据不会因MySQL宕机而丢失,从而满足了持久性要求。
下面是InnoDB引擎中数据落盘的简化流程如下
InnoDB持久化数据流程图
1.将事务操作写入重做日志缓冲中
2.通过检查点机制,刷新缓冲池中脏页数据到磁盘中
3.同时,InnoDB会定时或提交事务时将重做日志缓冲中的操作日志刷新到重做日志文件中
4.一旦系统宕机或意外重启时,InnoDB通过重做日志,恢复最后一个检查点之后的数据到数据库中
通过缓冲池和重做日志,配合对应相应的落盘机制,InnoDB实现了高效率的数据存储同时满足了事务的持久性要求。
总结
事务的持久性,就是保证事务提交后不会因为宕机等原因导致数据丢失,InnoDB主要基于重做日志来实现事务持久性的。