我们首先需要知道的一个大前提是: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的表级锁的更多相关文章

  1. Mysql 的表级锁和行级锁

    表级锁 MySQL表级锁分为读锁和写锁. 读锁 用法:LOCK TABLE table_name [ AS alias_name ] READ 释放锁使用UNLOCK tables.可以为表使用别名, ...

  2. Mysql的表级锁和行级锁

    表级锁 MySQL表级锁分为读锁和写锁. 读锁 用法:LOCK TABLE table_name [ AS alias_name ] READ 释放锁使用UNLOCK tables.可以为表使用别名, ...

  3. MySQL学习笔记(五):MySQL表级锁和行级锁

    一:概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...

  4. MySQL表级锁和行级锁

    一:概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...

  5. MySQL中的表级锁

    数据的锁主要用来保证数据的一致性,数据库的锁从锁定的粒度上可以分为表级锁,行级锁和页级锁. MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制,比如MyISAM和MEMORY存 ...

  6. [数据库事务与锁]详解五: MySQL中的行级锁,表级锁,页级锁

    注明: 本文转载自http://www.hollischuang.com/archives/914 在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的 ...

  7. MySQL行级锁,表级锁,页级锁详解

    页级:引擎 BDB. 表级:引擎 MyISAM , 理解为锁住整个表,可以同时读,写不行 行级:引擎 INNODB , 单独的一行记录加锁 表级,直接锁定整张表,在你锁定期间,其它进程无法对该表进行写 ...

  8. MySQL行级锁、表级锁、页级锁详细介绍

    原文链接:http://www.jb51.net/article/50047.htm 页级:引擎 BDB.表级:引擎 MyISAM , 理解为锁住整个表,可以同时读,写不行行级:引擎 INNODB , ...

  9. mysql 表级锁

    表级锁:分为读锁和写锁: lock tables table_name read;//其他事务只能读,不能加写锁,要等待更新. SESSION 50 执行: mysql> update test ...

随机推荐

  1. Navicat for MySQL 批量执行多个 SQL 文件

    文件合并 type *.sql >> aaa.sql 执行sql文件 右键点击数据库

  2. 多线程 | 03 | CAS机制

    Compare and swap(CAS) 当前的处理器基本都支持CAS,只不过每个厂家所实现的算法并不一样罢了,每一个CAS操作过程都包含三个参数:一个内存地址V,一个期望的值A和一个新值B,操作的 ...

  3. python-变量&底层存储原理

    目录 1.变量 1.变量如何使用 2.变量存储的原理 --[ 重点 ] 3.变量存储要遵循印射关系 4.变量三要素 2.常量 3.底层优化 4.垃圾回收机制 1.变量 1.变量如何使用 1.什么是变量 ...

  4. MySQL语法练习一

    DESC t_dept ALTER TABLE t_dept ADD descri VARCHAR(20) ALTER TABLE t_dept ADD decribe VARCHAR(20) FIR ...

  5. Trivy 容器镜像扫描工具学习

    简介 官方地址:https://github.com/aquasecurity/trivy Trivy是aqua(专注云原生场景下的安全)公司的一款开源工具,之前历史文章也有对aqua的一些介绍. T ...

  6. 一文了解Docker基本概念

    一.何为Docker Docker 是一个用于开发.交付和运行应用程序的开放平台,Docker 使您能够将应用程序与基础环境分开,以便您可以快速交付软件.借用百度百科的话来说,Docker 是一个开源 ...

  7. [hdu7065]Yinyang

    将一个格子看作一个节点,相邻(有公共边)的同色格子之间连边,那么由前两个条件即要求图恰被分为两个非空连通块(由于$n,m\ge 3$,显然不能不使用某种颜色) 下面,来分析图中的简单环,其对应于网格图 ...

  8. [bzoj3351]Regions

    这道题有一种较为暴力的做法,对于每个点枚举所有与r2为该属性的询问并加以修改,最坏时间复杂度为o(nq),然而是可过的(97s) 发现只有当r2相同的询问数特别多时才会达到最坏时间复杂度,因此如果删除 ...

  9. [loj3463]表达式求值

    类似cf582E,先建出表达式树,然后树形dp+离散+min和max卷积的优化,复杂度为$o(nm|E|)$,无法通过 考虑我们仅关心于这$n$个数的大小关系,具体来说,假设给出的数组是$a_{i,j ...

  10. Docker 之 Dockerfile 常用语法与实战

    1. 概述 老话说的好:超越别人,不如超越自我,每天比昨天的自己更强就好. 言归正传,之前聊了 Docker 的相关知识,今天来聊聊如何编辑 Dockerfile 脚本,来创建我们自己的镜像. 2. ...