mysql原理(八)事务简介

参考:https://www.cnblogs.com/kismetv/p/10331633.html

一、mysql逻辑架构图

逻辑架构图

mysql架构主要分为三层:
(1)第一层:处理客户端连接、授权认证等。
(2)第二层:服务器层,负责查询语句的解析、优化、缓存以及内置函数的实现、存储过程等。
(3)第三层:存储引擎,负责MySQL中数据的存储和提取。MySQL中服务器层不管理事务,事务是由存储引擎实现的。MySQL支持事务的存储引擎有InnoDB、NDB Cluster等,其中InnoDB的使用最为广泛;其他存储引擎不支持事务,如MyIsam、Memory等

二、四大特性ACID

衡量事务的四个维度,一般很难完全实现,mysql的innodb默认支持的可重复读,oracle默认支持读已提交,均不支持隔离性。

原子性:Atomicity
一致性:Consistency
隔离性:Isolation
持久性:Durability

2.1 mysql的日志分类

名称 作用
redo log(重做日志) 确保日志的持久性,防止在发生故障,脏页未写入磁盘。重启数据库会进行redo log执行重做,达到事务一致性
undo log(回滚日志) 保证数据的原子性,记录事务发生之前的一个版本,用于回滚,innodb事务可重复读和读取已提交 隔离级别就是通过mvcc+undo实现
err log(错误日志) Mysql本身启动,停止,运行期间发生的错误信息
slow query log (慢查询日志) 记录执行时间过长的sql,时间阈值可以配置,只记录执行成功
bin log (二进制日志) 用于主从复制,实现主从同步
relay log (中继日志) 用于数据库主从同步,将主库发来的bin log保存在本地,然后从库进行回放
general log (普通日志) 记录数据库的操作明细,默认关闭,开启后会降低数据库性能

2.2 原子性

要么都成功,有一个失败则全部要失败。数据库中若存在失败,则所有数据必须回滚。

原理 undo log

InnoDB实现回滚,靠的是undo log:当事务对数据库进行修改时,InnoDB会生成对应的undo log;如果事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子。

回滚的实现是通过具体操作的相反操作,比如insert对应delete,update在回滚时会将数据update为更新前的数据。

2.3 持久性

事务一旦经过提交,其对数据库的改变是永久性的,后续的操作或者故障不应对其产生影响。

原理:redo log

redo log出现的原因:Innodb是将数据存储在硬盘上的,无论写入必然需要磁盘IO,效率低下,为了解决这一问题,引入了Buffer Pool(缓冲池)。缓冲池包含磁盘中的部分数据页,当从读取数据时,会先在缓冲池进行查询,没有的话再去磁盘,同时更新数据到缓冲池。当像数据库写入数据时,会先写入到缓冲池中,缓冲池的数据会定期刷新到磁盘(刷脏)。

刷脏:当前缓冲池数据与磁盘数据不一致,被称为脏页,定时刷新脏页数据到磁盘的过程叫做刷脏。

缓冲池的存在引出的问题:如果刷脏过程还没进行就出现宕机,那么会出现丢失数据的问题,必然无法保证数据一致性。

鉴于上面的问题,redo log被引出用于解决以上问题。

当缓冲池的数据被修改时,会优先在redo log记载修改的操作记录(redo log采用的是WAL(Write-ahead logging,预写式日志),所有修改先写入日志,再更新到Buffer Pool)。事务提交时,通过调用fsync(参考下面的引申内容)接口对redo log进行刷盘。若果宕机的话,在重启是可以读取redo log的内容进行刷盘。

引申:

为了保证磁盘上实际文件系统与缓冲区中内容保持一致,unix提供了sync、fsync、fdatasync三个函数。

sync():只是将所有修改过的块缓冲区排入写队列,然后就返回,并不等待实际写磁盘操作结束。
fsync():只对由文件描述符filedes(与打开文件相对应)指定的单一文件起作用,且等待写磁盘操作结束,然后返回。该调用会阻塞等待直到设备报告IO完成。会将文件的元数据等一同写在磁盘上。
fdatasync():类似于fsync,但不保证文件的元数据会写入磁盘上。

fsync与fdatasync区别:除了同步文件的修改内容(脏页),fsync还会同步文件的描述信息(metadata,包括size、访问时间等等),因为文件的数据和metadata通常存在硬盘的不同地方,因此fsync至少需要两次IO写操作

在redo log当中,仍然存在redo log buffer这样的缓存区,仍然需要将redo buffer刷新到redo log file,参考文章:https://blog.csdn.net/weixin_38629422/article/details/105813338
可以通过下面的参数设置redolog刷新策略
innodb_flush_log_at_trx_commit
mysql推荐设置为1

innodb_flush_log_at_trx_commit的三种策略:
当为0时:不会在事务提交时将redo log buffer写入磁盘文件。
当为1时:在事务提交时,即将redo log buffer 写入磁盘文件redo log file中。
当为2时:会在事务提交时,首先将redo log buffer写入os cache,随后会在一定时间内将数据刷新到硬盘。

除了事务提交时,还有其他刷盘时机:如master thread每秒刷盘一次redo log等,这样的好处是不一定要等到commit时刷盘,commit速度大大加快。

2.4 隔离性

与原子性、持久性侧重于研究事务本身不同,隔离性研究的是不同事务之间的相互影响。

针对隔离性其实主要针对两个方面:
写写:一个正在写操作的事务对另一个正在写的事务事务是否有影响。锁机制保持隔离性。
写读:一个正在写操作的事务对另一个读取的事务是否有影响。MVCC保持隔离性。

2.4.1 写写操作

锁机制:innodb支持行级锁,而myisam支持的是表级锁。

查看锁的信息:
select * from information_schema.innodb_locks; #锁的概况
show engine innodb status; #InnoDB整体状态,其中包括锁的情况
2.4.2 写读操作
2.4.2.1 四种隔离级别
读未提交:READ UNCOMMITTED
读已提交:READ COMMITTED
可重复读:REPEATABLE READ
串行化:SERIALIZABLE 
隔离级别 脏读可能性 不可重复读可能性 幻读可能性
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE

脏读:读取了事务未提交时的数据。
不可重复读:在一个事务过程中,多次相同查询得到了不同的结果。
幻读:一个事务(同一个read view)在前后两次查询同一范围的时候,后一次查询看到了前一次查询没有看到的行。参考https://www.jianshu.com/p/c53c8ab650b5

MVCC(Multi-Version Concurrency Control,多版本并发控制)
mysql使用的是可重复读的隔离级别,那么必然会产生幻读的现象,通过使用MVCC(多版本并发控制)解决脏读,不可重复读,幻读问题。

实现MVCC的基本技术栈:
(1)隐藏列:InnoDB中每行数据都有隐藏列,隐藏列中包含了本行数据的事务id、指向undo log的指针等。
(2)基于undo log的版本链:每条undo log也会指向更早版本的undo log,从而形成一条版本链。
(3)ReadView:通过隐藏列和版本链,MySQL可以将数据恢复到指定版本;但是具体要恢复到哪个版本,则需要根据ReadView来确定。所谓ReadView,是指事务(记做事务A)在某一时刻给整个事务系统(trx_sys)打快照,之后再进行读操作时,会将读取到的数据中的事务id与trx_sys快照比较,从而判断数据对该ReadView是否可见,即对事务A是否可见。

2.5 一致性

一致性是指事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。

可以说,一致性是事务追求的最终目标:前面提到的原子性、持久性和隔离性,都是为了保证数据库状态的一致性。此外,除了数据库层面的保障,一致性的实现也需要应用层面进行保障。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,012评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,628评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,653评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,485评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,574评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,590评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,596评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,340评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,794评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,102评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,276评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,940评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,583评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,201评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,441评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,173评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,136评论 2 352