Mysql中键锁的使用方法

  

本文以为例,为大家分析Mysql中键锁的使用方法,阅读完整文相信大家对有了一定的认识。

连接与线程

查看连接信息<代码>显示processlist

 <代码> +——+ + - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
  | | |用户Id主机,,,,,,| db,| | |命令时间状态,|信息大敌;,,,,,|
  + - - - + - - - + - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
  3,| | |根172.17.0.1:60542 | |查询测试,| 0,开始,| |显示processlist |
  5,| | |根172.17.0.1:60546 | |测试睡眠,| 4168 |,,,,,| & lt; null>,,,,,|
  8,| | |根172.17.0.1:60552 | |测试睡眠,| 4170 |,,,,,| & lt; null>,,,,,|
  + - - - + - - - + - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +  

mysql非企业版本只支持一个线程一个链接

查看线程模型<代码>显示变量如& # 39;thread_handling& # 39;

 <代码> + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
  | Variable_name,,,,,,,,,,,,,|值,,,,,,,,,,|
  + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
  | thread_handling,,,,,,,,,,,,|每个连接一个线程的|
  + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +  

【事务提交策略】
有两个隐藏事务提交时间点需要注意,第一个是<代码> autocommit=1 Mysql会话级别的自动提交变量,所有, ORM 框架中的事务提交控制都会受到这个字段影响,默认情况下当前语句会自动提交,但是如果是显示 开始事务开启事务需要自行手动提交。有些时候ORM框架会根据一些设置或者策略,将自动提交 设置为0。

第二个就是,DDL操作前都会隐式提交当前事务,有些脚本将DML和DDL混合在一起使用,这样会有一致性问题.DDL会自动提交当前事务。因为DDL在5.7之前都是不支持事务原则操作的。(Mysql8.0已经支持DDL事务性)

键锁排查

键锁只发生在 RR(可重复读)隔离级别下。

Mysql有很多类型对种锁,<代码>表锁,<代码>记录锁,<代码>差距锁,<代码>意向共享/排他锁,<代码>插入意向锁,<代码>元数据锁,<代码> Auto_Incr自增锁> 元数据锁, Auto_Incr自增锁之后,剩下的锁组合使用最多的就是在RR隔离级别下。

RR隔离级别是默认事务隔离级别,也是Mysql的强项之一,在RR隔离级别下事务有最大的吞吐量,而且不会出现幻读问题.Next-Key锁就是为了解决这个问题,简单讲记录锁锁 +差距就是 键锁。

_幻读_的根本问题就是出现在记录的边界值上,比如我们统计年龄大于30岁的人数:<代码> select count(1)人民age& gt; 这30个语句有可能每次查询得到的结果集都是不一样的,因为只要符合 age> 30 的记录进到我们的 人民表中就会被查询条件命中。

所以要想解决幻读不仅不允许记录的空隙被插入记录外,还要防止两遍记录被修改,因为如果前后两条记录被修改了那区间就会变大,就会有幻读出现。

我们看个例子。

 <代码>创建表的人的(
  ,“id”int(11)无符号不是零AUTO_INCREMENT,
  ,“年龄”int(11)默认为空,
  ,主键(“id”),
  ,关键“idx_peoples_age”(“年龄”)
  )引擎=InnoDB AUTO_INCREMENT=1的默认字符集=utf8mb4  
 <代码> +——+——+
  年龄| | | id
  + - - - + - - - +
  | 1,20 | |
  30 2,| | |
  35 3,| | |
  40 | 4,| |
  + - - - +——+  

为了方便调试,将innodb获取锁的超时时间调大点

 <代码>显示变量如& # 39;% innodb_lock_wait % & # 39;
  设置innodb_lock_wait_timeout=600  

开启两个会话。

 <代码>会话id=8:
  开始
  选择计数(1)从人民那里age> 30更新; 
 <代码> B会话id=5:
  开始
  插入人民(年龄)值(31) 

<代码>显示processlist 找到连接的id。

 <代码> * * * * * * * * * * * * * * * * * * * * * * * * * * * (1。行)* * * * * * * * * * * * * * * * * * * * * * * * * * *
  身份证,,3,|
  用户,,|根
  主机,,| 172.17.0.1:60542
  db,,,|测试
  命令|查询
  时间,,| 0
  状态,|开始
  信息,| processlist展示
  * * * * * * * * * * * * * * * * * * * * * * * * * * * (2。行)* * * * * * * * * * * * * * * * * * * * * * * * * * *
  身份证,,5,|
  用户,,|根
  主机,,| 172.17.0.1:60546
  db,,,|测试
  命令|查询
  时间,394年,|
  状态,|更新
  信息,,|插入人民(年龄)值(31)
  * * * * * * * * * * * * * * * * * * * * * * * * * * * (3。行)* * * * * * * * * * * * * * * * * * * * * * * * * * *
  身份证,,8,|
  用户,,|根
  主机,,| 172.17.0.1:60552
  db,,,|测试
  睡眠命令|
  时间,396年,|
  状态,|
  信息,代码,| & lt; null> 

Mysql中键锁的使用方法