文档章节

MySQL锁

casoc
 casoc
发布于 2017/08/15 09:39
字数 1184
阅读 14
收藏 1

MySQL的锁主要分为表级锁(MyISAM为代表)、页级锁(BDB为代表)、行级锁(InnoDB为代表);

表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生冲突的概率最高,并发度最低

行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生冲突的概率最低,并发度最高

页级锁:开销和加锁时间介于表级锁和行级锁之间;会出现死锁;粒度和并发介于表级和行级之间

 

锁选择:

可以通过检查table_locks_waited和table_locks_immediate状态变量来分析锁冲突是否多,从而决定使用哪种锁;

table_locks_waited 表示SQL获取锁失败等待释放锁的次数

table_locks_immediate 表示SQL立即获取到锁的次数

show status like 'table%';

 

MyISAM锁问题

MyISAM的表级锁加锁方式:

lock table {table_name {as alias name}} {write|read} <local>

如果同时锁定多张表:

lock tables {table_name {as alias name}} {write|read} <local>, {table_name} {write|read} <local>

MyISAM在执行查询前会自动给涉及的所有表加读锁,在执行更新操作前会自动给涉及的表加写锁,所以上面的显式加锁并非必要;

local表示锁定后可以继续在表尾添加记录

当用lock tables给表显式加锁的时候,必须同时取得所有涉及表的锁(这是表级锁不能死锁的原因),并且不能访问未加锁的表。

 

解锁:

unlock tables;

 

并发插入(Concurrent Inserts):

MyISAM表的多些是串行的,但是在一定条件下,可以并发在表末尾插入;MyISAM存储引擎有一个系统变量concurrent_insert,可能曲子为0,1,2;

  • 值为0,表示不允许并行插入
  • 值为1,如果MyISAM表中没有空洞(即表的中间没有被删除的行),允许在表尾部并发插入
  • 值为2,无论有没有空洞,都允许在表位并发插入

 

*表空间的碎片可以使用optimize table {table_name};整理碎片

 

MyISAM默认会优先获得写锁,如在有Session1获取写锁的情况下,这时有一个Session2需要获得读锁,之后又有一个Session3需要获得写锁,由于这时Session1并没有释放写锁,所以后面的两个Session都将陷入等待,但是当写锁释放后,会由Sesssion优先获取到写锁,即使Session3晚于Session2申请锁。由于这个原因,MyISAM在有大量更新语句的情况下,会一直阻塞读操作,所以MyISAM更适合读远远大于写的情况下使用。

可以通过一些设置调节MyISAM的调度行为:

  • 通过制定启动参数low-priority-updates,是MyISAM引擎默认给予读请求优先的权利
  • 通过执行命令SET LOW_PRIORITY_UPDATEDS=1,减低更新请求优先级
  • 通过制定INSERT、UPDATE、DELERE语句的LOW_PRIORITY属性,降低语句优先级
  • MySQL提供了一种折中的办法来调节读写冲突,即给系统参数max_write_lock_count设置一个合适的值,当一个表的读锁等待数达到这个值,MySQL将暂时将写请求优先级降级

 

InnoDB锁问题

InnoDB行锁争用情况可以通过检查InnoDB_row_lock状态变量来分析系统上的行锁的争夺情况:

show status like 'innodb_row_lock%'

InnoDB实现了以下类型的行锁:

  • 共享锁(S)
  • 排它锁(X)
  • 意向共享锁(IS):事务打算给数据行加行共享锁时,必须先取得该表的IS锁。
  • 意向排它锁(IX):事务打算给数据行加行排它锁时,必须先取得该表的IX锁。

意向锁是为了在行级锁基础上添加对表级锁的支持提出的。

意向锁是InnoDB自动加的,不需要用户干预。

事务可以通过以下语句显示给记录集加共享锁或排它锁。

  • 共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE
  • 排它锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE

 

 

InnoDB行锁实现方式

InnoDB行锁是通过给索引项加锁来实现的,如果没有索引,InnoDB将通过隐藏的聚簇索引对记录加锁。行锁分为3中情况:

  • Record lock:对索引项加锁
  • Gap lock:对索引项之间的“间隙”、第一条记录前的“间隙”或最后一条记录后的“间隙”加锁
  • Next-key lock:前两种的组合,对记录及其前面的间隙加锁

InnoDB的锁是加在索引上的,所以如果where没有使用索引条件,就相当于使用表级锁

 

MySQL通过BINLOG记录执行成功的INSERT、UPDATE、DELETE等更新数据的SQL语句,并由此实现MySQL数据库的恢复和主从复制

© 著作权归作者所有

casoc
粉丝 48
博文 85
码字总数 60735
作品 0
成都
程序员
私信 提问
MySQL中的共享锁与排他锁

在MySQL中的行级锁,表级锁,页级锁中介绍过,行级锁是Mysql中锁定粒度最细的一种锁,行级锁能大大减少数据库操作的冲突。行级锁分为共享锁和排他锁两种,本文将详细介绍共享锁及排他锁的概念、...

steven
2016/09/23
67
0
MySQL中的行级锁,表级锁,页级锁

在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足。 在数据库的锁机制中介绍过,在DBMS中,可以按照锁的粒度把数据库锁分为行级...

Hosee
2016/06/01
702
0
MySQL数据库的锁机制

在并发访问情况下,很有可能出现不可重复读等等读现象。为了更好的应对高并发,封锁、时间戳、乐观并发控制(乐观锁)、悲观并发控制(悲观锁)都是并发控制采用的主要技术方式。 锁分类 ①、按操...

Javahih
2018/01/02
0
0
MySQL MVCC && 事务隔离级别 && 锁

MySQL MVCC && 事务隔离级别 && 锁 InnoDB多版本并发控制——MVCC http://my.oschina.net/xinxingegeya/blog/208821 MySQLS锁X锁read lockwrite lock http://my.oschina.net/xinxingegeya/bl......

秋风醉了
2014/07/30
583
0
Mysql InnoDB行锁实现方式

mysql中InnoDB存储引擎的行锁和表锁 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味...

mickelfeng
01/18
34
0

没有更多内容

加载失败,请刷新页面

加载更多

可能是国内第一篇全面解读 Java 现状及趋势的文章

作者 | 张晓楠 Dragonwell JDK 最新版本 8.1.1-GA 发布,包括全新特性和更新! 导读:InfoQ 发布《2019 中国 Java 发展趋势报告》,反映 Java 在中国发展的独特性,同时也希望大家对 Java 有...

阿里云官方博客
1分钟前
0
0
Spring Boot 2.x基础教程:Swagger静态文档的生成

前言 通过之前的两篇关于Swagger入门以及具体使用细节的介绍之后,我们已经能够轻松地为Spring MVC的Web项目自动构建出API文档了。如果您还不熟悉这块,可以先阅读: Spring Boot 2.x基础教程...

程序猿DD
5分钟前
0
0
《毅力》读书笔记

1.确信你全身心地投入 2.准备好为目标进行艰难的跋涉 3.通过减少需要使用毅力的情形,为将来的挑战做好准备 4.尽可能具体细致地确定你的目标和实现目标的过程 5.把挑战分解为小而易于管理的小...

lingch
6分钟前
1
0
zk中快速选举FastLeaderElection实现

选举涉及概念 服务器状态 投票 如何选择投票? 协议 选举 如何进行选举? epoch 发送者 接收者 发送队列 接收队列 服务器状态 public enum ServerState { LOOKING,寻找Leader状态,当服务处于...

writeademo
9分钟前
0
0
教你玩转Linux—磁盘管理

Linux磁盘管理好坏直接关系到整个系统的性能问题,Linux磁盘管理常用三个命令为df、du和fdisk。 df df命令参数功能:检查文件系统的磁盘空间占用情况。可以利用该命令来获取硬盘被占用了多少...

Linux就该这么学
11分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部