乐趣区

关于事务:数据库事务的实现原理

1. 前言

都晓得数据库事务有 ACID 个性(原子性、一致性、隔离型、持久性),本文简略聊一下它们的实现原理。

2. 日志文件

2.1. redo log

redo log 叫做重做日志,是用来实现事务的持久性。该日志文件由两局部组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log), 前者是在内存中,后者在磁盘中。

当事务提交之后会把所有批改信息都会存到该日志中。假如有个表叫做 tb1(id,username) 当初要插入数据(3,ceshi)

start transaction; 
select balance from bank where name="zhangsan"; 
// 生成 重做日志 balance=600 
update bank set balance = balance - 400; 
// 生成 重做日志 amount=400 
update finance set amount = amount + 400; 
commit;

redo log 有什么作用?

mysql 为了晋升性能不会把每次的批改都实时同步到磁盘,而是会先存到 Boffer Pool(缓冲池)外头,把这个当作缓存来用。而后应用后盾线程去做 缓冲池和磁盘之间的同步

那么问题来了,如果还没来的同步的时候宕机或断电了怎么办?还没来得及执行下面图中红色的操作。这样会导致丢局部已提交事务的批改信息!

所以引入了 redo log 来记录已胜利提交事务的批改信息,并且会把 redo log 长久化到磁盘,零碎重启之后在读取 redo log 复原最新数据。

总结:redo log 是用来复原数据的 用于保障,已提交事务的长久化个性。

2.2. undo log

undo log 叫做回滚日志,用于记录数据 被批改前 的信息。他正好跟后面所说的重做日志所记录的相同,重做日志记录数据被批改后的信息。undo log 次要记录的是数据的逻辑变动,为了在产生谬误时回滚之前的操作,须要将之前的操作都记录下来,而后在产生谬误时才能够回滚。

还用下面那两张表

每次写入数据或者批改数据之前都会把批改前的信息记录到 undo log。

undo log 有什么作用?

undo log 记录事务批改之前版本的数据信息,因而如果因为零碎谬误或者 rollback 操作而回滚的话能够依据 undo log 的信息来进行回滚到没被批改前的状态。

总结:undo log 是用来回滚数据的用于保障 未提交事务的原子性。

2.3. archive log

archive log(归档日志)是 Oracle 数据库中的概念,它其实是 redo log 的衍生物。

redo log file 是 LGWR 过程从 Oracle 实例中的 redo log buffer 写入的,是循环利用的。就是说一个 redo log file 写满后,才写下一个。归档日志是当数据库运行在归档模式下时,一个 redo log file 写满后,由 ARCn 过程将重做日志的内容备份到归档日志文件下,而后这个 redo log file 能力被下一次应用。

不论数据库是否是归档模式,重做日志是必定要写的。而只有数据库在归档模式下,重做日志才会备份,造成归档日志。

redo log 是循环利用的,然而归档日志不是,它一直接管从 redo log 中写入的日志备份。因而到肯定工夫后,会导致数据库存储不够,影响数据库应用。咱们个别都会执行一个定时脚本,在规定工夫周期后,删掉保留周期前的归档日志文件。

3. 锁和 MVCC 根底

3.1. 锁

具体对于锁的常识,能够翻看后面的文章《数据库事务和锁》。简略来分,锁分为上面 共享锁 排他锁

  • 共享锁(shared lock), 又叫做 ” 读锁 ”

读锁是能够共享的,或者说多个读申请能够共享一把锁读数据,不会造成阻塞。

  • 排他锁(exclusive lock), 又叫做 ” 写锁 ”

写锁会排挤其余所有获取锁的申请,始终阻塞,直到写入实现开释锁。

因而通过读写锁,只有 读读 能够并行,然而 写读 写写 都不能做到并行
事务的隔离性就是依据读写锁来实现的,这个前面再说。

3.2. MVCC 根底

MVCC (MultiVersion Concurrency Control) 叫做多版本并发管制。

InnoDB 的 MVCC,是通过在每行记录的前面保留两个暗藏的列来实现的。这两个列,
一个保留了行的创立工夫,一个保留了行的过期工夫,
当然存储的并不是理论的工夫值,而是零碎版本号。

以上片段摘自《高性能 Mysql》这本书对 MVCC 的定义。他的次要实现思维是通过 数据多版本 来做到 读写拆散 。从而实现 不加锁读进而做到读写并行

MVCC 在 mysql 中的实现依赖的是 undo log 与 read view

  • undo log :undo log 中记录某行数据的多个版本的数据。
  • read view : 用来判断以后版本数据的可见性。

4. 事务的实现原理

后面讲的重做日志,回滚日志以及锁技术就是实现事务的根底。

  • 原子性:应用 undo log,从而达到回滚。
  • 持久性:应用 redo log,从而达到故障后复原。
  • 隔离性:应用锁以及 MVCC, 使用的优化思维有读写拆散,读读并行,读写并行。
  • 一致性:一致性是通过原子性,持久性,隔离性来实现的。通过回滚,以及复原,和在并发环境下的隔离做到一致性。

原子性,持久性,隔离性折腾半天的目标也是为了保障数据的一致性。总之,ACID 只是个概念,事务最终目标是要保障数据的可靠性,一致性。

退出移动版