MySQL InnoDB锁介绍及不同SQL语句分别加什么样的锁
对付主键或独一索引,当有一再键错误(duplicate-key error)时,会在 一再的索引记录上 配置 shared next-key lock或shared index record lock。这也许会导致死锁。 上图演示了:T1在主键1上配置exclusive index record lock。T2和T3插入时,会发生一再键错误,于是T2和T3都在主键1上配置了shared next-key lock。如上图所示 假云云时,T1 rollback开释掉其所持有的index record lock,则T2和T3守候获取的shared next-key lock都乐成了,然后,T2和T3争夺主键1上的index record lock,于是T2和T3就死锁了,由于它俩都持有shard next-key lock,两边谁都不会放弃已经获得的shared next-key lock,于是,谁都无法获得主键1的index record lock。 必要明晰的是死锁的也许性并不受断绝级此外影响,由于断绝级别改变的是读操纵的举动,而死锁是因为写操纵发生的。死锁并不行怕,MySQL会选择一个捐躯者,然后,在体系变量innodb_lock_wait_timeout指定的秒数到达后,自动回滚捐躯者事宜;从MySQL5.7开始,新插手了体系变量innodb_deadlock_detect(默认ON),假如开启此变量,则MySQL不会再守候,一旦探测到死锁,就当即回滚捐躯者事宜。 上图演示了:在上图的状态下,当T1 commit时,T1开释了主键1上的index record lock,于是T2和T3守候获取的shared next-key lock都乐成了,然后,T2和T3争夺主键1上的index record lock,于是T2和T3死锁了,由于它俩都持有shard next-key lock,两边谁都不会放弃已经获得的shared next-key lock,于是,谁都无法获得主键1的index record lock。 五、performance_schema.data_locks中能看到所有的锁吗? 显而易见,performance_schema.data_locks并未表现所有的锁,那么,它表现了哪些锁呢?很不幸,我并未找到文档嗣魅这事,尽量文档(https://dev.mysql.com/doc/refman/8.0/en/innodb-information-schema-transactions.html)说:“事宜持有的每一个锁 以及 事宜被阻塞的每一个锁哀求,都在该表中占有一行”,但,我们许多例子都表白,它并未表现所有的锁。按照我的试验,我揣摩performance_schema.data_locks表现的是WHERE前提所触遇到的索引上的锁,“WHERE前提所触遇到的索引”是指SQL现实执行时所行使的索引,也就是SQL执行打算的key列所表现的索引,正由于此,INSERT时看不到任何锁,update g set a=a+1 where b=22时只看到idx_b上的锁。必要夸大的是,这是我本身试验并揣摩的,我并未在文档中看到这种说法。 假设T1和T2两个事宜操纵统一个表,先执行T1,此时尽量performance_schema.data_locks中只表现T1的WHERE前提所触遇到的索引上的锁,可是,究竟上在T1的WHERE前提触碰不到的索引上,也是会配置锁的。尽量表的索引idx并未被T1所触遇到,即performance_schema.data_locks表现T1在索引idx并没有配置任何锁,但,当T2执行 锁定读/插入/更新/删除 时触遇到了索引idx,T2才恍然发明,原本T1已经在索引idx上加锁了。 我们来看下面的三个例子 “performance_schema.data_locks无法看到所有锁”示例一 上图演示了:T1执行时,只触遇到了索引idx_b,T1执行完后,在performance_schema.data_locks中只能看到idx_b上的锁,看起来T1并未在idx_a上配置任何锁;但,当T2执行触遇到了索引idx_a时,T2才恍然发明,原本T1已经在idx_a上配置了index record lock啦。 “performance_schema.data_locks无法看到所有锁”示例二 插入新行时,会先配置insert intention lock,插入乐成后再在插入完成的行上配置index record lock。 (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |