mysql优化之锁机制与结构
2021/8/23 2:28:49
本文主要是介绍mysql优化之锁机制与结构,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录- 死锁
- 产生死锁的场景
- mysql死锁的演示
- mysql处理死锁的方式
- 死锁检测
- 回滚
- MVCC-乐观锁
- mvvc介绍
- 应用场景
- 悲观锁
- 应用场景
- 超卖问题的演示
- 应用场景
- 间隙锁
- 行锁升级为表锁
- InnoDB表锁定机制的列子
- 总结
- 事务的使用建议
- mysql大体结构
死锁
产生死锁的场景
死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产 生了死锁,这些永远在互相等待的进程称为死锁进程.表级锁不会产生死锁.所以解决死锁主要还是针对于最常用的InnoDB
mysql死锁的演示
通常在应用中,在事务隔离级别RR级别下,两个事务对相同的数据使用了排它锁,在没有符合该条件的情况下,两个事务都会加锁成功。如果是在程序中发现记 录不存在,就新增一条数据,如果两个事务都这么做,就会发生死锁的情况。
mysql处理死锁的方式
1. 等待,直到超时(innodb_lock_wait_timeout=50s)。 2. 发起死锁检测,主动回滚一条事务,让其他事务继续执行(innodb_deadlock_detect=on)。
死锁检测
死锁检测的原理是构建一个以事务为顶点、锁为边的有向图,判断有向图是否存在环,存在即有死锁。
回滚
检测到死锁之后,选择插入更新或者删除的行数最少的事务回滚,基于 INFORMATION_SCHEMA.INNODB_TRX 表中的 trx_weight 字段来判断。
MVCC-乐观锁
mvvc介绍
英文全称为Multi-Version Concurrency Control,翻译为中文即 多版本并发控制。MVCC使得InnoDB的事务隔离级别下执行一致性读操作有了保证,换言之,就是 为了查询一些正在被另一个事务更新的行, 并且可以看到它们被更新之前的值。这是一个可以用来增强并发性的强大的技术,因为这样一来的话查询就不用等 待另一个事务释放锁。这项技术在数据库领域并不是普遍使用的。一些其它的数据库产品, 以及mysql其它的存储引擎并不支持它。
mysql的innodb表除了实际的数据之外,还会加上3个隐藏的字段,如下:
实际数据 | create_no(创建版本号或者创建时间) | update_no(每次修改的版本号或者修改时间) | delete_no(删除版本号或者删除时间) |
---|
insert:当我们新增一条数据时,这条数据会加上创建的版本号 update:修改当前的字段,每修改一次数据,修改版本号都会依次增加一次 delete:删除当前的数据,其实并不会真实的删除,他会先在删除版本号字段记录下删除的版本号,在过了一段时间后会进行清除或者刷新
应用场景
一般是解决超卖问题
注意 : MVCC是乐观锁的一种实现方式,但并不是MVCC就等于乐观锁。
悲观锁
悲观并发控制(又名“悲观锁”,Pessimistic Concurrency Control,缩写“PCC”)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数 据。如果一个事务执行的操作读某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。
应用场景
在商品购买场景中,当有多个用户对某个库存有限的商品同时进行下单操作。若采用先查询库存,后减库存的方式进行库存数量的变更,将会导致超卖的产生。
超卖问题的演示
间隙锁
当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但不存在的 记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(NEXT-KEY)锁。
行锁升级为表锁
InnoDB 行级锁是通过给索引上的索引项加锁来实现的,InnoDB行级锁只有通过索引条件检索数据,才使用行级锁;否则,InnoDB使用表锁在不通过索引(主 键)条件查询的时候,InnoDB是表锁而不是行锁。
通常begin-end用于定义一组语句块
InnoDB表锁定机制的列子
总结
就是在没有使用索引的情况下InnoDB就会使用表级锁(共享锁不会有这个情况)
事务的使用建议
innodb存储引擎由于实现了行级锁,颗粒更小,实现更复杂。但是innodb行锁在并发性能上远远要高于表锁页锁。在使用方面可以尽量做到以下几点;
1. 控制事务大小,减少锁定的资源量和锁定时间长度。 2. 所有的数据检索都通过索引来完成,从而避免因为无法通过索引加锁而升级为表锁。 3. 减少基于范围的数据检索过滤条件,避免因为间隙锁带来的负面影响而锁定了不该锁定的数据。 4. 在业务条件允许下,尽量使用较低隔离级别的事务隔离。减少隔离级别带来的附加成本。 5. 合理使用索引,让innodb在索引上面加锁的时候更加准确。 6. 在应用中尽可能做到访问的顺序执行 7. 如果容易死锁,就可以考虑使用表锁来减少死锁的概率
mysql大体结构
客户端 = Connection(语言连接器例如:PHP-pdo,MySQLi)
服务端 = SQL层 + 存储引擎层
SQL层 = 链接/线程处理 + 查询缓存 + 分析器 + 优化器
存储引擎 = InnoDB + MariaDB + ..... Connection:这一块其实主要是其他语言的连接,并不属于MySQL本身;主要是其他语言对于MySQL的连接操作的工具比 如PHP中的:pdo,mysqli或者 Navicat for MySQL SQL层:
功能主要包括权限判断,SQL解析功能和查询缓存处理等。
1. 链接/线程处理:客户端通过 连接/线程层 来连接MySQL数据库,连接/线程层主要用来处理客户端的请求、身份验证和数据库安全性验证等。 2. 查询缓存和查询分析器是SQL层的核心部分,其中主要涉及查询的解析、优化、缓存、以及所有内置的函数,存储过程,触发器,视图等功能。 3. 优化器主要负责存储和获取所有存储在MySQL中的数据。
这篇关于mysql优化之锁机制与结构的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-25如何部署MySQL集群资料:新手入门教程
- 2024-12-24MySQL集群部署资料:新手入门教程
- 2024-12-24MySQL集群资料详解:新手入门教程
- 2024-12-24MySQL集群部署入门教程
- 2024-12-24部署MySQL集群学习:新手入门教程
- 2024-12-24部署MySQL集群入门:一步一步搭建指南
- 2024-12-07MySQL读写分离入门:轻松掌握数据库读写分离技术
- 2024-12-07MySQL读写分离入门教程
- 2024-12-07MySQL分库分表入门详解
- 2024-12-07MySQL分库分表入门指南