本文主要是介绍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表增加了写锁
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;
学习时可以关闭自动提交后进行测试;
查询数据时是否可以加锁?
select * from tableName where id =1 for update;
这篇关于mysql 性能优化(七)锁机制的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!