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很大,则说明表锁竞争很激烈,并发性能低下。

mysql myisam 行锁_MySQL MYISAM引擎表锁和行锁详解相关推荐

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

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

  2. mysql 优化300例_MySQL配置文件my.cnf参数优化和中文详解

    Mysql参数优化对于新手来讲,是比较难懂的东西,其实这个参数优化,是个很复杂的东西,对于不同的网站,及其在线量,访问量,帖子数量,网络情况,以及机器硬件配置都有关系,优化不可能一次性完成,需要不断的 ...

  3. mysql通过集合查询_MySQL使用集合函数进行查询操作实例详解

    本文实例讲述了MySQL使用集合函数进行查询操作.分享给大家供大家参考,具体如下: COUNT函数 SELECT COUNT(*) AS cust_num from customers; SELECT ...

  4. 删除mysql表_Mysql 删除数据表的三种方式详解

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

  5. mysql b tree图_MySQL索引--B-Tree(B+Tree)图文详解

    看了很多关于索引的博客,讲的大同小异.但是始终没有让我明白关于索引的一些概念,如B-Tree索引,Hash索引,唯一索引....或许有很多人和我一样,没搞清楚概念就开始研究B-Tree,B+Tree等 ...

  6. mysql sql执行过程_MySQL探秘(二):SQL语句执行过程详解

    昔日庖丁解牛,未见全牛,所赖者是其对牛内部骨架结构的了解,对于MySQL亦是如此,只有更加全面地了解SQL语句执行的每个过程,才能更好的进行SQL的设计和优化. 当希望MySQL能够以更高的性能运行查 ...

  7. mysql数据库帐户_MySQL数据库用户帐号管理基础知识详解

    MySQL管理员应该知道怎样通过指定哪些用户可连接到服务器.从哪里进行连接,以及在连接 时做什么,来设置MySQL用户账号.MySQL3.22.11引入了两个更容易进行这项工作的语句:GRANT 语句 ...

  8. mysql字段类型原理_mysql数据类型和字段属性原理与用法详解

    本文实例讲述了mysql数据类型和字段属性.分享给大家供大家参考,具体如下: 本文内容: 数据类型 数值类型 整数型 浮点型 定点型 日期时间类型 字符串类型 补充: 显示宽度与zerofll 记录长 ...

  9. mysql 时间取日期函数_mysql 获取当前日期函数及时间格式化参数详解

    MYSQL 获取当前日期及日期格式 获取系统日期: NOW() 格式化日期: DATE_FORMAT(date, format) 注: date:时间字段 format:日期格式 返回系统日期,输出 ...

  10. mysql format row_MySQL之InnoDB存储引擎:Row Format行格式

    MySQL下用的比较多.比较广的存储引擎就属InnoDB.这里我们来介绍下InnoDB存储引擎下数据记录的存储格式--Row Format行格式 基本操作 在MySQL中,所谓Row Format行格 ...

最新文章

  1. 大数据揭秘:北京每天这些道路“最红”
  2. WinJS实用开发技巧(3):仿微博信息流JK快捷键滚动
  3. DELPHI第三方控件及组件大全(安装方法与使用)
  4. 虚拟系统管理VSM提高服务器整合率
  5. 运算符——Python
  6. 卷积神经网络---文本分类原理及代码
  7. 接口自动化测试框架搭建(2、配置文件配置文件的读取)--python+HTMLTestRunnerCN+request+unittest+mock+db
  8. Visual Studio Code 运行html文件右键Open In Other Browsers提示找不到Chrome的解决办法
  9. MOS管常用电路分析
  10. python培训班-千锋教育Python培训-坚持高品质全程面授Python培训机构
  11. 在网页中快速集成自己的即时通聊天,实现类是淘宝旺旺的在线洽谈效果。
  12. pytorch 移植到Android平台(一)
  13. Confluence 6 配置快速导航
  14. 【SSR】287- 从头开始,彻底理解服务端渲染原理
  15. mysql 时区设定_设置MySQL默认时区
  16. Data transformation R语言与python
  17. 【UE4教程】Unreal 4.22 UI显示指定物体-实时渲染
  18. 如何写好科研论文(学习笔记2000字)
  19. linux 内存与磁盘管理
  20. 双网卡共享4G网络上网

热门文章

  1. css滚动条修改样式
  2. python string indices must be_python报错string indices must be integers,怎么解决?
  3. IBM/Thinkpad T61的骗局——最近疯起的二手T61高配置低价的真实故事
  4. MFC 捕获按钮 按下和抬起 (转)
  5. ღ_★古今最有霸气的名句★_ღ
  6. InDesign 教程:如何设置边距和分栏?
  7. Jetson Xavier NX (16) -- Jetson IIC: PCA9685
  8. 快来装扮你的新标签页
  9. mysql mklink_挂载与链接(assign与mklink)——Windows 7的磁盘分区规划 | 学步园
  10. v-if , v-show 和v-for