对InnoDB存储引擎的锁基本使用MySQL
MyISAM和内存使用表级锁(表级锁)BDB使用页锁(页级锁定)或表级锁,默认页锁
InnoDB支持行级锁(行级锁)和表级锁,默认是行级锁
各种锁具的特点
表锁:低开销、快速锁定、无死锁、大锁粒度、最高冲突概率和最低并发性。
行级锁:高开销、慢锁、死锁、最小锁粒度、最低锁冲突概率和最高并发性。
页面锁:开销和锁定时间介于表锁和行锁之间;死锁将出现;锁粒度介于表锁和行锁之间,并发性是常见的。
InnoDB存储引擎锁
InnoDB存储引擎实现了以下两锁
1,共享锁(s锁),允许事务读取一行数据
2、X锁,允许事务更新或删除一行数据
共享锁和排除锁的兼容性如下图所示
未读一致性
一致的非锁定读一致性,InnoDB存储引擎读取的方式行多版本控制在当前的执行时间数据库行的方式(多版本)。如果读行执行删除和更新操作,这是读操作,所以它不会等待锁的释放。相反,InnoDB会读一行数据的快照。
它被称为打开阅读因为它不需要等待就行X锁被释放。快照数据是以前版本的数据,这是通过回滚段来实现。但是在不同的事务隔离级别,阅读不同的是,并不是每个事务隔离级别读一致性。
例如:
对于读提交的事务隔离级别,他总是读取行的最新版本,如果行被锁定,则读取行的版本的最新快照。
对于可重复读(对InnoDB存储引擎的默认隔离级别),总是读行数据在事务开始。
非读写机制极大地提高了数据读取的并发性。在InnoDB存储引擎的默认设置,这是阅读的默认方式,但在某些情况下,它可以读取锁,例如:
1,显式读取被锁定,例如使用选择更新,在共享模式中选择锁定。
2、钥匙插入和更新,因为在钥匙插入和更新,对数据记录的高隔离度要求,扫描在父表中存在,所以我们需要插入,插入外键删除,InnoDB会加锁的方式实现。
InnoDB锁定算法
1,记录锁:单行记录上的锁
2,间隙锁:一个锁定范围但不包含记录本身的间隙锁。
3、下一个键锁:间隙锁+记录锁,锁定一个范围,并锁定记录本身。
记录锁锁住索引记录,如果InnoDB存储引擎的表建立的时候没有设置任何索引,那么InnoDB存储引擎将使用隐式的重点锁定在可重复读隔离级别,next-key锁算法默认行锁定算法。
锁带来的问题
1。丢失更新
如何避免丢失更新:使事务成为串行操作而不是并发操作,也就是说,每个事务都要锁定读记录。
2。脏读
脏读是指一个事务可以读取另一个事务中未提交的数据,这违反了数据库的隔离。
脏读的条件是事务的隔离级别要求读为未提交。
三.不要一次又一次地读
不可重复读、脏读的区别是:脏读取未提交的数据读取和不重复,已提交的数据。
一般来说,不可重复阅读是可以接受的。在InnoDB存储引擎,下键锁算法是用来避免不可重复读的问题。
值得注意的是,默认InnoDB存储引擎不会回滚的超时引起的异常。
死锁的相关问题
1。死锁发生的条件
互斥条件:一个资源仅可每次过程;请求和保持条件:一个资源请求和阻塞的过程中,不断获得资源;不剥夺:一个过程是利用资源结束前获得的,不能强行剥夺;循环等待条件:端到端的循环等待资源形成多个过程之间的关系。
2。死锁检测(基于因特网上的经验)
InnoDB死锁检测是两种,一是满足循环等待,还有另一种策略:锁的结构比MySQL的配置设置或锁定深度遍历的最大数目超过设定的最大深度,InnoDB会判断死锁(这是为了提高性能,一度占据了太多的资源避免交易)。
由循环等待条件引起的死锁只能有四种形式:两个表、两行、互斥锁的交叉应用程序、同一表、主键索引锁冲突、主键索引锁和非聚集索引锁冲突,以及锁升级阻塞锁等待队列。
3,避免死锁(基于因特网上的经验)
1。如果插入用…SELECT语句备份,数据量大,工作在一个单一的时间点,避免了竞争与其他SQL语句的使用资源,或选择到输出文件加LOAD DATA INFILE插入的选择,它不仅速度快,而且不需要锁定
2。一个交易,锁定一个记录集,其运算结果设置应尽量短,以免占用太多的资源,在一次冲突被其他事务处理记录。
三.更新或删除表数据,SQL语句的条件是主键或索引,避免两个交叉并导致死锁。当WHERE子句更复杂时,它仅由SQL获得,然后用于UPDATE语句中。
4的嵌套表。SQL语句不是太多,它可以拆分和拆分,同时避免资源和资源的等待,从而导致与其他事务的冲突。
5、定点运行脚本,避免在同一时间点在同一个表上读写多个脚本,特别注意大锁和大量数据的语句。
6。应用程序增加了死锁的判断,如果事务结束,则重新运行事务以减少对函数的影响。
4、死锁解决方案
1)先执行SHOW PROCESSLIST找到死锁的线程数。然后杀了PID
2)SHOW INNODB STATUS检查发动机的状态,你可以看到哪些语句产生死锁
3)看innodb_locks,innodb_trx,innodb_lock_waits,和information_schema架构下的其他表
ps:MySQL死锁
既然陷入僵局,这是一个特殊的问题。
什么是僵局
死锁是资源分配和使用不当造成的,是一个资源相互竞争、相互等待的过程,具体而言,死锁的发生有四个必要条件。
(1)互斥条件:每个资源只能由一个进程使用
(2)请求和保持条件:当进程被请求资源阻塞时,已获得的资源被保留起来。
(3)非剥夺条件:使用过程中获得的资源在使用结束前不得以武力剥夺。
(4)循环等待条件:若干进程形成头部和尾部之间的循环等待资源关系。
显然,两个或两个以上的过程是一个僵局,换句话说,死锁发生在并发程序。在Mysql,我们只是由于目前交易引擎(InnoDB支持锁),有优秀的男男恋情InnoDB和死锁。
死锁检测
1、利用SHOW INNODB STATUS检查发动机的状态,你可以看到哪些语句产生死锁
2,MySQL提供了一个information_schema检测死锁的innodb_locks,表innodb_trx,和innodb_lock_waits。
由循环等待条件引起的死锁只能有四种形式:两个表、两行、互斥锁的交叉应用程序、同一表、主键索引锁冲突、主键索引锁和非聚集索引锁冲突,以及锁升级阻塞锁等待队列。
死锁避免
1。如果插入用…SELECT语句备份,数据量大,工作在一个单一的时间点,避免了竞争与其他SQL语句的使用资源,或选择到输出文件加LOAD DATA INFILE插入的选择,它不仅速度快,而且不需要锁定
2。一个交易,锁定一个记录集,其运算结果设置应尽量短,以免占用太多的资源,在一次冲突被其他事务处理记录。
三.更新或删除表数据,SQL语句的条件是主键或索引,避免两个交叉并导致死锁。当WHERE子句更复杂时,它仅由SQL获得,然后用于UPDATE语句中。
4的嵌套表。SQL语句不是太多,它可以拆分和拆分,同时避免资源和资源的等待,从而导致与其他事务的冲突。
5、定点运行脚本,避免在同一时间点在同一个表上读写多个脚本,特别注意大锁和大量数据的语句。
6。应用程序增加了死锁的判断,如果事务结束,则重新运行事务以减少对函数的影响。