MySQL 的ASID

您所在的位置:网站首页 沧海一声笑版本对比 MySQL 的ASID

MySQL 的ASID

2024-07-10 09:45| 来源: 网络整理| 查看: 265

MySQL的结构

MySQL数据引擎 InnoDB 和 MyISam 的区别 事务方面

InnoDB 支持事务,而 MyISam 不支持事务。这个是 mysql 将默认引擎改为 InnoDB 的主要原因。

外键方面

InnoDB 支持外键,而 MyISaM 不支持外键

索引方面

InnoDB是聚簇索引,而 MyISam 是非聚簇索引

锁的粒度

InnoDB是行锁, MyISam是表锁,这也是把 myISAM 改成 InnoDB的一个重要原因

保存的文件格式

MyISAM 是有三个文件

.frm 存储表的定义

.myd 存的是数据

.myi 存的是索引

InnoDB 有两个文件(没有专门保存数据的文件)

.frm 表的定义

.idb 数据和索引存储文件

非聚簇索引。索引和数据是分开存的

image

聚簇索引,索引和数据是一起存的

image

所以也就明白了为什么尽量使用覆盖索引?

正如下图,如果使用覆盖索引,直接就把数据拿出来了,而不需要再去主键索引里去查找了

image

ACID

原子性(atomicity)

一致性(consistency)

持久性(isolation)

隔离性(durability)

并发控制的时候,出现的三种问题 脏读

指当一个事务正在访问数据,并且对数据进行了修改,而这种数据还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据还没有提交那么另外一个事务读取到的这个数据我们称之为脏数据。依据脏数据所做的操作肯能是不正确的。

不可重复读

不可重复读:指在一个事务内,多次读同一数据。在这个事务还没有执行结束,另外一个事务也访问该同一数据,那么在第一个事务中的两次读取数据之间,由于第二个事务的修改第一个事务两次读到的数据可能是不一样的,这样就发生了在一个事物内两次连续读到的数据是不一样的,这种情况被称为是不可重复读。

幻读

幻象读:一个事务先后读取一个范围的记录,但两次读取的纪录数不同,我们称之为幻象读(两次执行同一条 select 语句会出现不同的结果,第二次读会增加一数据行,并没有说这两次执行是在同一个事务中)

其实仔细想想,就脏读和不可重复读两种情况,幻读只不过是读多行的不可重复读

在标准的 SQL 规范中,事务的隔离级别有四种 读未提交

事务 A 和事务 B 同时执行,事务 A 在整个执行过程中,把数据从 1 加到 10 ,而事务 B可以看到事务 A操作的中间值。所有他会脏读

读已提交

示例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他埋单时(程序员事务开启),收费系统事先检测到他的卡里有3.6万,就在这个时候!!程序员的妻子要把钱全部转出充当家用,并提交。当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了(第二次检测金额当然要等待妻子转出金额事务提交完)。程序员就会很郁闷,明明卡里是有钱的…

注意:

也就说,事务对数据进行 读 操作时,读操作事务要等待这个 写 操作事务提交后才能读取数据

可重复读

事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他埋单时(事务开启,不允许其他事务的UPDATE修改操作),收费系统事先检测到他的卡里有3.6万。这个时候他的妻子不能转出金额了。接下来收费系统就可以扣款了。

注意:

重复读可以解决不可重复读问题。写到这里,应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。

串行化

是最严格的事务隔离级别,它要求所有事务被串行执行,即事务只能一个接一个的进行处理,不能并发执行。

总结一下这四种隔离级别

为什么会出现“脏读”?因为没有select操作没有规矩。

为什么会出现“不可重复读”?因为update 操作没有规矩。

为什么会出现“幻读”?因为insert和delete操作没有规矩。

“读未提(Read Uncommitted)”能预防啥?啥都预防不了。

“读提交(Read Committed)”能预防啥?使用“快照读(Snapshot Read)”,避免“脏读”,但是可能出现“不可重复读”和“幻读”。

“可重复读(Repeated Red)”能预防啥?使用“快照读(Snapshot Read)”,锁住被读取记录,避免出现“脏读”、“不可重复读”,但是可能出现“幻读”。

“串行化(Serializable)”能预防啥?排排坐,吃果果,有效避免“脏读”、“不可重复读”、“幻读”,不过效果谁用谁知道。

在mysql数据引擎中,使用 MVCC 实际上就可以解决了已提交和不可重复读的问题,这个和readview 的生成时间有关。而且我们可以通过 innodb 引擎中,通过添加间隙锁,防止添加数据,从而解决幻读的问题。

image

mysql 的默认隔离级别

mysql的默认隔离界别是可重复读,但是一般项目我们会把隔离级别更改成 读已提交。

mysql5.0 之前默认的隔离级别是读已提交, 5.0 以后的版本改成了 可重复读,原因是使用读已提交,在进行 主从复制 的时候,会存在大量的不一致的情况。

这个主要是和主从复制使用的 binglog 日志文件的格式有关

statement:记录的是修改SQL语句

row:记录的是每行实际数据的变更

mixed:statement和row模式的混合

为什么很多人会把读已提交,当作默认的隔离级别呢?

因为 可重复读 会让死锁的概率增大,在 可重复读 的条件下,条件未命中,将会引发表锁,而在 读已提交 的隔离级别下,只会锁行。

select * from test where id max_tex_id 不可访问 min_trx_id=< 事务ID =


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3