mysql 锁详解

目录

前言

一、全局锁

二、表级锁

三、行锁


前言

为什么要设计锁,锁设计初衷是为了解决多线程下并发问题。出现并发的时候用锁进行数据同步,避免因并发造成了数据错误(数据覆盖)。可见锁的重要性,并不是所有的数据库都有锁。比如Redis,单个操作是原子性的,并且是单线程的,并发请求会在队列排列,请求是按顺序执行的,就不需要锁。Mysql 需要锁,mysql 是多线程的,并发操作要保证数据的一致性,需要通过锁进行数据同步。根据锁的范围来讲,mysql 的锁分为全局锁、表级锁和行锁

一、全局锁

全局锁就是对整个数据库实例加锁。Msql 提供的加全局锁的方法,命令是 Flush tables with read lock (FTWRL),以及set global readonly=true那么整库是只读状态,那么对数据库的DDL 以及 DML 将被阻塞,数据库将报下列错误。

全局锁主要是用在全库逻辑备份。这个命令产生以下风险:如果你在主库上备份,那么备份期间不能执行更新,如果在从库上备份,备份期间从库不能执行主库同步过来的binlog,会导致主从延迟。

我们在想想备份为什么要加锁,一定要加锁吗。答案是肯定的,必须的。加锁是为了保证数据的一致性以及业务的完整性。

我们现在有一个订单表,有一个余额表。有用户购买一个产品,业务逻辑是先扣除余额,然后往订单插一条数据。业务期间我们开始备份,在扣除余额前开始备份。恢复数据时候我们发现,用户的余额没有减少,但是用户多了一个订单。是不是不可以呀,所以备份前需要加锁的。加全局锁会影响业务,也是不可取的,有没有其他方法呢。

可以用官方自带的逻辑备份工具mysqldump,当在mysqldump使用参数–single-transaction 的时候,导数据前会启动一个事物,这个事物的隔离级别必须是RR,来确保拿到了一致性视图。由于MVCC 支持,数据库的DML 正常的处理。这种方法需要使用事务引擎的库,MyISAM就不可以。

MyISAM备份还是需要使用FTWRL的。有人说用set global readonly=true也可以让全库只读,可以不,当然也是可以的。他们之间有什么区别呢。一是,修改global变量的方式影响面非常大,readonly会被用来做其他逻辑,比如用来判断一个库是主库还是备库 二是,在异常处理机制的差异。如果客户端异常断开时使用FTWRL会自动释放全局锁,整个库可以正常更新。使用readonly整个库依旧处于只读状态,不能更新。

二、表级锁

在mysql 提供了两种表级别的锁:一种是表锁,二种是元数据锁(meta data lock,MDL)。表锁的语法是 lock tables … read/write,用这种方法的话可以用unlock 去释放锁,也可以客户端断开时自动释放。lock 的影响面很大不仅影响其他线程的write/read,write,本线程接下来的write/也会影响。这种方法毕竟对业务的影响很大,并不常用。

MDL锁,不需要用户显示使用,是mysql 内部的一种机制。当我们对数据表DML时,系统会自动加上MDL读锁,防止用户DDL操作,产生不一致性。当我们对数据表DDL时,系统会自动加上MDL写锁,防止用户DML操作以及其他线程的MDL操作避免数据不一致。

多说一句MDL是一个两阶段锁,在事务开始时加锁,事物结束时释放锁。在这个地方可以给大家解释下,session A , session B , session C, session D 是几个客户端

Session A

此时表加了一个MDL 读锁,事务还没有结束一直保留着MDL 读锁,直到commit 或者 rollback

Session B

此时表加了一个MDL 读锁,读锁之间可以共享

Session C

此时表加了一个MDL 写锁,读锁和写锁之间是互斥的所以阻塞

Session D

此时表加了一个MDL 读锁,由于Session C 被阻塞了所以 Session D也不阻塞了

由此我们可以确定MDL 锁的生命周期是从事务开始到事务提交。上面在解释一下Session D也是MDL读锁为啥也被阻塞了,Session C被阻塞后,后面客户端对表的MDL锁都会放到队列里,当事务提交后,依次从队列取出执行

如何安全的给表修改字段呢?

事务不提交,就会一直占着MDL锁。在 MySQL 的 information_schema 库的 innodb_trx 表中,你可以查到当前执行中的事务。如果你要做 DDL 变更的表刚好有长事务在执行,要考虑先暂停 DDL,或者 kill 掉这个长事务。

下面是如何kil 一个事物

一、在 information_schema 库的 innodb_trx 中找到一个事物id ,然后执行kill 就可以了

如果业务很重要或者表一直有数据更新,那么这种方法不可以了。需要用

ALTER TABLE tbl_name NOWAIT add column ...ALTER TABLE tbl_name WAIT N add column ...

这种方法,失败了重试,知道成功 。MariaDB 已经合并了 AliSQL 的这个功能,所以这两个开源分支目前都支持 DDL NOWAIT/WAIT n 这个语法。

有人问我mysql 5.6不是支持online ddl了吗?还会有阻塞吗,其实会的。online ddl 执行过程是这样的分为以下几步:

  1. 拿MDL写锁

  2. 降级成MDL读锁

  3. 真正做DDL

  4. 升级成MDL写锁

  5. 释放MDL锁

1、2、4、5如果没有锁冲突,执行时间非常短。第3步占用了DDL绝大部分时间,这期间这个表可以正常读写数据,是因此称为“online ”

我们的例子第一步就锁住了

三、行锁

行锁住要讨论的是innodb引擎下机制,myisam 不支持行锁,也就不支持并发,也就意味着myisam的更新是表级锁。

在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。

这个机制非常重要,为我们在业务设计中减少锁的冲突提供了理论的支持。那就是说如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。

既然是有锁,对于我们业务开发会不会造成死锁呢,答案是肯定的,什么事死锁呢?

当并发系统中不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,就会导致这几个线程都进入无限等待的状态,称为死锁。

当出现死锁后,有两种策略解决死锁:

  1. 一种策略是,直接进入等待,直到超时。这个超时时间可以通过参数 innodb_lock_wait_timeout 来设置。

  2. 另一种策略是,发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑。

在 InnoDB 中,innodb_lock_wait_timeout 的默认值是 50s,意味着如果采用第一个策略,当出现死锁以后,第一个被锁住的线程要过 50s 才会超时退出,然后其他线程才有可能继续执行。对于在线服务来说,这个等待时间往往是无法接受的。如果值设置的太小那么正常的逻辑也有可能受到影响。

innodb_deadlock_detect 这个是有负担的,试想100个线程更新一条记录,那么就有100*100 个量级死锁检测,表的行数越多,会消耗大量的cpu 资源。如果关掉呢,又会一直死锁,直到超时,会影响业务。

那么怎么解决这样的问题呢?

以上两种方案,减少innodb_lock_wait_timeout时间以及 innodb_deadlock_detect=off都是不可取的,那么我们通过减少连接线程去减少并发从而达到减少死锁,后来发现这种方案也是不可靠的,第一、客户端的数量没法控制 第二、减少线程意味着系统的性能得不到完全利用。也只能从业务上去考虑呢,根据不同业务,把更新一行放到多行上,锁的粒度变小了,死锁就减少了。通过这些我们总结一个结论,提高系统性能往往需要确定系统的瓶颈在哪,锁造成的瓶颈,可以考虑减少锁的粒度,比如用分片锁等等

重要:大家有没有想过行锁是加在哪呢,是在索引上,意味着我们在update 时候,wehere 没有设置索引,那么只要扫描的记录都会加上索引,事务提交的时候统一释放。所以update 更新语句一定要记住加上索引,由于update 是当前读的,没有加上索引一定是灾难性的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/261756.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

51单片机学习(3)-----独立按键控制LED的亮灭状态

前言:感谢您的关注哦,我会持续更新编程相关知识,愿您在这里有所收获。如果有任何问题,欢迎沟通交流!期待与您在学习编程的道路上共同进步了。 目录 一. 器件介绍及实验原理 1.独立按键 (1)独…

Vue图片浏览组件v-viewer,支持旋转、缩放、翻转等操作

Vue图片浏览组件v-viewer,支持旋转、缩放、翻转等操作 之前用过viewer.js,算是市场上用过最全面的图片预览。v-viewer,是基于viewer.js的一个图片浏览的Vue组件,支持旋转、缩放、翻转等操作。 基本使用 安装:npm安装…

【寸铁的刷题笔记】树、dfs、bfs、回溯、递归(一)

【寸铁的刷题笔记】树、dfs、bfs、回溯、递归(一) 大家好 我是寸铁👊 总结了一篇刷题关于树、dfs、bfs、回溯、递归的文章✨ 喜欢的小伙伴可以点点关注 💝 105. 从前序与中序遍历序列构造二叉树 模拟分析图 代码实现 /*** Definition for a binary tre…

说一下 JVM 运行时数据区 ?

目录 一、程序计数器(Program Counter Register) 二、Java 虚拟机栈(Java Virtual Machine Stacks) 三、本地方法栈(Native Method Stack) 四、Java 堆(Java Heap) 五、方法区&…

Imagewheel私人图床搭建结合内网穿透实现无公网IP远程访问教程

文章目录 1.前言2. Imagewheel网站搭建2.1. Imagewheel下载和安装2.2. Imagewheel网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar临时数据隧道3.2.Cpolar稳定隧道(云端设置)3.3.Cpolar稳定隧道(本地设置) 4.公网访问测…

图——最小生成树实现(Kruskal算法,prime算法)

目录 预备知识: 最小生成树概念: Kruskal算法: 代码实现如下: 测试: Prime算法 : 代码实现如下: 测试: 结语: 预备知识: 连通图:在无向图…

代码随想录第二十三天 回溯算法 77.组合 216.组合总和 17.电话号码的字母组合

回溯算法 LeetCode 77 组合 题目描述 思路 递归函数的返回值以及参数 在这里要定义两个全局变量&#xff0c;一个用来存放符合条件单一结果&#xff0c;一个用来存放符合条件结果的集合。 代码如下&#xff1a; vector<vector<int>> result; // 存放符合条件…

【Java EE初阶十六】网络原理(一)

在网络原理中主要学习TCP/IP四层模型中的重点网络协议 1. 应用层 1.1 应用程序与协议 应用层是和程序员接触最密切的&#xff1b; 应用程序&#xff1a;在应用层这里&#xff0c;很多时候都是程序员自定义应用层协议&#xff08;步骤&#xff1a;1、根据需求&#xff0c;明确…

程序员必备技能----删库跑路大总结

删库跑路大总结&#xff0c;各个都是大杀器&#xff0c;破坏性太大&#xff0c;轻易不要尝试。 删除linux根目录&#xff0c;用户目录&#xff0c;其实还可以增加一个删除/etc。删除&#xff08;清除&#xff09;数据库。删除redis缓存和持久化文件。删除mongodb库。git push …

MCAL知识点(二十七):TC275如何通过GPT12实现ABZ解码

目录 1、概述 2、代码实现 1、概述 GPT12 - General Purpose Timer Unit (GPT12):通用定时器单元,具备较为灵活的定时器结构,可以用来做定时器、事件计数、脉冲宽度测量、产生PWM、频率调制、ABZ编码器增量测量。文章记录一下如何通过GPT12实现编码器ABZ信号的测量。 注意…

c#创建安装windows服务

背景:最近在做设备数据对接采集时,遇到一些设备不是标准的Service-Client接口,导致采集的数据不够准确;比如设备如果中途开关机后,加工的数量就会从0开始重新计数,因此需要实时监控设备的数据,进行叠加处理;考略到工厂设备比较多,实时监听接口的数据为每秒3次,因此将…

week04day01(爬虫)

一. 爬虫 只爬取公开的信息&#xff0c;不能爬取未公开的后台数据 1.爬虫的合法性 法无禁止皆可为 -- 属于法律的灰色地带https://www.tencent.com/robots.txt -- 网站/robots.txt 可以查看禁止爬取的内容 2. URL Uniform Resource Locator 统一资源定位符https://www.…

【国产MCU】-CH32V307-通用定时器(GPTM)-单脉冲模式

通用定时器(GPTM)-单脉冲模式 文章目录 通用定时器(GPTM)-单脉冲模式1、单脉冲模式介绍2、驱动API介绍3、单脉冲使用实例本文将详细介绍如何使用CH32V307通用定时器的单脉冲模式。 1、单脉冲模式介绍 单脉冲模式可以响应一个特定的事件,在一个延迟之后产生一个脉冲,延迟…

Sora--首个大型视频生成模型

Sora--首个大型视频生成模型 胡锡进于2024年2月20日认为&#xff1a;台当局怂了 新的改变世界模拟器视觉数据转换视频压缩时空补丁&#xff08;Spacetime Laten Patches&#xff09;视频生成扩展变压器算法和模型架构结语 胡锡进于2024年2月20日认为&#xff1a;台当局怂了 **T…

AI Agent规划能力全面拆解

“规划今天和每天的工作&#xff0c;然后执行规划” -- 撒切尔夫人 规划&#xff0c;无论对于人类还是智能体而言&#xff0c;本质上是一种预先设定行动的过程&#xff0c;以期望通过这些行动达到特定的目标或解决特定的问题。制定一个好的规划涉及对未来情景的预测、资源的…

机器学习面试:逻辑回归与朴素贝叶斯区别

逻辑回归与朴素贝叶斯区别有以下几个方面: (1)逻辑回归是判别模型&#xff0c;朴素贝叶斯是生成模型&#xff0c;所以生成和判别的所有区别它们都有。 (2)朴素贝叶斯属于贝叶斯&#xff0c;逻辑回归是最大似然&#xff0c;两种概率哲学间的区别。 (3)朴素贝叶斯需要条件独立假设…

ClickHouse--12-可视化工具操作

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 可视化工具操作1 tabixhttp://ui.tabix.io/ 2 DBeaverhttps://dbeaver.io/download/ 可视化工具操作 1 tabix tabix 支持通过浏览器直接连接 ClickHouse&#xff…

【Django】Django自定义后台表单——对一个关联外键对象同时添加多个内容

以官方文档为例&#xff1a; 一个投票问题包含多个选项&#xff0c;基本的表单设计只能一个选项一个选项添加&#xff0c;效率较低&#xff0c;如何在表单设计中一次性添加多个关联选项&#xff1f; 示例代码&#xff1a; from django.contrib import adminfrom .models impo…

springboot207基于springboot的实习管理系统

实习管理系统的设计与实现 摘要 近年来&#xff0c;信息化管理行业的不断兴起&#xff0c;使得人们的日常生活越来越离不开计算机和互联网技术。首先&#xff0c;根据收集到的用户需求分析&#xff0c;对设计系统有一个初步的认识与了解&#xff0c;确定实习管理系统的总体功…

消息队列MQ 保证消息不丢失(消息可靠性)

文章目录 概述RabbitMQ 怎么避免消息丢失&#xff08;可靠传输&#xff09;RocketMQ 怎么确保消息不丢失Kafka 怎么保证消息不丢失activeMQ 怎么避免消息丢失MQ 宕机了消息是否会丢失线上服务宕机时&#xff0c;如何保证数据100%不丢失吗&#xff1f;消息队列消息持久化 概述 …