一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情
MySQL数据库事务想必掘友们都用过,事务要么成功要么失败,事务的ACID(原子性、一致性、隔离性、持久性)原则,但是你们知道MySQL事务的持久性是怎么实现的吗?今天本篇文章讲的就是MySQL事务的持久性实现。
事务持久性
当应该是无一旦被提交那么数据的改变就是永久的即使MySQL服务宕机也不会丢失数据,在MySQL重启后数据还能恢复,持久性是通过事务日志来实现的由redo log重做日志和undo log回滚日志,举个例子,当我们提交一个事务的时候会先将数据库数据的变化先记录在redo log重做日志中然后在写入磁盘,这样子就能保证即使MySQL服务崩溃也能通过事先记录的重做日志恢复数据进而保证数据的修改也就是持久性。
redo log
redo log重做日志实际上也是真正存在磁盘当中的数据文件,默认在MySQL的data目录下,如下图:
相信大家都会有一个问题,既然重做日志也是磁盘文件,那么写入操作不也是io操作吗,为什么不直接写入磁盘?
有两个原因:
-
为了加快与磁盘交互的速度
-
为了实现数据的持久性
实际上在事务提交前先写入redo log日志并不是直接写入磁盘中文件,为了加快数据交互速度读和减少io次数,中间引入了redo log buffer缓冲池,在事务提交的过程中,注意是过程中,比如我一个事务内新增1000条数据,那么在第一条数据新增的时候会先去修改内存页然后同步写入redo log buffer缓存当中,当事务提交的时候会先强制将redo log buffer中的数据写入磁盘中的redolog重做日志文件,使用这种缓冲池能够有效的减少直接和磁盘的io次数,加快和数据交互的效率(ps:和事务的提交机制有关,MySQL默认是每次事务提交都强制先将数据刷盘都redo log文件),只有当日志文件记录成功事务才算提交成功,这样即使MySQL服务宕机也可以通过事先记录在日子中的数据在重启的时候恢复保证了事务的持久性。
补充:
查看当前数据库事务提交策略:show variables like 'innodb_flush_log_at_trx_commit',如下图:
查看redo log buffer的大小:show variables like 'innodb_log_buffer_size',如下图:
适当增加其内存可以减少redo log buffer和磁盘的交互次数。