Mysql事务日志
前言
上一章《Mysql数据库事务四大特性、事务状态、事务使用、事务隔离级别》讲到了事务有4种特性:原子性、一致性、隔离性、持久性。那么 ,这些特性到底是基于什么机制实现的呢?本章理论或许枯燥,但是,我们不正是要会别人不会的,才能安享35岁晚年吗?
一、事务四大特性ACID的实现机制
事务的隔离性由锁机制实现;
事务的原子性、一致性、持久性由REDO LOG
和UNDO LOG
实现的。
REDO LOG
称为重做日志,提供在写入操作,恢复提交事务修改的页操作,用来保证事务的持久性;
UNDO LOG
称为回滚日志,回滚行记录到某个特定版本,用来保证事务的原子性、一致性。
注意:
UNDO LOG
并不是REDO LOG
的逆过程,二者都是一种恢复操作。
REDO LOG
是存储引擎层(Innodb)生成的日志,记录的是物理级别上的页修改操作,比如页号**,偏移量** 写入‘ddd’数据,主要为了保证数据可靠性。
UNDO LOG
是存储引擎层(Innodb)生成的日志,记录的是逻辑操作,比如当用户进行insert
操作时,UNDO LOG
就记录一条与之相反的delete操作,主要用于事务回滚和一致性非锁定读(undo log
回滚行记录到某种特定的版本…MVCC
,即多版本并发控制)。
二、REDO日志
InnoDB存储引擎是以页为单位来管理存储空间的,会将磁盘上的页缓存到内存buffer Pool
之后才可以访问,所有变更都必须先更新缓冲池中的数据,然后缓冲池中的脏页(脏页:与磁盘页数据发生变化的页)会以一定的频率刷入到磁盘(checkPoint机制
),通过缓冲池来优化CPU
和磁盘
之间的鸿沟,保证性能。
1.为什么需要REDO日志?
checkPoint
是操作系统master线程
隔一段时间去处理的,所以最坏的情况是事务提交后,刚写完缓冲池,数据库宕机了,那么这段数据就是丢失了,违背了“事务提交后,对数据修改不能丢失”的原则。那么如何保证这个持久性呢?有人会说,在事务提交完成后立即把修改刷新到磁盘,但是这个简单粗暴的做法有些问题:
(1)修改量与刷新磁盘工作量严重不成比例
Innodb
是以页为单位来进行磁盘IO的,页默认是16kB,如果我们只修改了一个字节就要刷新16KB的数据到磁盘上,显然小题大做了。
(2)随机IO刷新较慢
一个事务包含很多语句,即使是一条语句也可能修改很多页,而且这些页并不相邻,那么在刷盘时,随机IO比顺序IO要慢,特别是传统机械硬盘。
另一个解决思路:我们不需要把每次commit
的修改都立即更新到磁盘,只需要把修改了哪些东西记录一下就好,比如:某个事务将系统空间中第10号页中偏移量为100处的值更新成2。
Innodb引擎的事务采用WAL
技术,就是先写日志,在写磁盘,只要日志写入成功,才算事务提交成功,这里的日志就是REDO LOG
,当数据库突然宕机,