IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> mysql innodb 事务隔离性实现原理 -> 正文阅读

[大数据]mysql innodb 事务隔离性实现原理

隔离性是什么?

数据库的四大特性ACID

  • 原子性(A):事务中的操作要么全部成功要么全部失败(通过undo log实现)
  • 一致性?:事务执行前后数据是处于一个一致性的状态(通过原子性,隔离性,持久性实现)
  • 隔离性(I):事务之间是隔离开的,互相不会干扰(通过mvcc和锁实现)
  • 持久性(D):事务一旦提交,之后的其他操作或者故障都不该对此结果产生影响(通过redo log实现)

事务没有隔离性会存在什么问题?

  • 脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
  • 幻读:是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
  • 不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

事务的隔离级别

为了解决脏读,幻读,不可重复读的问题,数据库为我们提供了四种隔离级别

  • 读未提交
  • 读已提交 -解决脏读
  • 可重复读 -解决不可重复读,脏读
  • 串行化-解决脏读,幻读,不可重复读

什么是MVCC?

事务的隔离性使用的是MVCC和锁实现的,那么什么是MVCC呢?

  • 定义:多版本并发控制,MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。
  • 作用:MVCC在MySQL InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读。

重要概念

  • 当前读:select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁)这些操作都是一种当前读,为什么叫当前读?就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。
  • 快照读:不加锁的select就是快照读,如果数据库的隔离级别是串行化的话回退化为当前读,产生快照读的原因是为了提高并发查询效率,快照读是基于MVCC实现的,可以将MVCC作为行锁的变种理解,多数情况下,避免了加锁操作,降低了开销,提高数据库的并发访问能力。

MVCC解决了什么问题?

数据库的并发有三种情景

  • 读读:无任何问题
  • 读写:有线程安全问题,可能会造成事务隔离问题,可能遇到脏读,幻读,不可重复读
  • 写写:有线程安全问题,可能存在更新丢失问题

MVCC解决的问题
MVCC是一种用来解决读写冲突的无锁并发控制,也就是为事务分配单项增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照,所以MVCC可以为数据库解决以下问题:

  • 在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能。
  • 解决脏读、幻读、不可重复读等事务隔离问题。

MVCC的实现原理

三个隐藏字段

  • DB_TRX_ID:6字节,最近修改事务id,记录创建这条记录或者最后一次修改该记录的事务id
  • DB_ROLL_PTR:7字节,回滚指针,指向这条记录的上一个版本,用于配合undolog,指向上一个旧版本
  • DB_ROW_ID: 6字节,隐藏的主键,如果数据表没有主键,那么innodb会自动生成一个6字节的row_id,数据库有主键用主键没有主键用唯一键,没有唯一键则生成这个ID

undo log

  • 在进行insert,delete,update操作的时候产生的方便回滚的日志。

  • 当进行insert操作的时候,产生的undolog只在事务回滚的时候需要,并且在事务提交之后可以被立刻丢弃

  • 当进行update和delete操作的时候,产生的undolog不仅仅在事务回滚的时候需要,在快照读的时候也需要,所以不能随便删除,只有在快照读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除

  • 当一个事务要对一条数据进行修改的时候会对这行数据加排他锁,将当前记录拷贝到undolog中,拷贝完毕后,进行对应修改,并将隐藏字段中的事务ID改为新事务ID,回滚指针指向之前拷贝的副本记录。
    undo log 历史版本图
    read view

  • 事务进行快照读操作的时候生成的读视图,在改事务执行快照读的那一刻,会生成一个数据系统当前的快照,记录并维护系统当前活跃的事务id,事务的id值是递增的。主要作用是用来进行可见性分析

可见性分析

  • 目的:之前做的修改能否对读有影响

  • 过程:将要被修改的数据的最新记录中的DB_TRX_ID取出来,与系统当前其他活跃事务ID进行比较,如果DB_TRX_ID跟read view的属性做了比较不符合可见性,那么就通过DB_ROLL_PTR回滚指针去去undolog中的DB_TRX_ID进行遍历操作直到找到符合条件的版本。

  • 重要属性:trx_list(read view生成时刻所有正在活跃的事务ID放到这个集合中),up_limit_id(记录trx_list中事务ID最小的ID),low_limit_id(read view 生成时刻下一个暂未分配的事务ID)

  • 规则:1、首先比较DB_TRX_ID < up_limit_id,如果小于,则当前事务能看到DB_TRX_ID所在的记录,如果大于等于进入下一个判断,2、接下来判断DB_TRX_ID >= low_limit_id,如果大于等于则代表DB_TRX_ID所在的记录在Read View生成后才出现的,那么对于当前事务肯定不可见,如果小于,则进入下一步判断, 3、判断DB_TRX_ID是否在活跃事务中,如果在,则代表在Read View生成时刻,这个事务还是活跃状态,还没有commit,修改的数据,当前事务也是看不到,如果不在,则说明这个事务在Read View生成之前就已经开始commit,那么修改的结果是能够看见的。

    概述图及流程图如下

在这里插入图片描述
在这里插入图片描述

可重复读&读已提交实现原理

原理

  • 生成read_view时间不同
  • 可重复读是在事务开始时生成的read_view
  • 读已提交是在每次的快照读生成新的read_view

不可重复读演示

建表如下

create table t1
(
    id   int         not null
        primary key,
    name varchar(20) null,
    age  int         null
);
插入数据

INSERT INTO test_db.t1 (id, name, age) VALUES (1, '1', 1);
INSERT INTO test_db.t1 (id, name, age) VALUES (2, '2', 2);
事务1执行
SELECT @@transaction_isolation;

###################RR隔离级别下read view生成时机##########################

# 1.关闭自动事务提交
set autocommit  = 0;
# 2.开启事务
begin ;
# 4.查询表数据
select * from t1;
# 8.查询表数据
select * from t1;
# 10.再次查询表数据(查不到说明read view是在事务开始的时候生成的)
select * from t1;
# 11.提交事务
commit ;

###################RC隔离级别下read view生成时机##########################

# 1.设置隔离级别为RC
    set session transaction isolation level read committed ;

# 2.开启事务
begin ;
# 6.查询表数据
select * from t1;

# 7.在此查询表数据(可以查到数据)
select * from t1;

# 8.提交
commit ;
事务2执行
###################RR隔离级别下read view生成时机##########################
# 3.开启事务
begin ;
# 5.查询表数据
select * from t1;
# 6.新增一条数据
insert into t1 values (3,'3',3);
# 7.在此查询表数据
select * from t1;
# 9.提交事务
commit;

###################RC隔离级别下read view生成时机##########################

# 3.开启事务
begin ;
# 4.新增数据
insert into t1 values (4,'4',4);
# 5.查询表数据
select * from t1;
# 6.提交事务
commit;

幻读演示

建表
-- auto-generated definition
create table user
(
    id   int auto_increment
        primary key,
    name varchar(255) null,
    age  int          null
);
事务1执行
###################幻读产生##########################
truncate table  user;
# 0.数据准备
INSERT into user VALUES (1,'1',20),(5,'5',20),(15,'15',30),(20,'20',30);
# 1.开启事务
begin ;
# 3.查看数据
select * from user;
# 7.修改数据
update user set name = '9' where age = 20;
# 8.在此查询数据获取到了最新的数据
select * from user;
# 提交事务
commit ;


###################解决幻读##########################

# 1.设置锁的输出信息为on
set global innodb_status_output_locks = on;
# 2.开启事务
begin ;
# 5.查看锁信息
show engine innodb status;
# 6.加锁操作
select * from user where age = 20 for update ;
commit ;
事务2执行
###################幻读产生##########################

# 2.开启事务
begin ;
# 4.查看数据
select * from user;
# 5.新增数据
insert into user values (25,'25',20);
# 6.提交事务
commit ;




###################解决幻读##########################
# 3.开启事务
begin ;
# 4.查询数据
select * from user where age = 20;
# 7.新增数据会阻塞
insert into user values (30,'30',20);
# 8.提交事务
commit ;
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 01:18:22  更:2022-09-04 01:22:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:10:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码