深入理解mysql各种锁

目录
  • 锁的概述
  • 锁分类
    • 对数据库操作的粒度分
    • 对数据操作的类型分
  • mysql锁
    • 不同存储引擎支持锁级别
    • 锁介绍
  • MyISAM表锁
    • 如何添加表锁
    • 加解锁
    • 锁竞争
    • 锁的使用情况
  • InnoDB锁
    • 行锁
    • 锁升级
    • 间隙锁
    • 锁争用
  • 总结
  • 优化建议

锁的概述

锁是计算机协调多个进程或线程并访问某一资源的机制

在数据库中,除传统的计算机资源(如cpu、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源,如果保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素,从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂

锁分类

对数据库操作的粒度分

表锁:
	操作时,会锁定整个表
行锁:
	操作时,会锁定当前操作行

对数据操作的类型分

读锁(共享锁):
	针对同一份数据,多个读操作可以同时进行而不会相互影响
写锁(排它锁):
	当操作没有完成之前,它会阻断其他写锁和读锁

mysql锁

相对其他数据库而言,Mysql的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。

不同存储引擎支持锁级别

存储引擎 表级锁 行级锁 页面锁
MyISAM 支持 不支持 不支持
InnoDB 支持 支持 不支持
MEMORY 支持 不支持 不支持
BDB 支持 不支持 支持

锁介绍

很难笼统说哪种锁更好,需要根据特定的应用场景来分析哪种锁更合适。

锁类型 特点
表级锁 偏向MyISAM存储引擎,开销小,加锁快;不会出现死锁;锁定粒度大,发送锁冲突的概率最高,并发度最低。
行级锁 偏向InnoDB存储引擎,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁 开销和加锁时间介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般。

MyISAM表锁

如何添加表锁

MyISAM在执行查询语句(select)前,会自动给涉的所有表加锁,在执行更新操作(update、delete、insert等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此,用户一般不需要直接使用LOCK TABLE命令给MyISAM表显示加锁

加解锁

加读锁:
	lock table table_name read;
	---解锁 unlock tables;
加写锁:
	lock table table_name write;
	添加写锁当前会话可以读写操作,别的会话会处于阻塞(等待)状态
读锁限制写,写锁限制读写

锁竞争

1、对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;
2、对MyISAM的写操作,则会阻塞其他用户对表一表的读和写操作;
3、MyISAM锁调度是写优先。
	不适合作为主表,写锁后其他线程大量的更新会使查询很难得到锁,可能会造成永远阻塞。

锁的使用情况

查看锁的使用情况
	show open tables;
查看表的锁定情况
	show status like 'table_locks%';
		Table_locks_immediate:可以获取表级锁的次数,每立即获取锁,值加1
		Table_locks_waited:不能立即获取锁需要等待的次数,每等待一次,值加1,可以判断比较严重的表级锁争用情况

InnoDB锁

InnoDB与MyISAM的最大不同有亮点:一是支持事务;二是采用行级锁

行锁

共享锁:
	又称读锁,多个事务可以共享一把锁,但是只能读,不能写
排它锁:
	又称写锁,锁不共用,获取不到锁的事务不能进行读写操作
如果进行update、delete和insert 语句,innoDB会自动给涉及数据集加排它锁
对不同的select语句不会添加任何锁
显示的给查询添加锁
	添加共享锁:
		select * from table_name where ... Lock IN SHARE MODE
	添加排它锁:
		select * from table_name where ... FOR UPDATE

锁升级

索引失效,行锁升级表锁
where后面没索引也升级为表锁

间隙锁

InnoDB会对间隙不存在的数据也会加锁,称之为间隙锁

锁争用

show status like 'innodb_row_lock%';
	Innodb_row_lock_current_waits当前正在等待锁的数量
	Innodb_row_lock_time 锁定的总时长
	Innodb_row_lock_time_avg 锁定的平均时长
	Innodb_row_lock_time_max 锁定的最大时长
	Innodb_row_lock_waits 系统启动到现在总共等待次数

总结

innoDB存储引擎实现了行锁,虽然锁定机制的实现方面带来了性能消耗可能比较表锁会更高些,但是在整体并发处理能力方面要远优于MyISAM表锁,当系统并发比较高的时候,InnoDB的整体性能和MyISAM会有比较明显的优势

优化建议

尽可能让所有数据检索都能通过索引来完成,避免无索引行锁升级为表锁
合理设计索引,尽量缩小锁的范围
尽可能减少索引条件,及索引范围,避免间隙锁
尽量控制事务大小,减少锁定资源量和时间的长度
尽可能使用低级别事务隔离(需要业务能满足需求)

到此这篇关于深入理解mysql各种锁的文章就介绍到这了,更多相关mysql锁内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 简单了解 MySQL 中相关的锁

    本文主要是带大家快速了解 InnoDB 中锁相关的知识 基础概念解析和RocketMQ详细的源码解析 http://xiazai.jb51.net/202105/yuanma/RocketMQ_jb51.rar 为什么需要加锁 首先,为什么要加锁?我想我不用多说了,想象接下来的场景你就能 GET 了. 你在商场的卫生间上厕所,此时你一定会做的操作是啥?锁门.如果不锁门,上厕所上着上着,啪一下门就被打开了,可能大概也许似乎貌似有那么一丁点的不太合适. 数据也是一样,在并发的场景下,如果不对数据加锁

  • mysql中锁机制的最全面讲解

    目录 前言 全局锁 全库逻辑备份 FTWRL和set global readonly=true的区别 表级锁 MDL锁 行锁 死锁 记录锁 间隙锁 临键锁 乐观锁和悲观锁 总结 前言 根据加锁的粒度区分 全局锁 表级锁 行锁 记录锁 间隙锁 临键锁 根据加锁的场景 乐观锁 悲观锁 全局锁 锁对象是:整个数据库实例 Flush tables with read lock (FTWRL)-会让整个库处于只读状态 使用场景: 做全库逻辑备份 全库逻辑备份 为什么要进行全局锁才能进行数据备份呢? 就比如

  • MySQL悲观锁与乐观锁的实现方案

    目录 前言 实战 1.无锁 2.悲观锁 3.乐观锁 总结 前言 悲观锁和乐观锁是用来解决并发问题的两种思想,在不同的平台有着各自的实现.例如在Java中,synchronized就可以认为是悲观锁的实现(不严谨,有锁升级的过程,升级到重量级锁才算),Atomic***原子类可以认为是乐观锁的实现. 悲观锁 具有强烈的独占和排他特性,在整个处理过程中将数据处于锁定状态,一般是通过系统的互斥量来实现.当其他线程想要获取锁时会被阻塞,直到持有锁的线程释放锁. 乐观锁 对数据的修改和访问持乐观态度,假设

  • 深入理解mysql各种锁

    目录 锁的概述 锁分类 对数据库操作的粒度分 对数据操作的类型分 mysql锁 不同存储引擎支持锁级别 锁介绍 MyISAM表锁 如何添加表锁 加解锁 锁竞争 锁的使用情况 InnoDB锁 行锁 锁升级 间隙锁 锁争用 总结 优化建议 锁的概述 锁是计算机协调多个进程或线程并访问某一资源的机制 在数据库中,除传统的计算机资源(如cpu.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源,如果保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性

  • mysql 悲观锁与乐观锁的理解及应用分析

    本文实例讲述了mysql 悲观锁与乐观锁.分享给大家供大家参考,具体如下: 悲观锁与乐观锁是人们定义出来的概念,你可以理解为一种思想,是处理并发资源的常用手段. 不要把他们与mysql中提供的锁机制(表锁,行锁,排他锁,共享锁)混为一谈. 一.悲观锁 顾名思义,就是对于数据的处理持悲观态度,总认为会发生并发冲突,获取和修改数据时,别人会修改数据.所以在整个数据处理过程中,需要将数据锁定. 悲观锁的实现,通常依靠数据库提供的锁机制实现,比如mysql的排他锁,select .... for upd

  • 深入理解Mysql事务隔离级别与锁机制问题

    概述 数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能导致脏读.脏写.不可重复度和幻读.这些问题的本质都是数据库的多事务并发问题,为了解决事务并发问题,数据库设计了事务隔离机制.锁机制.MVCC多版本并发控制隔离机制,用一整套机制来解决多事务并发问题. 事务及其ACID属性 原子性:操作的不可分割: 一致性:数据的一致性: 隔离性:事务之间互不干扰: 持久性:数据的修改时永久的: 并发事务处理带来的问题 脏写:丢失更新,最后的更新覆盖了由其他事务所做的更

  • 你需要理解的关于MySQL的锁知识

    一.前言 MySQL 的锁按照范围可以分为全局锁.表锁.行锁,其中行锁是由数据库引擎实现的,并不是所有的引擎都提供行锁,MyISAM 就不支持行锁,所以文章介绍行锁会以InnoDB引擎为例来介绍行锁. 二.全局锁 MySQL 提供全局锁来对整个数据库实例加锁. 语法: FLUSH TABLES WITH READ LOCK 这条语句一般都是用来备份的,当执行这条语句后,数据库所有打开的表都会被关闭,并且使用全局读锁锁定数据库的所有表,同时,其他线程的更新语句(增删改),数据定义语句(建表,修改表

  • 基于更新SQL语句理解MySQL锁定详解

    前言 MySQL数据库锁是实现数据一致性,解决并发问题的重要手段.数据库是一个多用户共享的资源,当出现并发的时候,就会导致出现各种各样奇怪的问题,就像程序代码一样,出现多线程并发的时候,如果不做特殊控制的话,就会出现意外的事情,比如"脏"数据.修改丢失等问题.所以数据库并发需要使用事务来控制,事务并发问题需要数据库锁来控制,所以数据库锁是跟并发控制和事务联系在一起的. 本文主要描述基于更新SQL语句来理解MySQL锁定.下面话不多说了,来一起看看详细的介绍吧 一.构造环境 (root@

  • 深入理解MySQL重做日志 redo log

    目录 一.redo log概念 二.缓存.磁盘结构 在事务的ACID特性中,原子性(A).一致性(C).持久性(D)由undo log和redo log实现,隔离性(I)由锁+MVCC实现 undo log:事务还没有commit,中途执行异常,可以使用undo log把数据恢复到事务执行前的状态,确保事务的原子性 redo log:事务commit成功,由于更新磁盘数据需要一段时间,此时若发生异常,可以使用redo log重新执行这一事务的SQL,确保事务的持久性(只要事务commit成功,不

  • 深入理解mysql事务与存储引擎

    目录 一.MySQL事务 1.事务的概念 2.事务的 ACID 特点 3.事物之间的互相影响 二.Mysql及事务隔离级别 1.查询全局事务隔离级别 2.查询会话事务隔离级别 3.设置全局事务隔离级别 4.设置会话事务隔离级别 三.事务控制语句 1.相关语句 2.案例 3.使用 set 设置控制事务 四.MySQL 存储引擎 1.存储引擎概念介绍 2.查看系统支持的存储引擎 3.查看表使用的存储引擎 4.修改存储引擎 一.MySQL事务 1.事务的概念 (1)事务是一种机制.一个操作序列,包含了

  • 深入理解MySQL事务的4种隔离级别

    目录 1 简介 2 什么是数据库事务? 2.1 事务的四大特性(ACID) 3 并发事务会导致的问题 3.1 本文会使用到的 SQL 语句 3.1.1 示例表结构 3.1.2 查询事务的默认隔离级别 3.1.3 设置当前会话的事务隔离级别 4 事务的4种隔离级别和示例演示 4.1 读未提交 4.2 读已提交 4.3 可重复读 4.4 串行化 1 简介 事务的4种隔离级别分别是读未提交(Read Uncommitted).读已提交(Read Committed). 可重复读(Repeatable

  • 一文搞懂MySQL元数据锁(MDL)

    目录 一.什么是metadata lock 二.MDL和行锁有什么区别 三.MDL为什么会造成系统崩溃 四.MDL的生命周期有多长 五.如何快速找到阻塞源头 六.本文开始的案例最终如何解决 小结 某日,路上收到用户咨询,为了清除空间,想删除某200多G大表数据,且已经确认此表不再有业务访问,于是执行了一条命令‘delete from bigtable’,但好长时间也没删完,经过咨询后,获知drop table删除表速度快,而且能彻底释放空间,于是又在另外一个session中执行了‘drop ta

  • MySQL使用表锁和行锁的场景详解

    目录 前言 全局锁 表级锁 表锁 元数据锁 意向锁 行级锁 总结 前言 MySQL Innodb 的锁可以说是执行引擎的并发基础了,有了锁才能保证数据的一致性.众所周知,我们都知道 Innodb 有全局锁.表级锁.行级锁三种,但你知道什么时候会用表锁,什么时候会用行锁吗? 虽然对 MySQL 的知识点挺熟悉的,但一开始看到这个问题,树哥也是有点懵,我还真没从这个角度去思考过.大家可以暂时 1 分钟思考下答案,后面我将带大家弄清楚这个问题. 对于这个问题,我只能粗略地想起一些片段,例如: 对于表级

随机推荐