操作类型
a.读锁(共享锁)对同一个数据,多个读操作可以同时进行,互不干扰
b.写锁(互斥锁)如果当前写操作没有完毕,则无法进行其他的读操作、写操作
操作范围:
a。表锁:一次性对一张表整体加锁,MyISAM储存引擎使用表锁,开销小、加锁快,无死锁,容易发生锁冲突,并发度低
b。行锁:一次性对一条数据加锁,Innodb储存引擎,开销大、易死锁,锁范围小,不易锁冲突,并发度高
读锁:加锁语法:
lock table 表1 read/write,表2 read/write ,....
查看加锁的表:
show open tables;释放锁:unlock tables;
会话0:
lock table xxx read;
select * from xxx; -- 读,可以
delete from xxx where id =1 ;--写(增删改),不可以
select * from yyy;--读,不可以
delete from yyy where = 1;--写,可以
--如果某个会话,对A表加了read 锁,则该会话可以对A表进行读操作,不能进行写操作。且该会话不能对其他表进行读、写操作
会话1(其他会话):
select * from xxx;--读,可以
delect from xxx where id = 1;--写,会一直等待会话0将锁释放
会话1(其他会话):
select * from yyy ;--读,可以
delect from yyy where id =1;--写。可以
会话0给A表加了锁;其他会话对A表以外的表可以进行读写操作;
对A表可以读操;写操作需要等待A表释放锁
写锁:
会话0:
lock tables xxx write;
当前会话可以对加了写锁的表,进行任何操作;但是不能操作其他表;
其他会话:
对会话0中加写锁的表,可以进行增删改查的前提是:等待会话0释放写锁;
MySQL表级锁的锁模式:
MyISAM在执行查询语句前,会自动给涉及到的所有表加读锁;
在执行更新操作前,会自动给涉及的表加写锁;
所以对MyISAM表进行操作,会有以下情况:
a.对MyISAM表的读操作(加读锁),不会阻塞其他进程(会话)对同一表的读请求
但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其他进程的写操作;
b.对MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写操作;
只有当写锁释放后,才会执行其他进程的读写操作
--分析表锁定:
查看加锁的表:show open tables;
加锁的严重程度:show status like 'table%';
Table_locks_immediate:立即能获取到的锁
Table_locks_waited:需要等待的锁数(值越大,存在越大的锁竞争)
Table_locks_immediate/Table_locks_waited > 5000 ;建议Innodb,否则MyISAM
--行锁:
1.如果会话x对某条数据a进行DML操作(关闭自动commit),则其他会话必须等会话x结束事务(commit/rollback)后,才能对a进行操作;
2.表锁是通过unlock tables 释放锁;行锁是通过事务解锁;
3.操作不同数据,则互不干扰;
4.如果没有索引或索引失效,行锁会转为表锁
行锁的特殊情况:间隙锁:值在范围内,但却不存在
--若xxx表中没有id=7的数据:
updata xxx set name='xx' where id>1 and id <9;--在此where范围中,没有id=7的数据,则id=7的数据成为间隙
间隙:mysql会自动给间隙加锁-->间隙锁。id=7的数据被加了间隙锁
行锁:如果有where,则实际加锁的范围就是where后面的范围,不是时间的值
行锁分析:
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:等待次数。从系统启动到现在一共等待的次数
查询时加锁:select * from xxx for update;
感谢博主,喝杯咖啡~
还没有人发表评论