Mysql锁相关

锁类型/引擎 行锁 表锁 页锁
MyISAM
InnoDB
BDB(被InnoDB取代)

锁的分类

  • 表锁:开销小,加锁快,不会死锁,粒度大,冲突率高,并发低。
  • 行锁:开销大,加锁慢,会死锁,粒度小,冲突率低,并发高。
  • 页锁:处于表锁和行锁之间,会死锁。

锁的适用场景

  • 表锁:更适用于查询为主,按少量索引条件更新。
  • 行锁:更适用于大量按索引并发更新少量不同数据,同时又有并发查询。

MyISAM表锁

  • 查看锁争用相关参数:show status like 'table%';
  • Table_locks_waited的值越高表示表锁争用越高。
  • MyISAM表的读操作,会阻塞同表的其他读请求,会阻塞同表写请求;
  • 写操作会阻塞同表的读请求和写请求。
  • 读与写、写与写之间串行,持锁线程可对表更新,其他线程读/写都会等待,直到锁释放。

MyISAM写阻塞读的例子

session 1 session 2
lock table user write;
select * from user; //返回查询结果 select * from user; //被阻塞,等待锁被释放
unlock tables; 获得锁,返回查询结果
注:
  1. lock tables时,要一次性锁定用到的所有表
  2. 对别名也需要锁定,如:lock table user as a read, user as b read;

MyISAM读阻塞写例子

session 1 session 2
lock table user read;
可查询:select * from user; 可查询:select * from user;
不能查询未锁定的表:select * from goods; //Table 'goods' was not locked with Lock Tables 能查询/更新未锁定的表
当前session更新锁定表会报错,Read Lock 更新锁定表会等待
Unlock tables; 获得锁,更新完成

MyISAM并发插入

系统变量 concurrent_insert:用于控制并发插入行为

  • 0 不允许并发插入
  • 1 表中没有被删除的行(即没有空洞),则允许一个进程读,另一个进程在表尾插入(默认设置)
  • 2 表中不论是否存在空洞,都允许在表尾并发插入

MyISAM读写并发

session 1 session 2
lock table user read local;
当前session无法对该表更新或插入 可以插入,但更新需要等待锁释放
无法访问其他session插入的数据
unlock tables; 获得锁,更新完成
可以查到其他session插入的数据
注:
  • 利用并发插入可以解决应用对同一个表查询和插入的锁争用;
  • 将cocurrent_insert设置为2,定期OPTIMIZE TABLE来整理空间碎片,回收删除记录产生的空洞。

MyISAM锁调度

  1. 读锁与写锁互斥;
  2. 读操作与写操作串行;
  3. 写进程先获得锁,即使读请求先到队列,也会被写请求插队,因为mysql认为写比读要重要(因此MyISAM不适合有大量更新/插入操作)。

调节MyISAM锁调度行为

  • low-priority-updates,给予读优先权利;
  • SET LOW-PRIORITY_UPDATES=1,降低更新请求优先级;
  • 指定INSERT、UPDATE、DELETE的LOW-PRIORITY属性,降低该语句优先级。

解决读写冲突的方法:

  • 系统参数 max_write_lock_count 设置合理值,表的读锁达到设定阈值后,mysql就将写请求优先级降低。
  • 一些需要长时间运行的读操作,需要拆分为多条短select sql,复杂查询放在数据库空闲时段进行,比如夜间执行。

InnoDB与MyISAM最大区别:

  1. 支持事务;
  2. 行级锁。

事务 - Transaction

事务操作 描述
BEGIN 或者 START TRANSACTION 开始事务
COMMIT 提交事务
ROLLBACK 回滚结束事务,撤销进行中的所有未提交的修改
SAVEPOINT identifier 设置保存点
RELEASE SAVEPOINT identifier 事务回滚到保存点
ROLLBACK TO identifier 撤销保存点
SET TRANSACTION = {READ UNCOMMITED,READ COMMITED,REPEATABLE READ,SERIALIZABLE} 设置事务隔离级别
SET AUTOCOMMIT = {0,1} 禁止/开启自动提交

事务的特性

  • A - Atomicity 原子性:全执行/全不执行
  • C - Consistent 一致性:数据状态一致
  • I - Isolation 隔离性:事务处理过程中的中间状态对外不可见,不受外部并发操作影响
  • D - Durable 持久性:事务完成后对数据修改是永久性的
并发事务问题 描述 解决方案
更新丢失 两个事务对同一行数据修改,先提交的被后提交的覆盖 应用程序对要更新的数据加锁
脏读 A事务改一行数据,B事务读到了A的改动“脏”数据,A回滚则B的数据有问题 数据库事务隔离,解决读一致性问题:1、读之前加锁,防止其他事务对数据修改;2、不加锁,生成快照,多版本并发控制
不可重复读 一个事务多次读取同一数据发现被改变/删除 同上
幻读 一个事务按先前的条件查询,发现其他事务插入了满足条件的新数据 同上
注:

事务隔离级别越高,并发副作用越小,代价越高,因为事务隔离从某种程度上说使得事务串行化。

MySQL事务隔离级别

隔离级别/并发问题 读一致性 脏读 不可重复读 幻读
未提交读 最低
已提交读 语句级
可重复读 事务级
可序列化 最高

获取InnoDB行锁争用情况

  • show status like 'innodb_row_lock%';
  • 锁争用严重时,InnoDB_row_lock_waits和InnoDB_row_lock_time_avg值较大。

InnoDB行锁类型

行锁类型 描述
共享锁 S 允许事务读一行,阻止其他事务获得排他锁
排他锁 X 允许事务更新数据,阻止其他事务获得共享读锁和排他写锁
意向共享锁 IS 事务打算给行加共享锁,先取得表IS锁
意向排他锁 IX 事务打算给行加排他锁,先取得表IX锁
请求锁模式是否兼容当前锁模式 X IX S IS
X
IX
S
IS
注:
  • 含I的锁与含I的锁兼容;
  • 单X与任何锁不兼容;
  • 单S与含X的锁不兼容;
  • 若一个事务请求的锁模式与当前的锁兼容,InnoDB将请求的锁授予该事务,不兼容就要等到锁释放;
  • 意向锁是InnoDB自动加的,DELETE、UPDATE、INSERT,InnoDB会自动加X锁,普通SELECT,InnoDB不加任何锁。

手动加锁的方法

  • 共享锁(S):SELECT * FROM user LOCK IN SHARE MODE;
  • 排他锁(X):SELECT * FROM user FOR UPDATE;
注:
  • SELECT * FROM ... LOCK IN SHARE MODE; //若当前事务加了读锁,进行更新会死锁
  • SELECT * FROM ... FOR UPDATE; //一个事务加了写锁,其他事务加锁操作需要等待
  • InnoDB行锁是通过给索引上的索引项加锁来实现的,只有通过索引条件检索,才会使用行级锁,否则会用表锁;
  • 分析锁冲突时,检查SQL执行计划(利用explain),以确认是否真正走了索引,例如:SELECT * FROM user WHERE name = 123; //name字段是varchar类型且有索引,但条件中用了int型,类型能自动转换,但会进行全表扫描。

间隙锁(Next-key Lock)

概念描述

用范围而非等值搜索数据,并且请求共享/排他锁时,InnoDB会对所有符合条件的已有记录的索引项加锁,对键值在范围内但不存在的记录,即GAP-间隙,也会加锁。

例如:
  • user表,id从1~100共100个,执行:
  • SET AUTOCOMMIT = 0;
  • SELECT * FROM id > 99 FOR UPDATE;
  • 会对id等于100的记录的索引项加锁,对id大于99的间隙加锁。
作用:
  1. 满足隔离级别要求,防止幻读;
  2. 满足恢复和复制需要(MySQL通过BINLOG录入执行成功的INSERT、UPDATE、DELETE等更新语句)
存在的问题:

按范围加锁机制会阻塞符合条件范围内的键值并发插入,造成锁等待。

解决方法:

优化业务逻辑,尽量用相等条件来检索数据。

注:
相等条件检索一个不存在记录加锁时,InnoDB也会使用间隙锁。例如:

  • 对上面的user表,执行:
  • SET AUTOCOMMIT = 0;
  • SELECT * FROM id = 101 FOR UPDATE;
  • 再在另一个 MySQL Session 中执行 INSERT INTO user (id, name, password, description)
    VALUES
    (101, 'clive', '123456', 'psw'); //查询被阻塞,进入等待直至锁释放

死锁的概念

死锁是指多个事务在统一资源上,出现相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。

MyISAM和InnoDB在死锁上的区别

  • MyISAM不会出现死锁,因为MyISAM总是一次获得所需要的全部锁,要么全部满足,要么全等待;
  • InnoDB除了单SQL事务,锁是逐步获得的,因此可能出现死锁。一般InnoDB能自动检测死锁,并使一个较简单的事务回退并释放锁,另一个事务获得锁,继续完成事务。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,290评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,399评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,021评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,034评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,412评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,651评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,902评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,605评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,339评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,586评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,076评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,400评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,060评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,851评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,685评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,595评论 2 270

推荐阅读更多精彩内容

  • 当一个系统访问量上来的时候,不只是数据库性能瓶颈问题了,数据库数据安全也会浮现,这时候合理使用数据库锁机制就显得异...
    初来的雨天阅读 3,499评论 0 22
  • 当一个系统访问量上来的时候,不只是数据库性能瓶颈问题了,数据库数据安全也会浮现,这时候合理使用数据库锁机制就显得异...
    JackFrost_fuzhu阅读 7,611评论 4 83
  • 一、概述 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种...
    忘忧谷主阅读 580评论 0 3
  • 你是否有过这样的经历?当别人长篇大论讲道理的时候,你其实根本不想听,只会烦躁的回应,哎呀,你说的这些我都知道啊。可...
    夏宇嫣_8335阅读 78评论 0 2
  • 9.12 完型填空再次暴露学生参差不齐的现状。到底如何讲解完型填空题呢?我都想去网上寻求答案了。娟姐的话,...
    Penny酱阅读 291评论 0 0