前言:

关于读锁、写锁、乐观锁、悲观锁、行锁、表锁的理解可以看看以前我写的:
读锁、写锁、乐观锁、悲观锁、行锁、表锁

内部锁:在MySQL服务器内部执行的锁,以管理多个会话对表内容的争用。这种类型的锁是内部的,因为它完全由MySQL服务器执行,不涉及其他程序。

表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

一、MySQL锁机制

关于MySQL有哪些存储引擎,可以看看我以前写的:查看和修改mysql存储引擎

在MySQL中不同的存储引擎支持不同的锁机制。

MyISAMMEMORYMERGE:表级锁(table-level locking);

BDB:页面锁(page-level locking),表级锁;

InnoDB:行级锁(row-level locking),表级锁,默认情况下是采用行级锁

表级锁:适用于一次只允许一个会话更新这些表。这种锁定级别使这些存储引擎更适合只读、多读或单用户应用程序。

行级锁:适用于InnoDB类型的表。用于支持多个会话同时进行写访问。适合适用于多用户、高并发和OLTP(在线事务处理)应用程序。

注意,特别说明:

在用LOCK TABLES给表显式加表锁时,必须同时取得所有涉及到表的锁,并且MySQL不支持锁升级。也就是说,在执行LOCK TABLES后,只能访问显式加锁的这些表,不能访问未加锁的表;同时,如果加的是读锁,那么只能执行查询操作,而不能执行更新操作。在自动加锁的情况下也一样,MyISAM总是一次获得SQL语句所需要的全部锁。这也正是MyISAM表不会出现死锁(Deadlock Free)的原因。

我们主要了解MyISAM表锁和InnoDB行锁;

二、MyISAM表锁

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

对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;对MyISAM表的写操作,则会阻塞其他用户对同一表的读和写操作;MyISAM表的读操作与写操作之间,以及写操作之间是串行的!当一个线程获得对一个表的写锁后,只有持有锁的线程可以对表进行更新操作。其他线程的读、写操作都会等待,直到锁被释放为止。

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

加读锁
LOCK TABLES 表名 READ;

加写锁
LOCK TABLES 表名 WRITE;

解锁有三种情况:

  1. UNLOCK TABLES;
  2. 再次使用 LOCK TABLES 其他表 READ/WRITE;
  3. 当前线程关闭

特别说明

当使用LOCK TABLES时,不仅需要一次锁定用到的所有表,而且这些表所有取的别名也要锁,否则也会出错!
mysql> lock table 表名 as 别名1 read,表名 as 别名2 read;

三、表级锁争用情况

show status like 'table%';

我们主要看table_locks_waitedtable_locks_immediate这2个状态变量;
如果Table_locks_waited的值比较高,则说明存在着较严重的表级锁争用情况。

四、并发插入(Concurrent Inserts)

MyISAM表并发插入条件的情况下,允许其他用户在表尾并发插入记录,在LOCK TABLES时加了“local”选项

Lock tables 表名 read local

MyISAM表的读和写是串行的;一定条件下,MyISAM表也支持查询和插入操作的并发进行

MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别可以为0、1或2。

concurrent_insert=0,不允许并发插入。

concurrent_insert=1,如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录。这也是MySQL的默认设置。

concurrent_insert=2,无论MyISAM表中有没有空洞,都允许在表尾并发插入记录。

可以利用MyISAM存储引擎的并发插入特性,来解决应用中对同一表查询和插入的锁争用。例如,将concurrent_insert系统变量设为2,总是允许并发插入;同时,通过定期在系统空闲时段执行 OPTIMIZE TABLE语句来整理空间碎片,收回因删除记录而产生的中间空洞。

五、MyISAM的锁调度

MyISAM存储引擎的读锁和写锁是互斥的,读写操作是串行的,在同时有2个进程,一个请求读锁,一个请求写锁,优先写锁!在锁的等待队列中,相比读锁,写锁总是优先
在MyISAM中写请求一般比读请求要重要!

所以,MyISAM表不太适合于有大量更新操作和查询操作应用,大量的更新操作会造成查询操作很难获得读锁,从而可能永远阻塞。

可以通过一些设置来调节MyISAM的调度行为:

  1. 通过指定启动参数low-priority-updates,使MyISAM引擎默认给予读请求以优先的权利。
  1. 通过执行命令SET LOW_PRIORITY_UPDATES=1,使该连接发出的更新请求优先级降低。
  1. 通过指定INSERT、UPDATE、DELETE语句的LOW_PRIORITY属性,降低该语句的优先级。

MySQL也提供了一种折中的办法来调节读写冲突,即给系统参数max_write_lock_count设置一个合适的值,当一个表的读锁达到这个值后,MySQL就暂时将写请求的优先级降低,给读进程一定获得锁的机会。

特别强调:

需要长时间运行的查询操作,也会使写进程 饿死!因此,应用中应尽量避免出现长时间运行的查询操作,不要总想用一条SELECT语
句来解决问题,因为这种看似巧妙的SQL语句,往往比较复杂,执行时间较长,在可能的情况下可以通过使用中间表等措施对SQL语句做一定的“分解”,使每
一步查询都能在较短时间完成,从而减少锁冲突如果复杂查询不可避免,应尽量安排在数据库空闲时段执行,比如一些定定时大量数据的抽数据或者大量数据进行统计的操作可以安排在夜间执行。

MySQL中的锁机制、MyISAM表锁、MyISAM表级锁争用情况、MyISAM并发插入Concurrent Inserts、MyISAM的锁调度相关推荐

  1. mysql的锁机制(读锁,写锁,表锁,行锁,悲观锁,乐观锁,间隙锁)

    读锁和写锁 介绍 MyISAM表锁中的读锁和写锁 读锁(共享锁S): 对同一个数据,多个读操作可以同时进行,互不干扰.加锁的会话只能对此表进行读操作,其他会话也只能进行读操作.MyISAM的读默认是加 ...

  2. mysql中的存储机制_Mysql的存储引擎

    MySQL的存储引擎存储引擎是什么?MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供广泛的不同的功能和能力.通过选 ...

  3. 认真学习MySQL中的MVCC机制

    什么是MVCC?MVCC(Multiversion Concurrency Control),多版本并发控制.顾名思义,MVCC是通过数据行的多个版本管理来实现数据库的并发控制.这项技术使得在Inno ...

  4. mysql中的mvcc机制

    MVCC多版本并发控制 简述MySQL锁 在InnoDB引擎下,按锁的粒度分类,可以分为行锁和表锁. 行锁实际上是作用在索引之上的.当我们的SQL命中了索引,那锁住的就是命中条件内的索引节点(这就是行 ...

  5. mysql语句中多表查询_6.MySql中的SQL语句(五):多表查询

    多表查询有如下几种: 合并结果集:UNION.UNION ALL 连接查询 内连接[INNER] JOINON 外连接OUTER JOIN ON 左外连接LEFT [OUTER] JOIN 右外连接R ...

  6. Mysql中如何根据.frm和.idb文件恢复表结构

    .frm和.idb文件是Mysql数据库使用InnoDB数据库引擎时产生的两个文件. ~表名.frm文件存储的相关表的表结构.索引等元数据. ~表名.idb文件存储的相关表中的数据记录. 举例: ad ...

  7. mysql scott用户_在mysql中创建 oracle scott 用户的四个表及插入初始化数据

    各表的字段的含义: 1.  部门表:dept № 名称 类型 描述 1 DEPTNO NUMBER(2) 表示部门编号,由两位数字所组成 2 DNAME VARCHAR2(14) 部门名称,最多由14 ...

  8. mysql 查看表格scott_在mysql中创建 oracle scott 用户的四个表及插入初始化数据

    各表的字段的含义: 1.  部门表:dept № 名称 类型 描述 1 DEPTNO NUMBER(2) 表示部门编号,由两位数字所组成 2 DNAME VARCHAR2(14) 部门名称,最多由14 ...

  9. mysql中overwrite,打造集群间HIVE数据库表半自动迁移(overwrite)工具

    Author:Christopher_L1n | CSDN Blog | 未经允许,禁止转载 Hive -> Hive 集群间迁移数据库表 阅读提示 为了代码易读性,脚本中加入冗余的参数赋值,可 ...

最新文章

  1. AI领域为何缺乏突破?前Quora工程VP:Hinton没有说到点子上
  2. 【HTML】行内元素与块级元素
  3. Sort_Buffer_Size 设置对服务器性能的影响
  4. JESD204B概述
  5. __attribute__ ((packed))
  6. POJ 3356 水LCS
  7. 爬取IMDBTOP250
  8. linux的基础知识——会话
  9. SQL Server插入binary类型的数据
  10. js(一) 三大事件 实现注册验证
  11. 编写dll 关于declspec(dllexport)和declspec(dllimport)
  12. java jconsole 远程连接_jconsole连接远程tomcat
  13. Git检查现有 SSH 密钥
  14. 如何用电脑破解WiFi
  15. python归一化nan加扰动_标准化和归一化对机器学习经典模型的影响
  16. cs224w(图机器学习)2021冬季课程学习笔记8 Colab 2
  17. 斐讯k1支持千兆吗_斐讯K2是不是千兆路由器
  18. 组合学:使用10个数字与52个字母生成1477万个不重复的4位串码V4衍生版本
  19. (伪)Python爬取猫眼电影(反反爬虫过程中遇到的坑)
  20. 语音和面部识别技术能帮助AI在情商上超越人类吗

热门文章

  1. python 在List中随机抽取n个元素
  2. DirectX(dll)修复软件推荐4.2增强版
  3. 解决idea中每次创建项目都要重复配置maven,全网几步配置
  4. 关于冲正,需要知道的那点事
  5. 基于Vue实现的网页音乐播放器
  6. electron-vue 仿网易云客户端(待完成)
  7. pyecharts 世界地图国家中英文对照表
  8. html手机号输入框,手机号输入框自动格式化为344
  9. 四步完成离线部署wvs
  10. CSS3属性border-radius参数详解