MySQL有三种锁:表级锁、行级锁和页面锁。BDB支持页面锁,MyISAM支持表级锁,而innoDB则支持表锁和行级锁。这篇文章主要介绍MYISAM引擎的表锁。


表锁分为读锁(read lock)和写锁(write lock)

1. 读锁(read lock)

当一个session给表加读锁,其他session也可以继续读取该表,但所有更新、删除和插入将会阻塞,直到将表解锁。下面是具体步骤:
session1给myisam_lock表加读锁:


session2可以照常读取myisam_lock表:


session2执行insert语句,被阻塞:


session1解锁myisam_lock表:


session2中被阻塞的insert操作成功执行:


MyISAM引擎在执行select时会自动给相关表加读锁,在执行update、delete和insert时会自动给相关表加写锁。而InnoDB则加行锁。

表级读锁有几点需要特别注意的地方:

①lock表的时候一定要把所有需要访问的表都锁住,因为锁表之后无法访问其他未加锁的表。(InnoDB一样)

②当前session lock表之后,当前session只能读锁住的表,而无法对其进行update、delete和insert操作。(InnoDB一样)

③同一个表如果在sql语句里面如果出现了N次,那么就要锁定N次,否则会出错。(InnoDB一样)


2. 写锁(write lock)

当一个session给表加写锁,其他session所有读取、更新、删除和插入将会阻塞,直到将表解锁。下面是具体步骤:
session1给myisam_lock表加写锁:

session2对myisam_lock表的查询被阻塞:

session1解锁myisam_lock表,session2查询出结果:

lock表的时候一定要把所有需要访问的表都锁住,因为锁表之后无法访问其他未加锁的表。


3. concurrent_insert和local操作(此操作为MyISAM引擎专有,InnoDB无此功能)

上面我们说到只要给一个表加了读锁,其他session对该表的写操作将被阻塞。那么有没有办法让其他session也能往里面添加数据呢?
这里我们可以使用local关键字,语法如下:lock table 表名 read local。这样在当前表被加读锁的时候,可以让其他session往表里添加记录,但需要配合concurrent_insert全局变量使用。
concurrent_insert属性有三中取值,分别是NEVER(0)、AUTO(1)和ALWAYS(2),从5.5.3版本开始concurrent_insert参数用枚举值,以前的版本则直接使用对应的数字。他们的含义如下:
NEVER:加读锁后,不允许其他session并发写入。
AUTO:加读锁后,在表里没有空洞(就是没有删除过行)的条件下,允许其他session并发写入。
ALWAYS:加读锁后,允许其他session并发写入。

通过show global variables like '%concurrent_insert%'命令可以查看当前数据库的设置:

通过set global concurrent_insert = ALWAYS命令可以改变数据库设置:

下面我们在AUTO的条件下进行试验,首先session1用local方式给myisam_lock表加读锁:

session2可以正常读取,还可以插入数据:

但session2插入的数据对session1是不可见的,必须等session1释放锁之后才可见:


4. MyISAM引擎锁的调度机制
MyISAM引擎默认是write lock优先于read lock的,也就是说如果一堆写请求和一堆读请求同时要一张表的锁,那读请求只能在所有的写请求执行完成后才能获得执行机会。这样就会出现一个很大的问题:如果我们在批量更新一张用户表,那么用户登录操作可能会出现长时间阻塞的情况,因为用户登录的读取操作在更新完之前无法访问用户表。
所以MyISAM最好不要用在那些更新和读取都非常频繁的表里,会造成读取的长时间阻塞。但我们可以用下面的方法来缓解这类问题:
①使用LOW_PRIORITY、HIGH_PRIORITY和DELAYED关键字。
语法为:insert [LOW_PRIORITY | HIGH_PRIORITY | DELAYED] into 表名 ...
执行delete、insert、update、load data和replace的时候可以使用LOW_PRIORITY来降低该更新语句的优先级,让读取操作能够执行。
执行select和insert的时候可以使用HIGH_PRIORITY来提高该语句的优先级,让读取操作能够执行。
执行insert和replace的时候可以使用DELAYED让MySQL返回OK状态给客户端,并且修改也是对该session可见的。但并不是已经将数据插入表,而是存储在内存里面等待排队。当能够获得表的写锁再插入。这样的好处是,提高插入的速度,客户端不需要等待太长时间。坏处是,不能返回自动递增的ID,以及系统崩溃时,MySQL还没有来得及插入数据的话,这些数据将会丢失。

②set LOW_PRIORITY_UPDATES = 1。
让所有支持LOW_PRIORITY选项的语句都默认地按照低优先级来处理。
③修改MAX_WRITE_LOCK_COUNT变量。
该变量默认为int最大值,表示当一个表的写锁数量达到设定的值后,就降低写锁的优先级,让读锁有机会执行。


5. 查看表锁的竞争情况

show status like 'table_locks%'


如果Table_locks_waited很大,则说明表锁竞争很激烈,并发性能低下。

转载于:https://blog.51cto.com/jaeger/1751481

MySQL MYISAM引擎表锁和行锁详解相关推荐

  1. MySQL 数据库 User表权限以及用户授权详解

    转载:https://blog.mimvp.com/article/27956.html MySQL 常用权限操作 1)本机登陆mysql: mysql -u root -p (-p一定要有):改变数 ...

  2. Mysql 删除数据表的三种方式详解

    用法: 1.当你不再需要该表时, 用 drop; 2.当你仍要保留该表,但要删除所有记录时, 用 truncate; 3.当你要删除部分记录或者有可能会后悔的话, 用 delete. 删除程度可从强到 ...

  3. mysql锁(全局锁、表锁、行锁、页锁、排他锁、共享锁)

    mysql锁 简介 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则. MySQL数据库由于其自身架构的特点,存在多种数据存储引擎,每种存储 ...

  4. mysql数据库存储引擎和索引的描述_Mysql InnoDB引擎的索引与存储结构详解

    前言 在Oracle 和SQL Server等数据库中只有一种存储引擎,所有数据存储管理机制都是一样的. 而MySql数据库提供了多种存储引擎.用户可以根据不同的需求为数据表选择不同的存储引擎,用户也 ...

  5. MySQL数据库锁机制之MyISAM引擎表锁和InnoDB行锁详解

    MySQL中的锁概念 Mysql中不同的存储引擎支持不同的锁机制.比如MyISAM和MEMORY存储引擎采用的表级锁,BDB采用的是页面锁,也支持表级锁,InnoDB存储引擎既支持行级锁,也支持表级锁 ...

  6. Mysql各数据库引擎优缺点,以及常用表锁,行锁,页面锁(个人总结)

    功能 MYISAM MEMORY INNODB ARCHIVE 事务 不支持 不支持 支持 不支持 哈希索引 不支持 支持 不支持 不支持 BTREE索引 支持 支持 支持 支持 锁机制 表锁 表锁 ...

  7. InnoDB 存储引擎中的表锁和行锁详解

    各位对 "锁" 这个概念应该都不是很陌生吧,Java 语言中就提供了两种锁:内置的 synchronized 锁和 Lock 接口,使用锁的目的就是管理对共享资源的并发访问,保证数 ...

  8. MySQL中的锁(表锁、行锁)

    锁是计算机协调多个进程或纯线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所在有数 ...

  9. mysql某个表被行锁了_MySQL中的锁(表锁、行锁)

    锁是计算机协调多个进程或纯线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所在有数 ...

  10. mysql 并发 锁表_MySQL中的锁(表锁、行锁) 并发控制锁

    https://github.com/MrLining/mysql/wiki/MySQL%E4%B8%AD%E7%9A%84%E9%94%81%EF%BC%88%E8%A1%A8%E9%94%81%E ...

最新文章

  1. 协作机器人鼻祖“重生”,卷土重来的Rethink能否给行业注入一针强心剂?
  2. 手把手教你发布自己的CocoaPods开源库
  3. [云炬创业基础笔记]第七张创业团队测试3
  4. hibernate ——联合主键
  5. 什么是13薪,真的有18薪、25薪的不?
  6. codeforce438D The Child and Sequence
  7. 免费python自学攻略-420小时学习代码之后:如何教你免费自学Python
  8. 前端学习总结【103天】:CSS——不用JavaScript实现tab标签切换的两种方法
  9. spring 之 AOP 理解
  10. hadoop学习使用
  11. SoapUI被动接口的压力测试/性能测试
  12. 直线分割平面的公式_几种分割平面问题 | 学步园
  13. java使用qq群发邮件_java群发发送qq邮件
  14. 开发人员如何规划自己的职业生涯
  15. Android 去掉标题栏
  16. 速记TCP/IP五层模型
  17. 高等数学——积分中值定理
  18. 音频降噪 java_流音频中的降噪和压缩
  19. 括号画家(括号匹配)
  20. android google定位和地图

热门文章

  1. ES6学习笔记对象的扩展(补充)
  2. python计算出nan_学习笔记0522:Tensorflow训练模型出现loss是nan的问题排查
  3. Linux中查看进程命令ps aux,ps -ef,ps -A,ps -a
  4. 全网首发:(解决办法)MAC OS Xcode给应用设置沙箱(Enable App Sandbox)之后,运行报错Illegal instruction: 4
  5. 文字处理技术:与布局相关的功能
  6. 与人和代码打交道,有何不同?
  7. python中访问lmdb
  8. linux cp 复制目录下文件到另一个目录下
  9. java txt 修改_java创建TXT文件并进行读、写、修改操作
  10. c语言程序游戏例子,C语言游戏编写例子.doc