MySQL 数据库锁理论(六)

MYSQL-创建数据库 CREATE DATABASE (十一) MYSQL创建数据库语法 CREATE DATABASE 阅读详情

9. 数据库锁理论

  • 根据操作类型,锁可分为

    • 读锁(共享锁): 针对同一份数据,多个读操作可以同时进行而并不相互影响。
    • 写锁(互斥锁): 当前写操作在没有完成之前,它会阻断其他写锁和读锁。
  • 根据数据操作的粒度划分,锁可分为

    • 表锁(偏读):
    • 行锁(偏写):
    • 页锁:

1. 创建表锁演示实例

  1. 建表 SQL:引擎选择 myisam

    create table mylock (
        id int not null primary key auto_increment,
        name varchar(20) default ''
    ) engine myisam;
    
    insert into mylock(name) values('a');
    insert into mylock(name) values('b');
    insert into mylock(name) values('c');
    insert into mylock(name) values('d');
    insert into mylock(name) values('e');
    
    select * from mylock;
    
  2. mylock 表中的测试数据

    mysql> select * from mylock;
    

    image-20201121144358253

  3. 查看当前数据库中表的上锁情况:show open tables;,In_user 的值0 表示未上锁。

    image-20201121144522832

  4. 添加读/写锁

使用命令:lock table 表名1 read(write) [,表名2 read(write)]

为mylock表添加读锁,即lock table mylock read;

添加之后,我们发现,依然可以读取mylock的数据。

image-20201121145337170

虽然可以读取数据,但是修改数据是不允许的。修改数据时,光标不断的在闪烁。

image-20201121150337831

接着,我们将读锁改为写锁,即 lock table mylock write;

添加之后,我们发现,读取数据时会被阻塞,光标不断在闪烁。

image-20201121145455476

最后,解锁,我们可以使用命令: unlock tables;

2. 表锁案例总结1:

MySQL的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)

  1. 对MyISAM表的读操作(加读锁),不会阻塞其他进程对同一表的读请求,但会阻塞对用一表的写请求,当前进程写操作时会报错。只有当读锁释放后,才会执行其他进程的写操作。
  2. 对MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其他进程的读写操作。

简而言之,就是读写锁会阻塞写,但是不会阻塞读。而写锁则会把读和写都阻塞。

=

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6VMkQOnR-1606020997384)(…/…/AppData/Roaming/Typora/typora-user-images/image-20201121153502148.png)]

3. 如何分析表锁?

分析表锁,我们可以通过检查 table_locks_waited 和 table_locks_immediate 状态变量来分析系统上的表锁定:

我们可以通过命令: show status like ‘table_lock%’; 查看状态变量。

image-20201121153839661

上图中的两个状态变量记录MySQL内部表级锁定的情况,两个变量说明如下:

  • Table_locks_immediate:产生表级锁定的次数,标识可以立即获取锁的查询次数,每立即获取锁值加1;

  • Table_locks_waited:出现表级锁定争用而发生等待的次数(不能立即获取锁的次数,每等待一次,锁值加1),此值高则说明存在着较严重的表级锁争用情况。

此外,MyISAM的读写锁调度是写优先,这也就是 MyISAM 不适合做写为主表的引擎。因为写锁后,其他线程不能做任何操作,大量更新会使查询很难得到锁,从而造成永远阻塞。

4. 创建行锁演示实例

  1. 建表 SQL:**引擎选择 InnoDB **

    CREATE TABLE test_innodb_lock (a INT(11),b VARCHAR(16))ENGINE=INNODB;
    
    INSERT INTO test_innodb_lock VALUES(1,'b2');
    INSERT INTO test_innodb_lock VALUES(3,'3');
    INSERT INTO test_innodb_lock VALUES(4, '4000');
    INSERT INTO test_innodb_lock VALUES(5,'5000');
    INSERT INTO test_innodb_lock VALUES(6, '6000');
    INSERT INTO test_innodb_lock VALUES(7,'7000');
    INSERT INTO test_innodb_lock VALUES(8, '8000');
    INSERT INTO test_innodb_lock VALUES(9,'9000');
    INSERT INTO test_innodb_lock VALUES(1,'b1');
    
    CREATE INDEX test_innodb_a_ind ON test_innodb_lock(a);
    CREATE INDEX test_innodb_lock_b_ind ON test_innodb_lock(b);
    
  2. 查询 test_innodb_lock 表中的测试数据

    image-20201121161155916

  3. 因为我们的数据库使用的是版本 Server version: 8.0.18 MySQL Community Server - GPL。 MySQL版本在5以上默认使用的是innodb引擎,该引擎是支持事务的,每一个分号的输入即自动提交事务。因此我们要关闭自动提交,自己手动提交数据,即输入命令:

    set autocommit=0; 。

  4. 会话1 进行修改数据,并暂时不提交事务。update test_innodb_lock set b='40001' where a=4;

  5. 会话1 查询数据,发现数据库数据发生了变化, a=4的值为4001

    image-20201121162311899

  6. 会话2 查询数据,发现数据并没有修改。

    image-20201121162421514

  7. 此时会话1还未提交,会话2想要修改a=4,即第4行数据,希望修改为4002 update test_innodb_lock set b='4002' where a=4; 。

    image-20201121163717037

    光标在闪烁,说明该修改命令被阻塞了,会话2无法修改。

  8. 此时会话1 进行 commit,提交数据,并查询结果。

    会话1的第4行的b已经修改为40001,会话2的修改语句执行完成。但会话2查询到的结果为会话2修改的值4002.

  9. 会话2也继续进行提交数据。

  10. 会话1为再次提交数据,读取到的仍然为旧的值。因为MySQL数据库的默认隔离级别为可重复读。

  11. 会话1提交数据,即可读到最新的数据了。

  12. 会话1修改第4行的数据,修改为4001;会话2修改第5行的数据,修改为5001;

    image-20201121165254033

  13. 我们可以发现,两个会话是可以同时提交成功的,说明会话1修改的行对会话2修改是没有影响的。这就是行锁的效率体现。

5. 无索引行锁升级为表锁

这个问题发生往往都很隐蔽,难以发现该错误的发生:

  1. 首先,我们查看我们的表的字段类型

    image-20201121175843463

  2. 在学索引的时候,我们都字段自动类型转换会导致索引失效。除次之外,还会导致行锁变为表锁。

  3. 举个栗子,我们在会话1中b的值为4001的记录修改a字段为401,

    即 update test_innodb_lock set a=401 where b=‘4001’;

    对于varchar类型的数据,我们必须加上引号,否则会产生神秘的问题。

  4. 如果有引号时,结果是很正常的

    image-20201121180303940

    image-20201121180408096

  5. 当我们把引号去掉时,再看看结果如何吧!!!

    image-20201121180509371

    我们可以发现,会话1秒出结果,但是会话2的光标不断的在闪烁。。。。说明行锁已经升级为表锁了。

  6. 当会话1提交时,会话2将不再阻塞。

    image-20201121180640615

6. 间隙锁

MySQL InnoDB支持三种行锁定方式:

  • ​ 行锁(Record Lock):锁直接加在索引记录上面。
  • ​ 间隙锁(Gap Lock):当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁。
  • ​ Next-Key Lock:行锁与间隙锁组合起来用就叫做Next-Key Lock。
  1. 查询 test_innodb_lock 的数据,查看存在哪些记录

    image-20201121182809736

  2. 我们很容易可以发现,缺少a为2的记录项。当我们的会话1需要修改 1<a<5的记录,b值修改为fafu时。会话2插入1条a=2,b=’2b’;

    # 会话1
    update test_innodb_lock set b='fafu' where a<5 and a>1;
    
    # 会话2
    insert into test_innodb_lock values(2,'2b');
    

    image-20201121183421612

    通过图,我们很容易看出问题了。 a=2的记录项原本就不能存在,但最终还是被锁住了,而如果插入的数据项a 的范围不在1~5之间的话,此时就不会被锁住。

  3. 所以 这 重分的说明了,如果是范围查询,会存在间隙锁。

  4. InnoDB使用间隙锁的目的,一方面是为了防止幻读,以满足相关隔离级别的要求,对于上面的例子,要是不使用间隙锁,如果其他事务插入了user_id大于100的任何记录,那么本事务如果再次执行上述语句,就会发生幻读;另外一方面,是为了满足其恢复和复制的需要

小结:

很显然,在使用范围条件检索并锁定记录时,InnoDB这种加锁机制会阻塞符合条件范围内键值的并发插入,这往往会造成严重的锁等待。因此,在实际应用开发中,尤其是并发插入比较多的应用,我们要尽量优化业务逻辑,尽量使用相等条件来访问更新数据,避免使用范围条件;当然,对一条不存在的记录加锁,也会有间隙锁的问题。

间隙锁在InnoDB的唯一作用就是防止其它事务的插入操作,以此来达到防止幻读的发生,所以间隙锁不分什么共享锁与排它锁。如果InnoDB扫描的是一个主键、或是一个唯一索引的话,那InnoDB只会采用行锁方式来加锁,而不会使用Next-Key Lock的方式,也就是说不会对索引之间的间隙加锁,仔细想想的话,这个并不难理解,大家也可以自己测试一下。

要禁止间隙锁的话,可以把隔离级别降为***读已提交***,或者开启参数***innodb_locks_unsafe_for_binlog***。

7. 如何锁定具体的某一行数据

大致可分为下面4个步骤

# 步骤1,开启
begin;
# 步骤2,锁定行
select * from test_innodb_lock where a=8 for update;
# 步骤3,进行数据修改
update ......
# 步骤4,提交
commit;

在会话1中锁定一行数据时,其他会话无法对该行记录继续修改操作。如果修改其他记录,则不会被阻塞

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uk9QH7Y7-1606020997403)(…/…/AppData/Roaming/Typora/typora-user-images/image-20201121185401229.png)]

8. 如何分析行锁?

通过检查 innoDB_row_lock 状态变量来分析系统上的行锁的争夺情况:

使用命令: show status like 'innodb_row_lock%';

image-20201121190825195

对各个状态量的说明如下:

状态描述
Innodb_row_lock_current_waits当前正在等待锁定的数量
Innodb_row_lock_time从系统启动到现在锁定总时间长度
Innodb_row_lock_time_avg每次等待所花的平均时间
Innodb_row_lock_time_max从系统启动到现在等待最长的一次所花的时间
Innodb_row_lock_waits系统启动后到现在总共等待的次数

在这5个状态量中,我们最主要关注 Innodb_row_lock_time_avg(平均时间),Innodb_row_lock_waits(等待总次数),Innodb_row_lock_time(等待总时间) 三个状态即可

MyEclipse DB Browser连接MySQL配置 MyEclipse DB Browser连接MySQL配置   1、打开MyEclipse   2、选择菜单:Window/Open Perspective/MyEclipse Database Explorer,点这儿OK,在左边打开DB Brower窗口。   3、在DB Brower窗口内任意空白处击右键,选择New命令,弹出Database Driver窗口   4、本 阅读详情

相关推荐

MYSQL常用命令

MYSQL常用命令MYSQL常用命令MYSQL常用命令

数仓开发之DIM层

(1)定义类。

JiaXingNashishua的博客 5537

易智联LM401模块学习(一)——初识Lora

Lora

weixin_46046597的博客 1054

Mysql 快速生成日期时间维度表

Mysql 快速生成日期时间维度表 创建表结构 CREATE TABLE `dim_date` ( `id` int(11) NOT NULL COMMENT '日期键 20000101', `date` date DEFAULT NULL COMMENT '日期 2000-01-01', `year` smallint(6) DEFAULT NULL COMMENT '年 2000', `month` smallint(6) DEFAULT NULL COMMENT '月 01', `

努力推石头的西西弗斯 2689

具身智能端到端大模型VLA (Vision Language Action)

在语言为条件的机器人任务中,策略必须具备理解语言指令、视觉感知环境并生成适当动作的能力,这就需要VLA的。例如,在自动驾驶领域,传统的做法是将感知、预测、规划等步骤分开处理,而VLA则试图用一个统一的框架来替代这种分立的方法。另外,VLA的模型对于算力的需求很大,单片AI算力1000Tops的Thor大概率会延期发布,加上英伟达芯片的量产时间与成本挑战,以及在国内的应用情况,对车企而言是个大问题。以谷歌DeepMind推出的RT-2为例,该模型可以在新的物体、背景和环境中表现出显著改善的性能。

具身智能机器人 1万+

桁架 拓扑优化 matlab程序_拓扑优化在结构轻量化及板壳加筋肋最优布置的应用...

1 拓扑优化简介材料的有效利用一直都是人类追求的目标,也是许多研究领域不变的话题,并伴随着结构优化理论和方法的产生而发展。结构优化设计通常分为三个层次:(1)拓扑优化:在一个确定的连续区域内寻求结构内部非实体区域位置和数量的最佳配置,寻求结构中的构件布局及节点联结方式最优化,使结构能在满足应力、位移等约束条件下,将外载荷传递到结构支撑位置,同时使结构的某种性态指标达到最优;(2)形状优化:指在保持...

weixin_39525355的博客 1877

MySQL 常踩的坑

MySQL的坑 08.删除 pit_device_shop 的重复数据 drop table if exists pit_device_shop_20181204; create table pit_device_shop_20181204 as select max(pit_key) ,pds.device_id ,pds.shop_id from pit_d...

说文科技,做有态度的研究。 1330

步进电机梯形加减速算法的实现

步进电机梯形加减速算法的实现

m0_69251699的博客 1318

Mysql数据库中的各种锁

在介绍InnoDB与MyIsam的区别时,提到了:InnoDB支持表、行(默认)级锁,而MyISAM支持表级锁 本文便着重对Mysql数据库中的锁进行介绍 概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。 MySQL大致可归纳为以下3种锁: 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最...

张花生的博客 6万+

项目经理必看:如何建立高效的相关方沟通机制?

你是否遇到过这样的场景?客户突然说“这不是我要的”,开发团队抱怨“需求总变”,高层追问“进度滞后为什么不早说”?这些问题的根源往往是——相关方沟通机制失效。本文聚焦“如何建立高效沟通机制”,覆盖从识别相关方到持续优化的全流程,适用于IT、产品、工程等各类项目。本文将按“理解问题→拆解核心概念→掌握工具方法→实战落地→未来趋势”的逻辑展开,重点讲解“相关方分析矩阵”“沟通计划表”等实用工具,并用“组织生日派对”的案例贯穿全文,让抽象概念变得可感知。相关方识别:用“权力/利益矩阵”找对人(像派对邀请关键客人)

项目管理的博客 1295

Cadence PCB 仿真宝典【目录】

欢迎大家来到《Cadence PCB 仿真宝典》该专栏包括【入门篇】【提升篇】【技巧篇】【疑难篇】四个部分,以供大家参考。大家直接点击大纲中的蓝色标题即可轻松传送。

fydar的博客 3269

MySQL锁机制详解-表锁与行锁

锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算机资源,如CPU、RAM、I/O等的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题。此外,锁冲突也是影响数据库并发访问性能的一个重要因素。

huangjhai的博客 1万+

几种负载均衡策略(DNS、NAT、重定向、反向代理)

摘要:本文对比了四种负载均衡技术:DNS负载均衡通过域名解析分发IP,用户直连服务器;NAT负载均衡通过VIP转发流量,所有流量经过负载均衡器;HTTP重定向通过302跳转实现分流;反向代理则隐藏后端服务器,统一转发请求。DNS简单但调度不精准,NAT精准但有带宽瓶颈,HTTP重定向延迟高,反向代理性能好但需专用设备。适用场景各异,DNS适合异地分流,NAT适合内网集群,HTTP重定向适合简单分流,反向代理适合高并发场景。核心区别在于层级(3层/7层)和流量走向(直连/中转)。

echo的博客 72

5、MySQL修改数据库:ALTER DATABASE用法简介

在 MySQL 数据库中只能对数据库使用的字符集和校对规则进行修改,数据库的这些特性都储存在 db.opt 文件中。下面我们来介绍一下修改数据库的基本操作。 在 MySQL 中,可以使用 ALTER DATABASE 来修改已经被创建或者存在的数据库的相关参数。修改数据库的语法格式为: ALTER DATABASE [数据库名] { [ DEFAULT ] CHARACTER SET <字符集名> | [ DEFAULT ] COLLATE <校对规则名>} 语法说明如下: A

you can you up up up的博客 2711

车载网络测试实操源码_使用CAPL解析VBF文件

VBF(Versatile Binary Format)文件是一种二进制文件格式,被沃尔沃、福特、马自达、吉利等汽车制造商广泛采用。这种格式无法使用我们常规的烧录器进行刷写,通常需要进行解析转化。如果各位需要自己编写软件或脚本来刷写VBF文件,或者需要对刷写功能进行测试时,那么本篇文章就会对你非常有用。今天我们就来讲一下如何使用CAPL脚本对VBF文件进行数据解析。VBF文件包含三部分:VBF版本段、文件头段、数据段。前面的版本段和文件头段是ASCII码,包含版本、地址、校验码等信息

文章主要涉及嵌入式软件开发、测试、项目管理等,欢迎交流,共同进步。 2997

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

MySQL 中的数据库锁和表锁

MySQL 中的数据库锁和表锁是保证数据一致性和完整性的重要手段。在实际应用中,需要根据具体的业务需求和场景选择合适的锁类型,并采取相应的措施来优化锁的性能,避免锁带来的问题,提高数据库的并发性能。文章(专栏)将持续更新,欢迎关注公众号:服务端技术精选。。个人小工具程序上线啦,通过公众号(服务端技术精选)菜单【个人工具】即可体验,欢迎大家体验后提出优化意见!500 个访问欢迎大家踊跃体验哦~

我爱娃哈哈的专栏 1619

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

MySQL数据库的锁

数据库锁是数据库管理系统中用来管理对数据库对象(如行、页或表)的并发访问的机制。其主要目的是确保数据的完整性和一致性,同时允许合理的并发操作。

锟斤拷 1011

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

mysql 新建database_MySQL创建数据库(CREATE DATABASE语句)

在MySQL 中,可以使用CREATE DATABASE 语句创建数据库,语法格式如下:CREATE DATABASE [IF NOT EXISTS] [[DEFAULT] CHARACTER SET ][[DEFAULT] COLLATE ];[ ]中的内容是可选的。语法说明如下::创建数据库的名称。MySQL 的数据存储区将以目录方式表示 MySQL 数据库,因此数据库名称必须符合操作系统的文...

weixin_30441727的博客 7050

MySQL修改数据库:ALTER DATABASE用法简介

数据库创建好后也是可以修改的,下面我们来介绍一下修改数据库的基本操作 基本语法 在 MySQL 中,可以使用 ALTER DATABASE 或 ALTER SCHEMA 语句来修改已经被创建或者存在的数据库的相关参数。修改数据库的语法格式为: ALTER DATABASE [数据库名] { [ DEFAULT ] CHARACTER SET <字符集名> | [ D...

MYSQL安装教程 2077

mysql alter database_MySQL修改数据库:ALTER DATABASE用法简介

在MySQL数据库中只能对数据库使用的字符集和校对规则进行修改,数据库的这些特性都储存在 db.opt 文件中。下面我们来介绍一下修改数据库的基本操作。在 MySQL 中,可以使用ALTER DATABASE来修改已经被创建或者存在的数据库的相关参数。修改数据库的语法格式为:ALTER DATABASE [数据库名] {[ DEFAULT ] CHARACTER SET |[ DEFAULT ]...

weixin_35084134的博客 2394

MYSQL 六、mysql锁 1

在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的 资源。为保证数据的一致性,需要对并发操作进行控制,因此产生了锁。同时锁机制也为实现MySQL 的各个隔离级别提供了保证。锁冲突也是影响数据库并发访问性能的一个重要因素。所以锁对数据库而言显得尤其重要,也更加复杂。

kkkkatoq的博客 1206

MySQL数据库 - 锁

本文介绍了MySQL数据库之锁,包括全局锁、表级锁、行级锁。锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂

xian_x_的博客 1481

db文件怎么修改_详解MySQL数据库的db.opt文件含义及作用

概述MySQL数据库存放数据目录里的db.opt文件是MySQL建库过程中自动生成的。细心的朋友可能会发现有时候在MySQL数据库的某些库目录下有个db.opt文件,那这个文件是干什么用的呢?如果你用记事本等编辑器打开看的话,内容很简单,是用来记录该库的默认字符集编码和字符集排序规则用的。db.optMySQL的每个数据库目录中有一个文件db.opt,该文件主要 用来存储当前数据库的默认字符集和字...

weixin_39856607的博客 2467

MySQL之修改数据库(ALTER DATABASE用法简介)

语法 数据库建立以后我们也是可以进行修改的,我们可以使用ALTER DATABASE或 ALTER SCHEMA 语句来修改已经被创建或者存在的数据库的相关参数。修改数据库的语法格式为: ALTER DATABASE [数据库名] { [ DEFAULT ] CHARACTER SET <字符集名> | [ DEFAULT ] COLLATE <校对规则名>} ALTE...

qq_38523616的博客 3226
上一篇: MySQL(五) 索引失效
下一篇: MySQL(七)存储过程
Dim_Jerry
博客等级 码龄8年 14粉丝 50原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值