事务隔离级别

(4)在客户端A,接着执行update balance = balance - 50 where id = 1,balance没有变成400-50=350,lilei的balance值用的是步骤(2)中的350来算的,所以是300,数据的一致性倒是没有被破坏。可重复读的隔离级别下使用了MVCC机制,select操作不会更新版本号,是快照读(历史版本);insert、update和delete会更新版本号,是当前读(当前版本)

补充:

 1、事务隔离级别为读提交时,写数据只会锁住相应的行

 2、事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key 锁;如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以防止幻读。

 3、事务隔离级别为串行化时,读写数据都会锁住整张表

  4、隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。

  5、MYSQL MVCC实现机制参考链接:https://blog.csdn.net/whoamiyang/article/details/51901888

+++++++++++++++++++++++++++++++++++++++++++++++++++

1.1 什么是MVCC

MVCC是一种多版本并发控制机制。

1.2 MVCC是为了解决什么问题?

大多数的MYSQL事务型存储引擎,如,InnoDB,Falcon以及PBXT都不使用一种简单的行锁机制.事实上,他们都和MVCC–多版本并发控制来一起使用.

大家都应该知道,锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销.

1.3 MVCC实现

MVCC是通过保存数据在某个时间点的快照来实现的. 不同存储引擎的MVCC. 不同存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制.

2.MVCC 具体实现分析

下面,我们通过InnoDB的MVCC实现来分析MVCC使怎样进行并发控制的.

InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的,这两个列,分别保存了​这个行的创建时间,一个保存的是行的删除时间​。这里存储的并不是实际的时间值,而是系统版本号(可以理解为事务的ID),每开始一个新的事务,系统版本号就会自动递增,事务开始时刻的系统版本号会作为事务的ID.下面看一下在REPEATABLE READ隔离级别下,MVCC具体是如何操作的

知识点复习 22 Mysql 知识点03_版本号

SELECT

InnoDB会根据以下两个条件检查每行记录:

a.InnoDB只会查找版本早于当前事务版本的数据行(也就是,行的系统版本号小于或等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的.

b.行的删除版本要么未定义,要么大于当前事务版本号,这可以确保事务读取到的行,在事务开始之前未被删除.

只有a,b同时满足的记录,才能返回作为查询结果

知识点复习 22 Mysql 知识点03_并发控制_02

知识点复习 22 Mysql 知识点03_mvc_03

知识点复习 22 Mysql 知识点03_并发控制_04

知识点复习 22 Mysql 知识点03_版本号_05

知识点复习 22 Mysql 知识点03_版本号_06

知识点复习 22 Mysql 知识点03_版本号_07


知识点复习 22 Mysql 知识点03_并发控制_08

知识点复习 22 Mysql 知识点03_版本号_09

数据库知识

##数据库隔离级别有哪些,各自的含义是什么,MYSQL 默认的隔离级别是是什么。

·未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据

·提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)

·可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读。 通过mvcc和间隙锁解决

·串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

MYSQL默认是RepeatedRead级别

MYSQL 有哪些存储引擎,各自优缺点。

MyISAM: 拥有较高的插入,查询速度,但不支持事务

InnoDB :5.5版本后Mysql的默认数据库,事务型数据库的首选引擎,支持ACID事务,支持行级锁定

BDB: 源自Berkeley DB,事务型数据库的另一种选择,支持COMMIT和ROLLBACK等其他事务特性

Memory :所有数据置于内存的存储引擎,拥有极高的插入,更新和查询效率。但是会占用和数据量成正比的内存空间。并且其内容会在Mysql重新启动时丢失

Merge :将一定数量的MyISAM表联合而成一个整体,在超大规模数据存储时很有用

Archive :非常适合存储大量的独立的,作为历史记录的数据。因为它们不经常被读取。Archive拥有高效的插入速度,但其对查询的支持相对较差

Federated: 将不同的Mysql服务器联合起来,逻辑上组成一个完整的数据库。非常适合分布式应用

Cluster/NDB :高冗余的存储引擎,用多台数据机器联合提供服务以提高整体性能和安全性。适合数据量大,安全和性能要求高的应用

CSV: 逻辑上由逗号分割数据的存储引擎。它会在数据库子目录里为每个数据表创建一个.CSV文件。这是一种普通文本文件,每个数据行占用一个文本行。CSV存储引擎不支持索引。

BlackHole :黑洞引擎,写入的任何数据都会消失,一般用于记录binlog做复制的中继

高并发下,如何做到安全的修改同一行数据。

使用悲观锁 悲观锁本质是当前只有一个线程执行操作,结束了唤醒其他线程进行处理。

也可以缓存队列中锁定主键。

乐观锁和悲观锁是什么,INNODB 的行级锁有哪 2 种,解释其含义。

乐观锁是设定每次修改都不会冲突,只在提交的时候去检查,悲观锁设定每次修改都会冲突,持有排他锁。

行级锁分为共享锁和排他锁两种 共享锁又称读锁 排他锁又称写锁


SQL 优化的一般步骤是什么,怎么看执行计划,如何理解其中各个字段的含义。


查看慢日志(show [session|gobal] status ),定位慢查询,查看慢查询执行计划 根据执行计划确认优化方案

Explain sql

select_type:表示select类型。常见的取值有SIMPLE(简单表,即不使用连接或者子查询)、PRIMARY(主查询,即外层的查询)、UNION(union中的第二个或者后面的查询语句)、SUBQUERY(子查询中的第一个SELECT)等。

talbe:输出结果集的表。

type:表的连接类型。性能由高到底:system(表中仅有一行)、const(表中最多有一个匹配行)、eq_ref、ref、ref_null、index_merge、unique_subquery、index_subquery、range、idnex等

possible_keys:查询时,可能使用的索引

key:实际使用的索引

key_len:索引字段的长度

rows:扫描行的数量

Extra:执行情况的说明和描述

++++++++++++++++++++++++++++++++

数据库会死锁吗,举一个死锁的例子,mysql 怎么解决死锁。

产生死锁的原因主要是:

(1)系统资源不足。

(2) 进程运行推进的顺序不合适。

(3)资源分配不当等。

如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。

产生死锁的四个必要条件:

(1) 互斥条件:一个资源每次只能被一个进程使用。

(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

例子 :

知识点复习 22 Mysql 知识点03_并发控制_10

这里提供两个解决数据库死锁的方法:

1)重启数据库(谁用谁知道)

2)杀掉抢资源的进程:

先查哪些进程在抢资源:SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;

杀掉它们:Kill trx_mysql_thread_id;

知识点复习 22 Mysql 知识点03_mvc_11

mysql为什么最左匹配?

知识点复习 22 Mysql 知识点03_版本号_12​​mysql会优化成最左匹配的顺序,所以还是可以利用索引的

知识点复习 22 Mysql 知识点03_mvc_13

数据库中 BTREE 和 B+tree 区别。

B+是btree的变种,本质都是btree,btree+与B-Tree相比,B+Tree有以下不同点:

每个节点的指针上限为2d而不是2d+1。

内节点不存储data,只存储key;叶子节点不存储指针。


Btree 怎么分裂的,什么时候分裂,为什么是平衡的。

Key 超过1024才分裂B树为甚会分裂? 因为随着数据的增多,一个结点的key满了,为了保持B树的特性,就会产生分裂,一般3层就足够了

知识点复习 22 Mysql 知识点03_并发控制_14

知识点复习 22 Mysql 知识点03_版本号_15

  1、exists是对外表做loop循环,每次loop循环再对内表(子查询)进行查询,那么因为对内表的查询使用的索引(内表效率高,故可用大表),而外表有多大都需要遍历,不可避免(尽量用小表),故内表大的使用exists,可加快效率;

 2、in是把外表和内表做hash连接,先查询内表,再把内表结果与外表匹配,对外表使用索引(外表效率高,可用大表),而内表多大都需要查询,不可避免,故外表大的使用in,可加快效率。

 3、如果用not in ,则是内外表都全表扫描,无索引,效率低,可考虑使用not exists,也可使用A left join B on = where is null 进行优化。