共计 2126 个字符,预计需要花费 6 分钟才能阅读完成。
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 只是个概念,事务最终目标是要保障数据的可靠性,一致性。