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只是个概念,事务最终目标是要保障数据的可靠性,一致性。