云南网站开发报价,免费博客网站,长沙微推广平台,网站运营与公司一#xff1a;概念介绍
MySQL数据库锁管理机制#xff1a;
SQL层实现的锁机制 Meta-data元数据锁#xff1a;在table cache缓存里实现的#xff0c;为DDL#xff08;Data Definition Language#xff09;提供隔离操作。一种特别的meta-data元数据类型#xff0c;…一概念介绍
MySQL数据库锁管理机制
SQL层实现的锁机制 Meta-data元数据锁在table cache缓存里实现的为DDLData Definition Language提供隔离操作。一种特别的meta-data元数据类型叫Name Lock。 表级table-level数据锁 全局读锁—FLUSH TABLES WITH READ LOCK
引擎层实现的锁机制 存储引擎特有机制—row locks行锁page locks页锁table locks表级版本控制 MySQL常用存储引擎的锁机制
MyISAM 和 MEMORY 采用表级锁(table-level locking)BDB 采用页面锁(page-level locking)或表级锁默认为页面锁InnoDB 支持行级锁(row-level locking)和表级锁, 默认为行级锁
锁分类
按思想悲观锁、乐观锁按锁粒度行级锁、间隙锁、页级锁、表级锁按锁性质排它锁X、共享锁S、意向排它锁IX、意向共享锁IS,读锁一般为共享锁、写锁一般为排它锁
其中InnoDB是最常见的MySQL存储引擎以下以它为例
二Innodb 中的锁机制
Innodb 中的行锁与表锁
在 Innodb 引擎中既支持行锁也支持表锁那么什么时候会锁住整张表什么时候或只锁住一行呢
InnoDB 行锁是通过给索引上的索引项加锁来实现的这一点 MySQL 与 Oracle 不同后者是通过在数据块中对相应数据行加锁来实现的。InnoDB 这种行锁实现特点意味着只有通过索引条件检索数据InnoDB 才使用行级锁否则InnoDB 将使用表锁
在分析锁冲突时, 可以检查 SQL 的执行计划, 以确认是否真正使用了索引。
为什么Innodb 会出现死锁
MyISAM 中是不会产生死锁的因为 MyISAM 总是一次性获得所需的全部锁要么全部满足要么全部等待。而在 InnoDB 中锁是逐步获得的就造成了死锁的可能。
在 MySQL 中行级锁并不是直接锁记录而是锁索引。索引分为主键索引和非主键索引两种如果一条 sql 语句操作了主键索引MySQL 就会锁定这条主键索引如果一条语句操作了非主键索引MySQL 会先锁定该非主键索引再锁定相关的主键索引。 在 UPDATE、DELETE 操作时MySQL 不仅锁定 WHERE 条件扫描过的所有索引记录而且会锁定相邻的键值即所谓的 next-key locking。
当两个事务同时执行一个锁住了主键索引在等待其他相关索引。另一个锁定了非主键索引在等待主键索引。这样就会发生死锁。
Innodb的死锁处理
在Innodb的事务管理和锁定机制中有专门检测死锁的机制会在系统中产生死锁之后的很短时间内就检测到该死锁的存在。
当Innodb检测到系统中产生了死锁之后Innodb会通过相应的判断来选这产生死锁的两个事务中较小的事务来回滚而让另外一个较大的事务成功完成。
Innodb行锁优化建议
尽可能让所有的数据检索都通过索引来完成从而避免Innodb因为无法通过索引键加锁而升级为表级锁定合理设计索引让Innodb在索引键上面加锁尽可能准确尽可能的缩小锁定范围避免造成不必要的锁定而影响其他Query的执行尽可能减少基于范围的数据检索过滤条件避免间隙锁带来的负面影响而锁定了不该锁定的记录尽量控制事务的大小减少锁定的资源量和锁定时间长度在业务环境允许的情况下尽量使用较低级别的事务隔离以减少MySQL因为实现事务隔离级别所带来的附加成本
如何预防死锁
有多种方法可以避免死锁这里只介绍常见的三种
1、如果不同程序会并发存取多个表尽量约定以相同的顺序访问表可以大大降低死锁机会。
2、在同一个事务中尽可能做到一次锁定所需要的所有资源减少死锁产生概率
3、对于非常容易产生死锁的业务部分可以尝试使用升级锁定颗粒度通过表级锁定来减少死锁产生的概率
三锁分类
3.1 按思想
悲观锁、乐观锁见之前写的博文
3.2 按粒度
行级锁 是MySQL中粒度最小的锁所以发生锁定资源争用的概率也最小。 但是由于粒度最小导致开销大加锁慢并且最容易死锁。
表级锁
表级别的锁定是MySQL各存储引擎中最大颗粒度的锁定机制。该锁定机制最大的特点是实现逻辑简单带来的系统负面影响最小。所以获取锁和释放锁的速度很快。由于表级锁一次会将整个表锁定所以可以很好的避免死锁问题。 当然锁定颗粒度大所带来最大的负面影响就是出现锁定资源争用的概率也会最高致使并大度较低。
页级锁
页级锁定的特点是锁定颗粒度介于行级锁定与表级锁之间所以获取锁定所需要的资源开销以及所能提供的并发处理能力也同样是介于上面二者之间。另外页级锁定和行级锁定一样会发生死锁。 在MySQL数据库中使用表级锁定的主要是MyISAMMemoryCSV等一些非事务性存储引擎而使用行级锁定的主要是Innodb存储引擎和NDBCluster存储引擎页级锁定主要是BerkeleyDB存储引擎的锁定方式。
间隙锁 3.3 按性质
排它锁(exclusive lock)
排它锁又叫写锁如果事务T对A加上排它锁则其它事务都不能对A加任何类型的锁。获准排它锁的事务既能读数据又能写数据。
用法SELECT … FOR UPDATE共享锁(share lock)
共享锁又叫读锁如果事务T对A加上共享锁则其它事务只能对A再加共享锁不能加其它锁。获准共享锁的事务只能读数据不能写数据。
用法SELECT … LOCK IN SHARE MODE;
意向锁(share lock)
为了允许行锁和表锁共存实现多粒度锁机制InnoDB还有两种内部使用的意向锁Intention Locks这两种意向锁都是表锁。
意向共享锁IS事务打算给数据行加行共享锁事务在给一个数据行加共享锁前必须先取得该表的IS锁。
意向排他锁IX事务打算给数据行加行排他锁事务在给一个数据行加排他锁前必须先取得该表的IX锁。
四并发事务处理带来的问题
✈ 更新丢失Lost Update 当两个或多个事务选择同一行然后基于最初选定的值更新该行时由于每个事务都不知道其他事务的存在就会发生丢失更新问题–最后的更新覆盖了由其他事务所做的更新。 ✈ 脏读Dirty Reads 一个事务正在对一条记录做修改在这个事务完成并提交前这条记录的数据就处于不一致的状态这时另一个事务也来读取同一条记录如果不加控制第二个事务读取了这些“脏”数据并据此作进一步的处理就会产生未提交的数据依赖关系。这种现象被形象的叫做“脏读”。 一句话事务A读取到了事务B已经修改但尚未提交的数据还在这个数据基础上做了操作。此时如果B事务回滚A读取的数据无效不符合一致性要求。 ✈ 不可重读Non-Repeatable Reads 一个事务在读取某些数据后的某个时间再次读取以前读过的数据却发现其读出的数据已经发生了改变、或某些记录已经被删除了这种现象就叫做“不可重复读”。 一句话事务A读取到了事务B已经提交的修改数据不符合隔离性 ✈ 幻读Phantom Reads 一个事务按相同的查询条件重新读取以前检索过的数据却发现其他事务插入了满足其查询条件的新数据这种现象就称为“幻读”。 一句话事务A读取到了事务B提交的新增数据不符合隔离性
脏读是事务B里面修改了数据 幻读是事务B里面新增了数据
事务隔离级别