MySQL进阶实战2,那些年学过的事务
@
一、MySQL服务器逻辑架构
MySQL核心部分包括查询解析、分析、优化、缓存以及内置函数,所有跨存储引擎的功能,存储过程、触发器、视图等。
存储引擎负责MySQL中数据的存储和提取。服务器通过API和存储引擎进行通信。存储引擎API包含几十个底层函数,用于执行诸如“开始一个事务”或“根据主键查询数据”等操作,但存储引擎不会去解析SQL,不同存储引擎之间也不会相互通信,而只是简单地响应上层服务器的请求。

二、并发控制
1、读写锁
读锁是共享的,或者说是互不阻塞的,多个用户在同一时刻可以同时读取同一个资源,而互不打扰。
写锁则是排它锁,写锁会阻塞其它的写锁和读锁。
2、锁粒度
获取锁、检查锁是否被占用、释放锁等操作,都会增加系统的开销。
锁策略的意思就是在锁的开销和数据的安全性之间寻求平衡。
3、表锁
表锁是开销最小的锁,表锁 = 锁住整张表。
一个用户在对表进行写操作前,需要先获得写锁,这会阻塞其它用户对该表的读写操作。没有写锁时,其它用户会获取读锁,读锁之间互不阻塞。
尽管存储引擎可以管理自己的锁,MySQL还是会使用各种高效的表锁来实现不同的目的。比如,ALTER TABLE语句使用的就是表锁,而忽略存储引擎的锁机制。
4、行级锁
行级锁可以最大程度的支持并发处理,但也带来了最大的锁开销。
三、事务
事务内的语句,要么全执行,要么全不执行。事务具有ACID特性,ACID表示原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)。
1、原子性(atomicity)
一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全执行提交成功,要么全不失败回滚。
2、一致性(consistency)
数据库总是从一个一致性的状态转换到另一个一致性的状态。
3、隔离性(isolation)
一个事务所做的修改在最终提交以前,对其它事务是不可见的。
4、持久性(durability)
事务一旦提交,则七所做的修改就会永久的保存在数据库中。
四、隔离级别
1、未提交读 read uncommited
在read uncommited级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为脏读(Dirty Read)。这会导致很多问题,实际应用中很少使用。
2、提交读 read commited
大多数数据库系统的默认隔离级别都是 read commited,但MySQL不是, read commited满足前面提到的隔离性,一个事务开始时,只能看见已经提交的事务所做的修改。也称为不可重复读,因为两次执行同样的查询,可能会得到不一样的结果。
3、可重复读 repeatable read
repeatable read 解决了脏读的问题,该级别保证了在同一个事务中多次读取同样的记录的结果是一致的。但还是解决不了幻读的问题,幻读指的是当某个事务在读取某个范围内的记录时,另一个事务又在该氛围内插入了新的记录,档之前的事务再次读取该范围的记录时,会产生幻行。
可重复读是MySQL的默认事务隔离级别。
4、可串行化 serializable
serializable是最高级别的锁,它通过强事务串行执行,避免了之前说的幻读问题,serializable会在读取的每一行数据上都加锁,可能会导致大量的超时和锁争用问题,实际应用中很少使用这个隔离级别。
五、死锁
死锁是指两个或多个事务在同一个资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。当多个事务视图以不同的顺序锁定资源时,就可能会产生死锁。如果两个事务都尝试去执行一条相同的update语句,却发现该行已经被对方锁定,然后两个事务都等待对方释放锁,同时又持有对方需要的锁,则陷入死锁。
为了解决死锁问题,比如MySQL的InnoDB存储引擎,如果检测到死锁的循环依赖,InnoDB会将持有最少行级锁的事务进行回滚。
六、事务日志
存储引擎在修改表的数据时只需修改其内存拷贝,再把该修改行为记录在磁盘的事务日志中,而不是每次都将修改的数据本身持久到磁盘。
事务日志采用的是追加方式,事务日志在持久化之后,内存中被修改的数据会在后台慢慢的存入磁盘,但如果此时发生了异常,存储引擎在重启后,也会根据事务日志,将数据存到磁盘中。
七、多版本并发控制MVCC
MySQL的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑,它们一般都同时实现了多版本并发控制MVCC,可以认为MVCC是行级锁的一个变种,但MVCC在很多情况下避免了加锁操作,开销比行级锁要低的多。
MVCC是通过保存某个时间点的快照实现的,不管需要执行多长时间,每个事物看到的数据都是一致的。根据事务开始的时间不同,每个事物对同一张表,同一时刻看到的数据可能是不一致的。
InnoDB的MVCC是通过在每行记录后面保存两个隐藏的列实现的,一个保存了行的创建时间,一个保存行的删除时间。存储的并不是实际的时间值,而是系统版本号。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行对比。
MVCC只在提交读 read commited、可重复读 repeatable read两个隔离级别中使用。
分别分析增删改查时,MVCC的使用。
1、select
InnoDB会根据以下两个条件检查每行记录:
- InnoDB只查找版本早于当前事务版本的数据行,这样保证事务读取的行,要么是在事务开始前就存在的,要么是事务自身插入或修改的;
- 行的删除版本要么未定义,要么大于当前事务版本号,这样保证事务读取的行,在事务开始前未被删除;
2、insert
InnoDB为新插入的每一行保存当前系统版本号作为行版本号。
3、update
InnoDB会插入一行新纪录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除表示。
4、delete
InnoDB为删除的每一行保存当前系统版本号作为行删除标识。
保存这两个额外的系统版本号,使大多数读操作都可以不用加锁,MVCC的设计是的读数据很简单,性能很好,并且也能保证只会读到符合要求的行,不足之处是每行记录都需要额外的存储空间,需要做更多的行检查工作,以及一些额外的维护工作。
MySQL进阶实战2,那些年学过的事务的更多相关文章
- MySQL进阶实战5,为什么查询速度会慢
一.先了解一下MySQL查询的执行过程 MySQL在查询时,它是由很多子任务组成的,每个子任务都会消耗一定的时间,如果要想优化查询,实际上要优化其子任务,可以消除一些子任务.减少子任务的执行次数.让子 ...
- MySQL进阶实战1,数据类型与三范式
一.选择优化的数据类型 MySQL支持的数据类型非常多,选择正确的数据类型对于获得高性能至关重要. 1.更小的 一般情况下,应该尽量使用较小的数据类型,更小的数据类型通常更快,因为占用更少的磁盘.内存 ...
- MySQL进阶实战4,MySQL索引详解,下篇
一.索引 索引是存储引擎用于快速查找记录的一种数据结构.我觉得数据库中最重要的知识点,就是索引. 存储引擎以不同的方式使用B-Tree索引,性能也各有不同,各有优劣.例如MyISAM使用前缀压缩技术使 ...
- MySQL进阶实战3,mysql索引详解,上篇
一.索引 索引是存储引擎用于快速查找记录的一种数据结构.我觉得数据库中最重要的知识点,就是索引. 存储引擎以不同的方式使用B-Tree索引,性能也各有不同,各有优劣.例如MyISAM使用前缀压缩技术使 ...
- MySQL进阶实战6,缓存表、视图、计数器表
一.缓存表和汇总表 有时提升性能最好的方法是在同一张表中保存衍生的冗余数据,有时候还需要创建一张完全独立的汇总表或缓存表. 缓存表用来存储那些获取很简单,但速度较慢的数据: 汇总表用来保存使用grou ...
- MySQL进阶实战7,查询的执行过程
@ 目录 一.拆分查询 二.分解关联查询 三.查询的执行过程 四.优化器的一些优化手段 1.重新定义关联表的顺序 2.将外连接转化为内连接 3.使用增加变换规则 4.优化count().max().m ...
- 【Python高级工程师之路】入门+进阶+实战+爬虫+数据分析整套教程
点击了解更多Python课程>>> 全网最新最全python高级工程师全套视频教程学完月薪平均2万 什么是Python? Python是一门面向对象的编程语言,它相对于其他语言,更加 ...
- 最新Python3.6从入门到高级进阶实战视频教程
点击了解更多Python课程>>> 最新Python3.6从入门到高级进阶实战视频教程 第1篇 Python入门导学 第2篇 Python环境装置 第3篇 了解什么是写代码与Pyth ...
- Linux Capabilities 入门教程:进阶实战篇
原文链接:https://fuckcloudnative.io/posts/linux-capabilities-in-practice-2/ 该系列文章总共分为三篇: Linux Capabilit ...
随机推荐
- 【项目实战】自备相机+IMU跑通Vins-Mono记录
前言 初次接触SLAM,公司要求用自己的设备来跑通vinsmono这个程序,虽然已经跑通了别人的数据包,但是真正自己上手来运行这个程序,发现真的是困难重重,特意在此记载下来整个过程,以供大家参考. 我 ...
- Elasticsearch Dockerfile 例子
文章转载自:https://elasticstack.blog.csdn.net/article/details/111692444 前提条件 在继续执行本教程中概述的步骤之前,你需要具备一个关键的先 ...
- FastDFS 分布式文件系统的安装与使用---两台服务器搭建FastDFS环境
写在前面 有不少小伙伴在实际工作中,对于如何存储文件(图片.视频.音频等)没有一个很好的解决思路.都明白不能将文件存储在单台服务器的磁盘上,也知道需要将文件进行副本备份.如果自己手动写文件的副本机制, ...
- 【前端必会】webpack的目标代码
背景 webpack生成什么样的代码呢?同的模块依赖的写法(import.export export default),会导致生成代码的不同,下面介绍普通的import与export 开始 导出PI1 ...
- 5G 与数字化转型的关系是怎样的?
5G提供的是通信网络服务,数字化转型需要网络服务,但并不是必须使用5G网络,也就是说5G在数字化转型中并不是必虚的,但可以作为备选项,不过在某些行业比如农业.林业.牧业.港口.建筑等布设有线网络.无线 ...
- Petrozavodsk Winter Training Camp 2016: Moscow SU Trinity Contest
题目列表 A.ABBA E.Elvis Presley G. Biological Software Utilities J. Burnished Security Updates A.ABBA 题意 ...
- 微信小程序开发优化
一.开发优化一 1.使用Vant Weapp 1.1 什么是Vant Weapp Vant Weapp官网链接 Vant Weapp是有赞前端团队开源的一套小程序UI组件库,助力开发者快速搭建小程序应 ...
- PyCharm安装PyQt5及其工具(Qt Designer、PyUIC、PyRcc)详细教程
摘要:Qt是常用的用户界面设计工具,而在Python中则使用PyQt这一工具包,它是Python编程语言和Qt库的成功融合.这篇博文通过图文详细介绍在PyCharm中如何完整优雅地安装配置PyQt5的 ...
- 关于VirtualBox在新建虚拟机时-选择操作系统类型后没有64位的版本选项
今天笔者准备使用VirtualBox安装一台windows的虚拟时,在选项操作系统类型为Microsoft Windows后 发现下面的版本选择中,没有之前看到的64位选择,全是32位的,但实际昨天都 ...
- PHP全栈开发(五):PHP学习(2. echo 和 print 输出、数组、foreach循环、字符串)
在PHP中有两个基本的输出语句,就是echo 和 print 这两个东东有什么不同呢. echo 可以一次输出一个或者多个字符: echo "这是一个", "字符串,&q ...