MYSQL
-
引擎:Innodb和MyISAM.
a. 区别:
-
InooDB支持行级锁(row-level locking)和表级锁,默认为行级锁,MyISAM只支持表锁,
-
InooDB默认隔离级别是可重复读,MyISAM不支持事务,所以没有隔离级别的概念。
-
InooDB有聚簇索引(只有主键有,索引段直接和数据绑定在一起),MyISAM没有。这导致了回表的问题。(回表:用非聚簇索引,指向的是文件的地址,通过非主键索引会查到主键,再根据主键回表继续查主键索引才能得到数据)
-
是否支持外键: MyISAM不支持,而InnoDB支持。
-
索引
-
聚簇索引
-
覆盖索引,可以避免回表
-
索引下推,MySql5.6新特性
-
-
事务:
-
什么是事务:事务是逻辑上的一组操作,要么都执行,要么都不执行。
-
事物的特性:原子性,一致性,隔离性,持久性。
- 原子性:事务是最小的执行单位,不允许分割。事务的原子性保证一个事务的所有操作要么都执行完成,要么都完全不起作用。
- 一致性:指事务完成前后,数据保持一致,数据库完整性没被破坏。
- 隔离性:事务之间不互相干扰,都是独立的。
- 持久性:一个事务被提交后,对数据库中的数据的改变是持久的。
-
并发事务带来的问题:
- 脏读:当一个事务修改了数据还没提交时,另一个事务读取到未提交的数据。(InnoDB采用Write Ahead Log策略来防止宕机数据丢失,即事务提交时,先写重做日志,再修改内存数据页,这时候内存页的数据还没写入磁盘,这样就产生了脏页(内存页)。)
- 丢失修改:即两个事务同时读取某一数据,并进行修改,则先提交的事务会丢失修改。
-
-
不可重复读:(侧重在修改)一个事务读取某一数据,这时另一个事务修改了数据,这时第一个事务再次读取数据时,数据前后不一致。
-
幻读:也是一种不可重复读,只是重点在新增和删除。
-
事务隔离级别:
set global transaction isolation level read uncommitted
- READ-UNCOMMITTED(读取未提交),最低的隔离级别,允许读取尚未提交的数据变更,可能导致脏读、不可重复读和幻读。
- READ-COMMITTED(读取已提交),允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
- REPEATABLE-READ(可重复读),对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
- SERIALIZABLE(可串行化):最高的隔离级别,事务逐个进行。该级别可以防止脏读、不可重复读以及幻读。
MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)。由于InnoDB会以Next-Key Lock 锁进行加锁,可以防止幻读的发生。MySQL 8.0 查看隔离级别 命令改为
SELECT @@transaction_isolation;
InnoDB存储引擎的锁的算法有三种:
- Record lock:单个行记录上的锁
- Gap lock:间隙锁,锁定一个范围,不包括记录本身
- Next-key lock:record+gap 锁定一个范围,包含记录本身
相关知识点:
-
innodb对于行的查询使用next-key lock
- Next-locking keying为了解决Phantom Problem幻读问题
-
当查询的索引含有唯一属性时,将next-key lock降级为record key 如果查询的是主键,主键唯一,则为record key
- Gap锁设计的目的是为了阻止多个事务将记录插入到同一范围内,而这会导致幻读问题的产生
-
有两种方式显式关闭gap锁:(除了外键约束和唯一性检查外,其余情况仅使用record lock) A. 将事务隔离级别设置为RC B. 将参数innodb_locks_unsafe_for_binlog设置为1
Next-Key Lock是行锁和间隙锁的组合,当InnoDB扫描索引记录的时候,会首先对索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。加上间隙锁之后,其他事务就不能在这个间隙修改或者插入记录。
GAP的区间如下:是一个左开右闭的空间( 原因是默认主键的有序自增的特性 )。Gap Lock在InnoDB的唯一作用就是防止其他事务的插入操作,以此防止幻读的发生。
行锁锁定的是索引记录,而不是行数据,也就是说锁定的是key。
-