ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

mysql 性能优化(七)锁机制

2021-07-01 21:33:48  阅读:168  来源: 互联网

标签:加锁 行锁 性能 Table 会话 MyISAM mysql 操作 优化


1、锁介绍

解决因资源共享,而造成的并发问题。
例如:例如:电商A,B两人同时购买最后一件商品
A:仅快0.0001秒抢到的->加锁->处理业务逻辑->释放锁
B:在B获取到商品时,商品已加锁,等待所释放,商品状态已发生改变,已售空。

  • 分类:
    • 操作类型:
      • 读锁(共享锁):对同一个数据,可以同时进行多个读操作,互不干扰
      • 写锁(互斥锁): 如果当前写操作没有完成(未释放锁),则无法进行其他的读操作和写操作
    • 操作范围:
      • 行锁:一次性对一行加锁,如InnoDB存储引擎,开销大,加锁慢,容易出现死锁,锁的范围较小,不容易发生锁冲突,并发度高(很少发生,脏读、幻读、不可重复读、丢失更新)
      • 表锁:一次性对一个表加锁,如MyISAM存储引擎,开销小,加锁快,无死锁,容易生锁冲突,并发度低
      • 页锁(基本不用)

1.1、MyISAM表锁

  • 查看锁

    1代表加了锁
    show open tables;

  • 增加锁

    locak table 表1 read/write ,表2 read/write…可以加多个

  • 释放锁

    unlocak tables;
    也可以通过事物解锁,ROLLBACK / COMMIT

  • 查看表状态

    SHOW STATUS LIKE ‘table%’;

    • Table_locks_immediate:可以获取到的表锁数
    • Table_locks_waited:需要等待的表锁数,值越大说明锁竞争越大
    • Table_open_cache_hits:表缓存命中的次数
    • Table_open_cache_misses:高速缓存大小
    • Table_open_cache_overflows:超过了table_open_cache的设置,则会进行淘汰,淘汰的值记录到Table_open_cache_overflows

一般建议:Table_locks_immediate / Table_locks_waited > 5000采用InnoDb,否则采用MyISAM

1.1.1、加读锁

例如:会话0给A表增加了读锁

  • 当前会话
    • 如果给A表加了读操作,则当前会话只能对A表进行读操作
  • 其他会话
    • 可以对其他表进行读写操作
    • 可以对A表进行读操作,写操作需要等待会话0释放锁后才会执行

1.1.2、加写锁

例如:会话0给A表增加了写锁

  • 当前会话
    • 可以对当前表进行任何操作;
    • 不能操作其他表
  • 其他会话
    • 需要等待会话0释放锁后,才能进行增删改查操作

mysql表级锁的锁模式

MyISAM

  • 执行查询语句(select)前,会自动给涉及的所有表加读锁。
  • 执行更新操作(DML)前,会自动给涉及的表加写锁。

所以对MyISAM表操作会有一下几种情况

  • 对MyISAM表的读操作(加读锁)
    • 不会阻塞其他进程读(会话)对同一个表的读操作
    • 会阻塞对同一个表的写操作,只有读锁释放后才会执行其他会话写操作。
  • 对MyISAM表的写操作(加写锁)
    • 会阻塞其他进程(会话)对同一个表读写操作,写锁释放后才会执行其他会话读写操作。

2.1、行锁(InnoDB)

如果会话X对某条数据a进行DML操作

  • 其他会话需要等待会话A结束事物后,才能对a数据 进行操作
  • 行锁是通过事物来解锁的
  • 行锁一次锁一行数据,操作不同行数据互不干扰

注意

  • 如果没有索引或索引失效,则行锁转为表锁

2.1.1、间隙锁

行锁的一种特殊情况:值在范围内,但却不存在

例如:一个表a中,ID有1、2、3、4、6、7,这些条数据,但是没有id等于5的

update a set name =‘name’ where id >1 and id< 7

在where中没有id等于5的数据,所以 id =5的数据称之为间隙

mysql会自动给间隙加锁 所以示例中会自动给id=5的数据加间隙锁(行锁)

如果有where 则加锁的范围就是where后面的范围,不是实际的值

  • 总结:
    InnoDB默认采用行锁;
    缺点:比表锁性能损耗大
    有点:并发能力强,效率高
    建议:高并发采用InnoDB,否则采用MyISAM
  • 分析

    show status like’%innodb_row_lock%’

    Innodb_row_lock_current_waits:当前正在等待锁的数量
    Innodb_row_lock_time:等待锁的总时长,从系统启动到现在一共等待(锁定)的时间
    Innodb_row_lock_time_avg:等待锁的总时长,从系统启动到现在平均等待时长
    Innodb_row_lock_time_max:等待锁的总时长,从系统启动到现在最大等待时长
    Innodb_row_lock_waits:等待锁的总时长,从系统启动到现在一共等待的次数

2.1.2、查询数据加锁

set autocommit=0;

set transaction;

begin;

学习时可以关闭自动提交后进行测试;

查询数据时是否可以加锁?

  • 查询语句后增加for update

select * from tableName where id =1 for update;

标签:加锁,行锁,性能,Table,会话,MyISAM,mysql,操作,优化
来源: https://blog.csdn.net/Extraordinarylife/article/details/118380334

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有