广告位联系
返回顶部
分享到

mysql中Innodb行锁实现原理介绍

Mysql 来源:互联网 作者:佚名 发布时间:2024-10-21 22:08:09 人浏览
摘要

一、Innodb行锁的实现 【1】Innodb的行锁是通过给索引的索引项加锁来实现的 【2】Innodb按照辅助索引进行数据操作时,辅助索引和主键索引都将锁定指定的索引项 【3】通过索引进行数据检索时

一、Innodb行锁的实现

【1】Innodb的行锁是通过给索引的索引项加锁来实现的

【2】Innodb按照辅助索引进行数据操作时,辅助索引和主键索引都将锁定指定的索引项

【3】通过索引进行数据检索时,Innodb才使用行级锁,否则Innodb将使用表锁

二、场景分析

环境: 创建一张表,ID为主键,Name为普通字段。下面通过实际场景进行说明。

【1】使用主键ID来进行数据检索时,其余行仍然可以操作。

session1 session2
mysql>set autocommit=0;
Query OK,0 rows affected(0.00sec)
mysql>set autocommit=0;
Query OK,0 rows affected(0.00sec)
mysql> select * from test_lock wehre id = 1 for update;
±-----±-----+
| id | name  |
| 1  | hua zi |
1 row in set(0.00sec)
 
  mysql> select * from test_lock wehre id = 2 for update;
±-----±-----+
| id | name  |
| 2  | guo zi |
1 row in set(0.00sec)
【2】用非索引的字段来进行数据检索时,此时会升级为表锁,其余列就不能操作。  
session1 session2
---- ----
mysql>set autocommit=0;
Query OK,0 rows affected(0.00sec)
mysql>set autocommit=0;
Query OK,0 rows affected(0.00sec)
mysql> select * from test_lock wehre name = ‘hua zi’ for update;
±-----±-----+
| id | name  |
| 1  | hua zi |
1 row in set(0.00sec)
 
  mysql> select * from test_lock wehre name = ‘guo zi’ for update;
等待
【3】由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。应用设计的时候要注意这一点。虽然 session_2和session_1访问的是不同的记录,但因为使用了相同的索引,所以需要等待锁。  
session1 session2
---- ----
mysql>set autocommit=0;
Query OK,0 rows affected(0.00sec)
mysql>set autocommit=0;
Query OK,0 rows affected(0.00sec)
mysql> select * from test_lock wehre id = 1 and name = ‘hua zi’ for update;
±-----±-----+
|  id | name  |
|  1  | hua zi |
1 row in set(0.00sec)
 
  mysql> select * from test_lock wehre id = 1 and name = ‘guo zi’ for update;
等待
【4】当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁。  
session1 session2
---- ----
mysql>set autocommit=0;
Query OK,0 rows affected(0.00sec)
mysql>set autocommit=0;
Query OK,0 rows affected(0.00sec)
mysql> select * from test_lock wehre id = 1 for update;
±-----±-----+
| id | name  |
| 1  | hua zi |
1 row in set(0.00sec)
 
  mysql> select * from test_lock wehre name = ‘guo zi’ for update;
±-----±-----+
| id | name  |
| 2  | guo zi |
1 row in set(0.00sec)
  mysql> select * from test_lock wehre name = ‘hua zi’ for update;
等待

三、特殊场景

即便在条件中使用了索引字段,但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的,如果MySQL认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁,而不是行锁。因此,在分析锁冲突时,别忘了检查SQL的执行计划,以确认是否真正使用了索引。

在下面的例子中,检索值的数据类型与索引字段不同,虽然MySQL能够进行数据类型转换,但却不会使用索引,从而导致InnoDB使用表锁。通过用explain检查两条SQL的执行计划,我们可以清楚地看到了这一点。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

mysql> alter table test_lock add index name(name);

Query OK, 4 rows affected (8.06 sec)

Records: 4  Duplicates: 0  Warnings: 0

mysql> explain select * from test_lock where name = 1 \G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: test_lock

type: ALL

possible_keys: name

key: NULL

key_len: NULL

ref: NULL

rows: 4

Extra: Using where

1 row in set (0.00 sec)

mysql> explain select * from test_lock where name = '1' \G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: test_lock

type: ref

possible_keys: name

key: name

key_len: 23

ref: const

rows: 1

Extra: Using where

1 row in set (0.00 sec)


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • Navicat连接MySQL出现2059错误的解决方案介绍
    Navicat连接MySQL出现2059错误 在Navicat中连接MySQL时遇到错误代码2059,这表示MySQL服务器不接受Navicat客户端提供的加密插件。 MySQL 8.0 及以上版本
  • mysql时间戳格式化yyyy-mm-dd的使用介绍

    mysql时间戳格式化yyyy-mm-dd的使用介绍
    格式化到 年月日 1 2 3 4 # 将时间换成列名就行;当前是秒级时间戳,如果是毫秒的 / 1000即可 # SELECT FROM_UNIXTIME(1602668106666.777888999 / 1000,%Y-%m
  • mysql-8.0.15-winx64安装与修改密码方式介绍

    mysql-8.0.15-winx64安装与修改密码方式介绍
    第一步:下载 移步官网:https://www.mysql.com/downloads/下载一个压缩包(个人版) 第二步:安装 解压安装包,根据自己的喜好选择路径 将安装
  • mysql中Innodb行锁实现原理介绍
    一、Innodb行锁的实现 【1】Innodb的行锁是通过给索引的索引项加锁来实现的 【2】Innodb按照辅助索引进行数据操作时,辅助索引和主键索引都将
  • windows-mysql8.0.15如何修改密码、重置密码

    windows-mysql8.0.15如何修改密码、重置密码
    windows-mysql8.0.15 修改密码、重置密码 打开命令窗口cmd 输入命令:net stop mysql,停止MySQL服务。 1 net stop mysql 如果出现下图提示,就则需要用管
  • Mysql主从同步怎么重置

    Mysql主从同步怎么重置
    服务器强制重启,导致MySQL主从数据库出现数据不一致问题,主从数据库数据相差较大,无法完成数据同步,出现报错。 因此,需要进行主
  • MySQL中关于表的约束介绍

    MySQL中关于表的约束介绍
    一、空属性 在MySQL中,空属性约束指定了某一列是否可以包含NULL值。 它们用于各种目的,例如数据验证和限制数据的输入格式。 NOT NULL:当
  • MySQL按时间进行表分区的方法
    创建按月份分区的表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 create table if not exists table_name ( id bigint auto_increment comment 主键id, create_by varchar(64) not null
  • mysql数据库提权的三种方法

    mysql数据库提权的三种方法
    MySql提权的三种方式: udf提权 mof提权 启动项提权 以下是一些常见的数据库及其默认端口: 1. MySQL: 默认端口为 3306 2. PostgreSQL: 默认端口为
  • 解决ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘

    解决ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘
    最近在学习Django框架,于是在windows系统上搭建了Django环境,并使用虚拟机ubuntu系统上安装的mysql作为项目的远程数据库,前几天一直用得好
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计