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

  1. mysql 排它锁_Mysql共享锁、排他锁、悲观锁、乐观锁

    一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |--排他锁(X锁,MyISAM 叫做写锁) |--间隙锁( ...

  2. mysql建表时外检怎么创建_MySQL创建表时加入的约束以及外键约束的的意义

    1,创建表时加入的约束 a) 非空约束,not null b) 唯一约束,unique c) 主键约束,primary key d) 外键约束,foreign key 1,非空约束,针对某个字段设置其 ...

  3. mysql 虚表_mysql虚拟表

    虚拟表,就是实际上并不存在(物理上不存在),但是逻辑上存在的表. 在MySQL中,存在的虚拟表:临时表.内存表和视图,派生表. 只能从select语句可以返回虚拟表的是视图和派生表. 一.派生表 当s ...

  4. mysql 查看表v空间自增涨_MySQL InnoDB表空间加密

    从 MySQL5.7.11开始,MySQL对InnoDB支持存储在单独表空间中的表的数据加密 .此功能为物理表空间数据文件提供静态加密.该加密是在引擎内部数据页级别的加密手段,在数据页写入文件系统时加 ...

  5. mysql同表字段前4位复制_MySQL不同表之前的字段复制

    有时候,我们需要复制某个字段一整列的数据到另外一个新的字段中,这很简单,SQL可以这么写: UPDATE tb_1 SET content_target = content_source; 大概写法如 ...

  6. mysql建表是要注意什么问题_MySQL建表注意事项

    1.建表规范 -- 数据库名丶表名,全部使用小写字母,使用"_"下划线连接且长度小于12,做到见名知意 2.建议使用 innodb 引擎,这也是MySQL的默认引擎 3.字段类型选 ...

  7. mysql数据表损坏的常见原因是_MYSQL数据表损坏的分析

    MYSQL数据表损坏的分析 MYSQL 数据表损坏的分析<1.0>作 者: 王黎晓 完成日期: 2006-12-20 修改情况记录:版本号 修改人 修改日期 审核人 批准人 备注1.0-d ...

  8. mysql中什么来维护表之间_转mysql维护索引和表

    即使用正确的类型创建了表并加上了合适的索引,工作也没有结束,还需要维护表和索引来确保他们都正常工作.维护表有三个主要的目的:找到并修复损坏的表,维护准确的索引统计信息,减少碎片. 一.找到并修复损坏的 ...

  9. Mysql 乐观锁 事务,Mysql事务隔离级别与乐观锁的问题

    问题一: 当事务隔离级别设置为可重复读的时候,将所有select过的行都加了读锁,并且记录了版本号,当update 的时候们如果发现版本号变了,则事务失败回滚.不知道我这样理解是否正确? 问题二: 如 ...

最新文章

  1. vs release 调试 路径设置
  2. 直播回顾丨B2B 企业如何高效获客增长
  3. How is ABAP keyword highlight implemented in Chrome
  4. Oracle在Linux上的预配置
  5. C++ STL pair方法详解
  6. 简述一下索引的匹配原则_Mysql联合索引最左匹配原则
  7. hdu Collect More Jewels
  8. python实现 Floyd算法求解最短路径距离问题
  9. C#中is、as以及强制转换之间区别
  10. VS2008 调试windows服务项目
  11. 【简单快速】启动后桌面正常下方任务栏无反应/鼠标一直转圈
  12. linux python for循环语句,Python之for循环的使用
  13. Excel如何将数据上下调换位置
  14. Java实现发送短信
  15. flashfxp连接后文件名乱码问题
  16. 实现java多线程的3种方式
  17. 一起来自制水果甜品吧
  18. Windows Mobile 播放声音文件
  19. CSGO DIY-小地图修改
  20. RabbitMQ:使用Docker构建RabbitMQ高可用负载均衡集群

热门文章

  1. puppeteer执行js_使用Node.js和Puppeteer与表单和网页进行交互– 1
  2. 万字详解|手撕 9大排序算法!
  3. 2018年终总结—努力做一个有趣的人
  4. C#下2\10\16进制互转代码总汇
  5. C语言——顺序栈(Stack)
  6. python爬虫程序requests采用get和post方式
  7. Tensorflow 神经网络作业手写数字识别 训练、回测准确率
  8. HDFS使用JavaAPI操作上传特定副本到datanode
  9. 计算机科技与技术对应岗位,计算机技术与软件专业技术资格名称及岗位基本任职条件...
  10. Bootstrap模态框居中显示