我是靠谱客的博主 生动饼干,最近开发中收集的这篇文章主要介绍开启访问控制_MYSQL 并发访问控制原理简析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

    身为一名工程师,我们经常和数据库打交到。我想理解一下MYSQL的一些原理能更好的帮助我们写好代码。

    那么数据库有哪些隔离级别的呢?访问的时候是怎么做到隔离的?

MYSQL的隔离级别:

  • 可重复读(当开始当前事务时候读取某行数据,其他事务对这行数据进行修改提交事务后,当前事务再读取数据,看到的数据还是不变)

  • 读未提交(当开始当前事务读取某行数据,其他事务对其修改未提交事务,当前事务再去读该行数据,数据发生变化)

  • 读提交(当开始当前事务读取某行数据,其他事务对其修改且提交事务,当前事务再去读该行数据,数据发生变化)

  • 串行化(排队一个一个领盒饭56129051f4ef3cd150b77f80b7389eb4.png56129051f4ef3cd150b77f80b7389eb4.png)

    大家大概了解了数据库的隔离级别,那么今天我们讨论的并发访问控制是基于 可重复读 来探讨。MYSQL默认的事务隔离级别正是可重复读,我想我们平时工作中用的比较多的也就是可重复读的隔离级别。

来个例子:

    我们创建一张以下的表,有id和c两个字段

826eef3675db94e513444f2a081418cd.png

    给我们的客户端都设置为手动提交事务

    在可重复读的隔离级别下按照如下图的SQL执行顺序Q1~Q6结果分别是什么呢?56129051f4ef3cd150b77f80b7389eb4.png56129051f4ef3cd150b77f80b7389eb4.png

 2f364a5d65e5833f6684cd08834a9e2c.png

    大家看到这里可以停下来思考一下

-------------我是分割线------------

-------------我是分割线------------

   以下是分析结果:自己分析的结果是不是和我分析的一样呢?

032b7a8208432f906ee4d8e95c5681e4.png

  • Begin:并不是执行了begin就代表开启了事务,而是在执行第一条SQL的时候才会开启事务。

  • start transaction with  consistent snapshot:当使用这个命令开启事务的时候,就代表这条语句执行完后就开启了事务。

  • 当前读:直白的说是读取这行最新的数据(数据是版本控制的,后面和大家解释)

       通过上面的例子我想大家也对可重复读有了更多的了解。

    大家可能会想,这应该是通过版本来进行数据的控制把?嗯,我想也是。

通过版本来控制数据:

    首先我们来理解几个概念方便后面进行分析1e21d52734638d1be45e68af8db6cf63.png1e21d52734638d1be45e68af8db6cf63.png1e21d52734638d1be45e68af8db6cf63.png

  • 行数据中的隐藏列:(最新的事务id和回滚段指针)

f65d2f5e136f11f843bec4996a3248a3.png

  1. 每次行数据修改的时候会更新这两个隐藏的列

  • 数据的版本:

73bfce3c3e2058104e6c723778bdce34.png

  1. 数据从V1变成V2的时候会记录下undo log

  2. undo log 中包含了上个版本的事务id,旧记录的回滚指针

    和修改的字段信息等

  3. 而最新的事务id和回滚段指针会记录在行数据的隐藏列中

  4. 当数据处于V3版本想要找到上个版本的数据,可以通过找到的undo log计算出V2版本的行数据。往前追溯可依次类推。

  5. 所以磁盘上存储的行数据只有一份,多个事务对数据进行访问的时候,当前事务通过对数据的可见性来读取对应版本的数据。

数据的可见性:

  • 事务对数据的可见性:

8f62e552240956970422100a52e18756.png

  1. trx_id:是在事务开始的时候向InnoDB的事务系统申请的,是按申请顺序严格递增的。

  2. 事务视图:可以认为是一个数组,在开启事务的时候,会把当前活跃的事务id都记录在这个数组中,用于可见性判断。 

    我们已经了解了隔离的级别,数据是通过版本可以进行往前追溯,开启事务会有事务的视图,那么现在关键的是当前事务是怎样判断应该显示哪个版本的数据?

    这边给大家看一段伪代码。

3b997366b2db843d5131c35f829512c5.png

    大家可以看到,通过比较行数据中的trx_id和事务视图,可以判断出数据是否可见。

    我想大家脑袋里是否已经有一张图,当加载一行数据的时候,读取trx_id判断是否可见,不可见我们可以通过undolog去追溯上个版本数据和trx_id,反复往前追溯直到我们判断出数据是可见的,这时候会返回相关数据。

    我想大家需要的是这张图:

ecff9fb8c5c5ebb474800a348e252943.png

    以上这个图表达了SQL执行过程中的trx_id的变化和undolog的生成,我们可以分析一下T7的查询语句。

  1. 读取行数据,得到trx_id是101,数据不可见,寻找undolog

  2. 找到的undolog中的上个版本的trx_id是102,数据不可见。使用该undolog将数据修改到V2版本。并且通过回滚指针找到再上一个undolog(第二个undolog)。

  3. 找到了第二个undolog,发现上一个版本的trx_id是80(V1版本数据),表示数据可见,那么使用undolog将数据回滚到V1版本

  4. 返回数据(c= 0)

    经过以上烧脑的内容,我想你已经理解了MYSQL是如何做并发访问控制的。最后再给大家总结一下。

  1. 数据表中有两个隐藏列:data_trx_id和data_roll_ptr,每次数据修改后会更新data_trx_id和data_roll_ptr。

  2. 每次数据修改的时候都会将原先的data_trx_id,data_roll_ptr和修改的字段信息记录到undolog。

  3. 数据可以通过undolog往前追溯历史版本的数据

  4. 开始事务的时候会生成事务ID和事务视图。

  5. 当进行查询的时候,可以通过事务对数据可见性的判断,选择是返回数据还是往前追溯数据,直到满足可见性要求。

参考内容:

《MYSQL技术内容InnoDB存储引擎》

《MYSQL实战45讲》

最后

以上就是生动饼干为你收集整理的开启访问控制_MYSQL 并发访问控制原理简析的全部内容,希望文章能够帮你解决开启访问控制_MYSQL 并发访问控制原理简析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部