关于事务的小小理解

目录

  • 什么是事务
  • 事务的实现
    • 一个事务的实现过程
  • 事务的隔离
    • 事务的隔离级别
    • MVCC

什么是事务

事务是数据库区别于文件系统的重要特征之一。它是由若干条SQL语句组成的。在事务中的操作,要么都做,要么都不做,是一个不可分割的单元。事务必须同时满足:
原子性(Atomicity):事务的所有操作,要么都做,要么都不做,不会结束在中间某个环节。
隔离性(Isolation):多个事务同时访问数据库中同一数据时,所表现出来的相互关系。
持久性(Durability):事务完成后,事务所做的修改进行持久化保存,不会丢失。
一致性(Consistency) :事务开始之前和事务结束之后,数据库的完整性没有被破坏。

事务的实现

一个事务的实现过程

假如执行如下一条语句:

begin;--开启事务
update test set name='exp1997' where id=1;
rollback;--回滚
commit;--提交

在理解事务执行过程之前,首先要知道与其相关的几个文件(这里的每一个都足以写长篇):

1.重做日志。重做日志是用来实现事务的持久性的。主要是记录每个数据页数据变化的日志,在必要时对数据页进行重做。它由两部分组成:一是内存中的重做日志缓存(redo log buffer),二是重做日志文件(redo log file),默认在数据目录下有两个名为ib_logfile0 和ib_logfile1的重做日志文件。重做日志文件循环写入方式运行,InnoDB存储引擎先写ib_logfile0,当写到最后时,会切换到ib_logfile1,再当ib_logfile1写满时,会再切换回ib_logfile0中。
2.ibd文件。每创建一个表,都有一个“表名.ibd”的文件,这个文件主要存放该表的数据和索引。
3.缓存池(buffer pool)。就是一块内存区域,在数据库中读取页,首先将从磁盘读到的页放在缓存池中,对数据库页的修改操作,则首先修改缓存池中的页。
4.LSN :就是日志序列号,这个序列号单调递增的,比如原本的序列号是1000,有一个事务写入了20个字节,那么 LSN就变成了1020。LSN不仅在重做日志中有,在每个数据页的头部,也记录了该页的LSN。数据页中的LSN表示最后刷新数据页时LSN的大小。
5.undo。 undo日志在ibdata1文件中存储,存储了事务工作过程中的回滚信息,在回滚时,实际上做的是与先前相 反的工作。对于insert,存储引擎会完成一个delete,对于每个delete,存储引擎会执行一个insert,对于update,存储引擎会完成一个相反的update,将修改前的数据放回去。

那么上述代码的实现过程究竟是什么样的?

  1. 首先,由io将test.ibd文件中的id=1所在的页(16K)调入buffer pool,然后对buffer pool中的信息进行修改,并将变化的信息记录到redo log buffer中。缺省情况,commit会立即将redo log buffer写入磁盘重做日志文件ib_logfiles中,日志落盘成功commit返回。buffer pool中的脏页由page cleaner thread每隔一段时间刷新回磁盘。 而当数据库宕机重启的时候,会将redo log中的内容加载到redo log buffer,由于redo log的LSN比磁盘的LSN新,两者数据不一致MySql是无法启动的。此时用redo log buffer的数据重做一下buffer pool中的数据,然后写回磁盘数据页,才能启动数据库恢复到数据库中,再根据undo log和binlog内容决定回滚数据还是提交数据。上述过程实际解释了持久性和一致性的问题。
  2. rollback。回滚是根据undo日志回滚,回到之前的某一个状态(savepoint的点)。
    undo在生成过程中会记录redo信息,当发生异常时(如宕机),如果redo中的信息没有提交,此时,先用redo日志恢复,然后再根据undo信息回滚。redo和undo保证了原子性

事务的隔离

MySQL从概念上可以分为四层,顶层是接入层,不同语言的客户端通过mysql的协议与mysql服务器进行连接通信,接入层进行权限验证、连接池管理、线程管理等。下面是mysql服务层,包括sql解析器、sql优化器、数据缓冲、缓存等。再下面是mysql中的存储引擎层,mysql中存储引擎是基于表的。最后是系统文件层,保存数据、索引、日志等。
上述引用自:https://www.jianshu.com/p/f692d4f8a53e

事务的隔离级别

MySql中使用MVCC提高了事物的并发处理能力,但同时也带老生常谈的脏读、不可重复读和幻读的问题。
为了解决这些问题,数据库设置了四种隔离级别:
关于事务的小小理解_第1张图片
InnoDB存储引擎默认隔离级别REPEATABLE READ,通过MVCC解决了幻读的问题。

MVCC

MVCC是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存行的过期时间(或删除时间)。当然存储的并不是实际的时间值,而是系统版本号(system version number)。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。
mvcc实际是通过时间戳实现的。

你可能感兴趣的:(mysql,数据库)