MySQL锁

MySQL锁_第1张图片
锁目录.PNG

一. 锁概述

InnoDB默认支持行级锁,但也支持表级锁
MyISAM,Memory支持表级锁

三种锁特性

1. 表级锁

用于查询为主,少量按索引条件更新

开销小,加锁快
不会出现死锁
锁粒度大,锁冲突概率高,并发度低

2. 行级锁

适用于大量按索引条件更新数据,如OLTP

开销大,加锁慢
会出现死锁
锁粒度小,锁冲突概率低,并发度高

3. 页面锁

加锁时间介于前二者之间
会出现死锁
并发度一般

二. MyISAM表锁

1. 表锁兼容性

读写互斥

MySQL锁_第2张图片

2. 如何加表锁

MyISAM在select前自动加读锁,更新前自动加写锁
MyISAM总是一次性获得SQL语句的所有锁---故无死锁

3. MyISAM锁调度

读写互斥,且写请求比读请求重要
故不适用大量更新和查询应用(查询操作被永远阻塞)

避免长时间查询操作,导致饿死写请求--不要想一条SELECT搞定所有

三. 事务论

支持事务;采用行级锁

1. 事务的ACID特性

Atomicity 原子性

数据修改,要么全执行,要么全不执行

Consistent 一致性

事务开始和完成时,数据一致

Isolation 隔离性

事务不受外部并发操作影响,独立执行

Durable 持久性

事务完成后,数据修改是永久性的,系统故障也能保持

2. 并发事务问题(锁问题)

1) 更新丢失

最后的更新覆盖了其他事务所做的更新
必须完全避免

2)脏读

一个事务修改了记录,但未提交,同时另一个事务对该记录进行读取

3)不可重复读

事务再次读取之前读过的数据,该数据已改变或该记录已被删除

4)幻读

一个事务相同条件查询,发现其他事务插入了满足条件的新数据

3. 事务隔离级别

脏读、不可重复读、幻读----数据库读一致性问题,事务隔离机制来解决

1) 事务隔离方式

  1. 读取数据前加锁
  2. MVCC(multiversion concurrency control ) --多版本并发控制(或多版本数据库)
    生成数据请求时间点 一致性数据快照(同一数据,多个版本)

MVCC实现InnoDB一致性非锁定读

若读取的行正在delete,update操作,不等待行上锁释放,转去读取行的一个数据快照。如下图

MySQL锁_第3张图片

2) 事务隔离级别

用以解决隔离与并发的矛盾,分为四种:

未提交读(导致脏读,很少用)
已提交读(大多数数据库默认级别
可重复读(mysql默认,无法解决幻读)

可序列化(每行加锁,导致大量超时和锁争用,很少使用)

MySQL锁_第4张图片
事务隔离级别

四. InnoDB锁

1. InnoDB行锁模式及加锁方法

两种行锁:

1) 共享锁(S)

  • 允许一个事务读一行,阻止其他事务获得相同数据的 排他锁
  • 加锁语句:
    select * from table where... LOCK IN SHARE MODE

2) 排他锁(X)

  • 持X的事务可更新数据,阻止其他事务(取得相同数据集)的 共享读锁排他写锁
  • 加锁语句:
    select * from table where...FOR UPDATE

两种意向锁(表锁):

InnoDB自动加
对更新语句,自动加X锁
普通SELECT语句,不加锁

1) 意向共享锁(IS)

事务想获得表中某几行的共享锁
事务在对数据行加S锁前,必须先取得表IS锁

2)意向排他锁(IX)

事务想获得表中某几行的排他锁


MySQL锁_第5张图片

2. InnoDB行锁实现方式

  • InnoDB行锁通过对索引项加锁实现
  • 无索引,则通过聚簇索引加锁
  • 不通过索引条件检索,InnoDB会锁定所有记录,导致大量锁冲突,效果等同于表锁

三种InnoDB锁算法

1) record lock

索引项加锁

2) gap lock

对第一条记录前,索引项之间,最后一条记录之后 的 间隙 加锁

3) next-key lock

前二者组合,对记录和前面的间隙加锁
用于范围条件查询

3. Next-Key锁

Gap

键值在条件范围内,但不存在的记录

目的

防止幻读
恢复和复制机制需要

会阻塞条件范围内键值插入,导致严重锁等待,故尽量用相等条件

例:

id={1,2,3....101}
select * from table where id>100 for update

对101,>101(间隙)加锁

五. 如何避免死锁

MySQL锁_第6张图片

@其他补充

你可能感兴趣的:(MySQL锁)