MYSQL事务原理分析
目录
- 事务是什么
- ACID特性
- 原子性(A)
- 隔离性(I)
- 持久性(D)
- 一致性(C)
- 隔离级别
- 简介
- 有些什么
- READ UNCOMMITTED(读未提交)
- READ COMMITTED(读已提交)
- REPEATABLE READ(可重复读)
- SERIALIZABLE
- 实现
- MVCC
- 锁
- 锁类型
- 锁算法
- 修改事务隔离性
- 并发异常
- 读异常
- 脏读
- 不可重复读
- 幻读
- 丢失更新
- 回滚覆盖
- 提交覆盖
- 并发死锁
- 原因
- 查看死锁
- 系统表
- 开启日志
- 线上查看
- 如何避免死锁
事务是什么
- 将数据库从一种一致性状态转换为另一种一致性状态
- 可以是一条语句,也可以是一组语句
ACID特性
原子性(A)
- 事务操作要么都做(提交),要么都不做(回滚)
- 事务是访问并更新数据库各种数据项的一个程序执行单元,是不可分割的工作单位
- 通过 undolog 来实现回滚操作。undolog 是将事务每步具体操作记录在共享表中,当回滚时,回放事务具体操作的逆运算
隔离性(I)
- 事务的隔离性要求每个读写事务的对象对其他事务的操作对象能相互分离,并发事务之间不会相互影响,设定了不同程度的隔离级别,通过适度破环一致性,得以提高性能
- 通过 MVCC 和 锁来实现
- 数据库中提供粒度锁的策略,针对表(聚集索引B+树)、页(聚集索引B+树叶子节点)、行(叶子节点当中某一段记录行)三种粒度加锁
持久性(D)
- 事务提交后,事务DML操作将会持久化(写入 redolog 磁盘文件 哪一个页 页偏移值 具体数据)
- 即使发生宕机等故障,数据库也能将数据恢复。redolog 记录的是物理日志
一致性(C)
- 一致性指事务将数据库从一种一致性状态转变为下一种一致性的状态,在事务执行前后,数据库完整性约束不会被破坏
- 一个事务单元需要提交之后才会被其他事务可见。例如:一个表的姓名是唯一键,如果一个事务对姓名进行修改,但是在事务提交或事务回滚后,表中的姓名变得不唯一了,这样就破坏了一致性
- 一致性由原子性、隔离性以及持久性共同来维护的
隔离级别
简介
- ISO 和 ANIS SQL 标准制定了四种事务隔离级别的标准,各数据库厂商在正确性和性能之间做了妥协,并没有严格遵循这些标准;
- MySQL innodb默认支持的隔离级别是 REPEATABLE READ
有些什么
READ UNCOMMITTED(读未提交)
- 该级别下读不加锁,
- 写加排他锁
- 写锁在事务提交或回滚后释放锁
READ COMMITTED(读已提交)
- 从该级别后支持 MVCC ,也就是提供一致性非锁定读
- 此时读取操作读取历史快照数据
- 该隔离级别下读取历史版本的最新数据,所以读取的是已提交的数据
REPEATABLE READ(可重复读)
- 支持MVCC
- 此时读取操作读取事务开始时的版本数据
SERIALIZABLE
实现
MVCC
- 多版本并发控制,
- 读取过程中,遇到其他进、线程对该资源加写锁(X锁,又称行写锁、排他锁),则读取该资源的快照(以前存储的数据)。
锁
- 用来处理并发 DML 操作
锁类型
- 表锁
- 页锁
- 行锁(记录锁)
- 共享锁(S锁)
在 SERIALIZABLE 隔离级别下,默认帮读操作加共享锁
在 REPEATABLE READ 隔离级别下,需手动加共享锁,可解决幻读问题
在 READ COMMITTED 隔离级别下,没必要加共享锁,采用的是 MVCC
在 READ UNCOMMITTED 隔离级别下,既没有加锁也没有使用 MVCC
手动加S锁:
select * from xxx lock in share mode;
- 排他锁 (X锁)
事务删除或更新加的锁;对某一行加锁
插入的时候,会在中间再加一个插入意向锁
在4种隔离级别下,都添加了排他锁,事务提交或事务回滚后释放锁
手动加X锁:
select * from xxx for update;
- 意向共享锁(IS)
仅仅为了告知即将操作的事务:当前有事务进正在进行访问,且其中几行已经加入共享锁 - 意向排他锁(IX)
仅仅为了告知即将操作的事务:当前有事务进正在进行访问,且其中几行已经加入排他锁 - 意向锁
该表中存在锁,表明该锁正在接受某事务访问
目的:排除表层次的锁操作 - AUTO-INC Lock (AI锁)
自增锁,是一种特殊的表级锁,发生在 AUTO_INCREMENT 约束下的插入操作。
采用的一种特殊的表锁机制。
完成对自增长值插入的SQL语句后立即释放。
在大数据量的插入会影响插入性能,因为另一个事务中的插入会被阻塞。
从MySQL 5.1.22开始提供一种轻量级互斥量的自增长实现机制,该机制提高了自增长值插入的性能。
较低概率造成B+树的分裂。 - 锁的兼容性
注:其中IS、IX与S、X的冲突是当X、S为全表操作时候会产生冲突,单行操作并不会产生冲突
意向锁不会与行锁冲突!!!
锁算法
Record Lock
单个行记录上的锁Gap Lock
间隙锁,锁定一个范围,但不包含记录本身, 全开区间
解决幻读问题
仅REPEATABLE READ级别支持间隙锁
产生死锁重要原因之一Next-Key Lock (记录锁+间隙锁)
产生死锁重要原因之一
锁定一个范围,并且锁住记录本身,左开右闭区间
仅REPEATABLE READ级别支持间隙锁Insert Intention Lock (插入意向锁)
插入意向锁,insert操作的时候产生。
在多事务同时写入不同数据至同一索引间隙的时候,并不需要等待其他事务完成,不会发生锁等待。
提升插入的并发性能。
假设有一个记录索引包含键值4和7,两个不同的事务分别插入5和6,每个事务都会产生一个加在4-7之间的插入意向锁,获取在插入行上的排它锁,但是不会被互相锁住,因为数据行并不冲突。
产生死锁重要原因之一AUTO-INC Lock (AI锁)
比行插入方式,较低概率造成B+数的分裂,所以它的性能更高锁兼容
如果有事务已经持有insert Intention key, 这个时候不会影响其他事务
如果有事务想要执行insert Intention key 但是这个时候已经有事务持有了GAP或者NEXT-KEY, 则会产生阻塞
修改事务隔离性
# set transaction isolation level read uncommitted;
# set transaction isolation level read committed;
# set transaction isolation level repeatable read;
set transaction isolation level SERIALIZABLE;
begin
select * from table;
update table_a set name='lsy';
delete from table_b;
commit
并发异常
读异常
- 一个事务已经获取了插入意向锁,对其他事务是没有任何影响的
- 一个事务想要获取插入意向锁,如果有其他事务已经加了 gap lock 或 Next-key lock 则会阻塞
脏读
事务A可以读到事务B未提交的数据
不可重复读
两次读取同一条记录,读到了不一样的结果,因为有其他事务对该数据做了修改
幻读
两次读取同一范围内的记录,结果的集合不一样
由于repeatable read中规定:读取事务开始前前的版本行数据,那么在该隔离级别下,不管该事务中对改行数据做什么操作,该数据都将不变
丢失更新
回滚覆盖
该问题已经被数据库修复,数据库将拒绝该操作,
该问题会将数据回滚为事务开始之前的数据
比如事务a读取数据后做了回滚,在这期间,事务B对该数据做了修改,结果事务a回滚时候将使得事务B的操作无效
提交覆盖
两个事务同时写一个数据,后提交的事务覆盖掉了先提交的数据
并发死锁
使用 wait-for graph的方式进行死锁检测
异常报错:deadlock found when trying to get lock
原因
- 相反方向加锁
- 隔离级别冲突
查看死锁
系统表
-- 开启标准监控
CREATE TABLE innodb_monitor (a INT) ENGINE=INNODB;
-- 关闭标准监控
DROP TABLE innodb_monitor;
-- 开启锁监控
CREATE TABLE innodb_lock_monitor (a INT) ENGINE=INNODB;
-- 关闭锁监控
DROP TABLE innodb_lock_monitor
开启日志
-- 开启标准监控
set GLOBAL innodb_status_output=ON;
-- 关闭标准监控
set GLOBAL innodb_status_output=OFF;
-- 开启锁监控
set GLOBAL innodb_status_output_locks=ON;
-- 关闭锁监控
set GLOBAL innodb_status_output_locks=OFF;
-- 将死锁信息记录在错误日志中
set GLOBAL innodb_print_all_deadlocks=ON;
线上查看
-- 查看事务
select * from information_schema.INNODB_TRX;
-- 查看锁
select * from information_schema.INNODB_LOCKS;
-- 查看锁等待
select * from information_schema.INNODB_LOCK_WAITS;
如何避免死锁
- 尽可能以相同顺序来访问索引记录和表;
- 如果能确定幻读和不可重复读对应用影响不大,考虑将隔离级别降低为RC;
- 添加合理的索引,不走索引将会为每一行记录加锁,死锁概率非常大;
- 尽量在一个事务中锁定所需要的所有资源,减小死锁概率;
- 避免大事务,将大事务分拆成多个小事务;大事务占用资源多,耗时长,冲突概率变高;
- 避免同一时间点运行多个对同一表进行读写的概率;
MYSQL事务原理分析相关推荐
- MySQL事务原理分析(ACID特性、隔离级别、锁、MVCC、并发读异常、并发死锁以及如何避免死锁)
MySQL事务原理分析(ACID特性.隔离级别.锁.MVCC.并发读异常.并发死锁以及如何避免死锁) 一.事务 目的 组成 特征 事务空间语句 二.ACID特性 原子性(A) 隔离性(I) 持久性(d ...
- Linux服务器开发【有用知识】—MySQL事务原理分析
前言 今天的目标是学习MySQL事务原理分析,但是却似乎总是非常不顺利,概念和实操实在多到令人发指,故干脆轻松学完一节课,等到时机到了再重新刷一遍吧! 一.事务是什么? 将数据库从一致性状态转化成另一 ...
- 数据库之mysql事务原理分析与锁机制 详解
1.事务 1.2.目的 事务将数据库从一种一致性状态转换为另一种一致性状态: 1.3.组成 事务可由一条非常简单的SQL语句组成,也可以由一组复杂的SQL语句组成: 其中单条语句会默认自动添加事务控制 ...
- Spring事务原理分析-部分一
Spring事务原理分析-部分一 什么事务 事务:逻辑上的一组操作,组成这组操作的各个单元,要么全都成功,要么全都失败. 事务基本特性 ⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要 ...
- Spring的事务原理分析、与mysql的事务关系
spring事务?mysql事务? 系统中到底谁的事务是在保证数据的一致性,两个事务有什么关系? spring事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,s ...
- Spring事务原理分析(一)--@EnableTransactionManagement 到底做了什么?
目录 一.概述 二.事务的ACID属性 三.事务的隔离级别 四.事务的传播行为 五.Spring声明式事务环境搭建 六.@EnableTransactionManagement分析 七.AutoPro ...
- mysql第五话 - mysql索引原理分析
在工作中听到最多的一句话,sql查询太慢怎么办?加个索引吧! 今天来探索一下mysql的索引原理. 1.索引是什么? 可以毫不夸张的说,系统中sql的快慢,是能直接决定你系统的快慢的.但是sql的快慢 ...
- mysql 事务原理详解
前言 事务是mysql Innodb引擎的一大特点,可以说,在日常开发中,对于mysql事务的使用无处不在,因此深入了解并掌握mysql的事务原理很有必要. 一.mysql事务简介 事务 是一组操作集 ...
- Mysql事务原理拆解
1.mysql事务基本概念 事务特性 ACID A 原子性 I 隔离性 D 持久性 C 一致性 并发问题 脏读 读取到未提交的数据. 不可重复读 两次读取结果不同 幻读 select操作得到的结果所表 ...
最新文章
- 拇指接龙游戏升级记录03(升级MainScene.cpp)
- 用 Pyecharts 制作炫酷的可视化大屏
- IaaS, PaaS和SaaS是云计算的三种服务模式
- 水磨石地面分隔条设置示意图_水磨石抛光过程中什么时候用百洁垫?什么时候用百亮钢丝棉?...
- python mysql 遍历_Python自动化办公系列六(pdf文档处理)
- 改进初学者的PID-采样时间
- 删除android电视软件下载,安卓智能电视必装工具没有之一,进程管理备份清理全靠它!...
- Linux学习总结(22)——CentOS7.2安装Nginx
- mysql_数据备份和迁移(Windows)
- gerrit 数据迁移_gerrit importer 使用方法
- 教你怎么用三种办法找到发给你QQ的坦白说的那个人
- 自己写的txt分割器
- java代码生成springdao_可一键生成dao、表、controller等几十种的代码生成器源码分享...
- 事件绑定,事件类型,事件委托
- 计算机基础知识(免费、全面)
- 人事经理常问的面试问题及答案
- android高仿微信表情输入与键盘输入(详细实现分析)
- spring bean实现init/destory生命周期方法的三种方式
- Redis删除过期数据的策略概要
- 加密与解密的基本概念--GPG加密工具的使用
热门文章
- websocket系列:基于tio-websocket-spring-boot-starter实现
- 【安卓-tio】安卓集成t-io
- 卸载计算机程序有几种方法,电脑上如何卸载软件 卸载软件的三个办法
- 我所熟悉的0X000000该内存不能为read的解决方法
- 用C语言写飞机小游戏
- unity使ui面向镜头_pihqcam面向相机的软件ui
- 客快物流大数据项目(九十九):Clickhouse中update/delete的使用
- 论:程序员成就之天梯排行榜
- 怎么查看服务器里的文件夹,如何查看远程服务器里面的文件夹
- Linux操作系统网络驱动程序编写