延伸阅读:

五分钟了解Mysql的行级锁

一分钟深入Mysql的意向锁

mysql锁相关讲解及其应用——《深究mysql锁》了解锁前,一定要先看这篇,了解什么是MVCC,如果我们学习锁,没有MVCC的知识,理解起来会总觉得不明朗。本来我的这个只是个记录,并不是专门的讲给别人看的,后发现有不少人看,我还是专门加上这篇文章的链接。

我们首先需要知道的一个大前提是:mysql的锁是由具体的存储引擎实现的。所以像Mysql的默认引擎MyISAM和第三方插件引擎 InnoDB的锁实现机制是有区别的。可根据不同的场景选用不同的锁定机制。

Mysql有三种级别的锁定:表级锁定、页级锁定、行级锁定

一、定义

每次锁定的是一张表的锁机制就是表级别锁定(table-level)。它是MySQL各存储引擎中粒度最大的锁定机制。

二、优缺点

1. 优点

实现逻辑简单,开销小。

获取锁和释放锁的速度快。

由于表级锁一次会将整个表锁定,所以能很好的避免死锁问题。

2. 缺点

由于锁粒度最大,因此出现争用被锁定资源的概率也会最高,致使并发度十分低下。

三、支持存储引擎

使用表级锁定的主要有MyISAM,MEMORY,CSV等一些非事务性存储引擎。

四、表级锁类型

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

锁模式的兼容性:

对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写操作;

对MyISAM表的写操作,则会阻塞其他用户对同一表的读和写操作;

MyISAM表的读操作与写操作之间,以及写操作之间是串行的。当一个线程获得对一个表的写锁后,只有持有锁的线程可以对表进行更新操作。其他线程的读、写操作都会等待,直到锁被释放为止。

五、如何加表锁

在执行查询语句(select)前,会自动给涉及的所有表加读锁

在执行更新操作(update、delete、insert等)前,会自动给涉及的表加写锁。这个过程并不需要用户干预,因此不需要直接用lock table命令给MyISAM表显式加锁。

显示加写锁:

// 当一个线程获得对一个表的写锁后,只有持有锁的线程可以对表进行更新操作。

// 其他线程的读、写操作都会等待,直到锁被释放为止。

// test表将会被锁住,另一个线程执行select * from test where id = 3;将会一直等待,直到test表解锁

LOCK TABLE test WRITE;

显示加读锁

// test表将会被锁住,另一个线程执行select * from test where id = 3;不会等待

// 执行UPDATE test set name='peter' WHERE id = 4;将会一直等侍,直到test表解锁

LOCK table test READ;

显示释放锁:

UNLOCK TABLES;

需要注意的是,在同一个SQL session里,如果已经获取了一个表的锁定,则对没有锁的表不能进行任何操作,否则会报错。

// 锁定test表

LOCK table test WRITE;

// 操作锁定表没问题

SELECT * from test where id = 4;

// 操作没有锁的表会报错

SELECT * from bas_farm where id =1356

报错:[Err] 1100 - Table 'bas_farm' was not locked with LOCK TABLES。这是因为MyISAM希望一次获得sql语句所需要的全部锁。这也正是myisam表不会出现死锁的原因。

当然,你也不必担心,MyISAM引擎的默认方式是会给同一个session里的所有表都加上锁的,不会麻烦你自己显示操作的。

六、查看表级锁争用情况

执行:show status like ‘table%’;

mysql> show status like 'table%';

+----------------------------+-----------+

| Variable_name | Value |

+----------------------------+-----------+

| Table_locks_immediate | 20708 |

| Table_locks_waited | 0 |

+----------------------------+-----------+

Table_locks_immediate:产生表级锁定的次数;

Table_locks_waited:出现表级锁定争用而发生等待的次数;

如果Table_locks_waited状态值比较高,那么说明系统中表级锁定争用现象比较严重,就需要进一步分析为什么会有较多的锁定资源争用了。

七、优化表级锁定

优化表级锁时的最大问题是:提高并发度

###1. 通过减少查询时间缩短锁定时间

缩短锁定时间的总体原则是:让Query执行时间尽可能的短。

尽量减少大的、复杂的Query,将复杂Query分拆成几个小的Query分步执行;

尽可能的建立足够高效的索引,让数据检索更迅速;

尽量让MyISAM存储引擎的表只存放必要的信息,控制字段类型;

利用合适的机会优化MyISAM表数据文件。

###2. 设置可并发插入:concurrent_insert=2

MyISAM的表锁虽是读写互相阻塞的,但依然能够实现并行操作。MyISAM存储引擎有一个控制是否打开Concurrent Insert(并发插入)功能的参数选项:concurrent_insert,取值范围为0,1,2。

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

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

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

所以,我们可通过设置concurrent_insert=2,同时定期在系统空闲时段执行optimize table tableName语句来整理空间碎片,收回因删除记录而没有真正释放的空间,从而提高并发。optimize参考:mysql中OPTIMIZE TABLE的作用及使用

###3. 合理设置读写优先级

MyISAM存储引擎默认是写优先级大于读优先级。即使是写请求后到,写锁也会插到读锁请求之前。

但是,有时像修改文章点击数 操作是不那么重要的,我们希望的是读更快,此时我们可以这样:

UPDATE LOW_PRIORITY article SET click_num=134 WHERE id = 823

LOW_PRIORITY使得系统认为update操作优化级比读操作低,如果同时出现读操作和上面的更新操作,则优先执行读操作。

MySQL提供了几个语句调节符,允许你修改它的调度策略:

LOW_PRIORITY关键字应用于:DELETE、INSERT、LOAD DATA、REPLACE和UPDATE。

HIGH_PRIORITY关键字应用于:SELECT、INSERT语句。

delayed(延迟)关键字应用于:INSERT、REPLACE语句。

如果你希望所有支持LOW_PRIORITY选项的语句都默认地按照低优先级来处理,那么可能使用**low-priority-updates**选项来启动服务器。然后可通过使用insert HIGH_PRIORITY table.....来把个别我们希望的INSERT语句提高到正常的写入优先级。

mysql慢查询 表级锁_三分钟了解Mysql的表级锁——《深究Mysql锁》相关推荐

  1. mysql数据库查询要注意事项_三种mysql高级查询技巧_数据库_mysql函数_课课家

    大家都知道GROUP BY,但是大家知道GROUP BY后面可以带哪些函数吗?今天给大家介绍下GROUP BY后面可以带的函数. 1GROUP_CONCAT 在MySQL中,你可以获取表达式组合的连接 ...

  2. java 写tb级文件_三管齐下!TB 级文件的上传性能瞬间被优化 100 倍!

    作者 | 中华石杉 责编 | 伍杏玲 本文经授权转载石杉的架构笔记(ID:shishan100) 这篇文章我们来看看,世界上最优秀的分布式文件系统HDFS,是如何对超大文件的上传做性能优化的? 首先, ...

  3. sql 如何设置行级锁_如何使用SQL Server 2016行级安全性过滤和阻止数据访问

    sql 如何设置行级锁 SQL Server 2016 came with many new features and enhancements for existing ones, that con ...

  4. mysql和oracle冲突吗_三分钟带你分清MySQL 和Oracle之间的误区

    原标题:三分钟带你分清MySQL 和Oracle之间的误区 来自:华为云开发者社区 摘要:MySQL和Oracle,别再傻傻分不清. MySQL 和Oracle 在开发中的使用是随处可见的,那就简单去 ...

  5. Juniper 210 密码清不掉_三分钟学会如何找回mysql密码

    一.在测试工作中我们肯定会写一些sq查询语句方便我们验证数据是否正确,从而判断当前软件是否存在缺陷,但是查询的过程中肯定需要我们先连接数据库,如果数据库密码忘记我们就无法完成工作,这里就教会大家如何快 ...

  6. mysql触发器主机自动增长_三分钟带你分清 Mysql 和 Oracle 之间的误区

    摘要:Mysql 和Oracle,别再傻傻分不清. mysql 和Oracle 在开发中的使用是随处可见的,那就简单去了解一下这俩款火的不行的数据库. 本质区别: Oracle数据库是一个对象关系数据 ...

  7. mysql数据库查询余额_MySQL 数据库(三):查

    掌握 单表查询 掌握 多表查询 掌握 order by 排序方法 掌握 in 查询用法 掌握 like 模糊查询用法 掌握 count() 统计用法 掌握 group by 分组用法 掌握 disti ...

  8. mysql联合查询语句详解_实例讲解MySQL联合查询

    1. 内联结: Select A.Name, B.Hobby from A, B where A.id = B.id,这是隐式的内联结,查询的结果是: Name Hobby Tim Football ...

  9. sql 查询上个月的数据_数据分析-SQL 进阶篇 多表查询

    知识点 一.表的加法 Union:删除表中的重复值 union al:包含表中所有内容,包括重复值 二.表的联结 联结:join 联结分为以下五种: 交叉联结(cross join)又称为笛卡尔积:将 ...

最新文章

  1. 软件测试培训怎么学?有没有发展前景?
  2. 关于C和C++的一点观点
  3. window.open()函数参数说明
  4. 群友:事务中的异常不也抛出了,为什么没catch到而回滚?
  5. 【SpringMVC 之应用篇】 1_SpringMVC入门 —— 第一个 Spring MVC 程序
  6. php计算程序运行时间的简单例子分享
  7. 433M无线串口E30-TTL-100在农业物联网上的应用
  8. python 装饰器有哪些_python装饰器有什么用
  9. java中自定义泛型类_java 自定义一个泛型类
  10. sap后台配置原因代码_【MM配置】Inventory Management 库存管理
  11. gradle打包web jar_Gradle构建SpringBoot并打包可运行的jar配置
  12. docker 中 NGINX+PHP+MYSQL+REDIS+Elasticsearch 环境搭建 (linux系统)
  13. pycharm怎么改成中文版?
  14. 物联网应用三个阶段,你在哪里?
  15. 最少的脚本实现在NSH脚本作业中加入动态参数
  16. 水果店快开业怎么发朋友圈,水果店开业怎么发朋友圈图片
  17. 网络常识,whirshark分析
  18. 全球与中国微型翘板开关市场现状及未来发展趋势
  19. NO.2-24 [网鼎杯 2020 朱雀组]Nmap
  20. mysql 基于一张表更新_MySQL更新表基于另一个表的值

热门文章

  1. 微型计算机常常采用三种线结构,中北大学微机原理习题册终极版考试必备
  2. java 文件进行加密解密_java使用异或对文件进行加密解密
  3. Boxes in a Line UVA - 12657 (双向链表)
  4. pl/sql连接Oracle数据库的方式
  5. 无法执行任何java命令,报错OutOfMemoryError: Cannot create GC thread. Out of system resources
  6. spi收发时的寄存器sr不变_「正点原子Linux连载」第二十七章SPI实验(一)
  7. 京东抢购机器人_双十二什么值得买?会自动收垃圾的扫拖机器人了解一下
  8. cmd 日志刷新卡屏
  9. Elasticsearch与SpringBoot整合 High-level-client-rest
  10. 内存二三事: Xcode 内存图、Instruments 可视化检测循环引用