欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MySql-锁

程序员文章站 2024-03-24 08:24:10
...

数据库锁

  • 表锁
  • 行锁
  • 间隙锁

锁是计算机协调多个进程或线程并发访问某一资源的机制

表锁

偏向myisam存储引擎,开销小,加锁快,锁定粒度大,发送锁冲突的概率最高,并发度低。

-- 创建表
create table lock_text(
    id int not null primary key auto_increment,
    name varchar(20)
)engine myisam;

--插入数据
insert into lock_text(name) values('a'),('b'),('c'),('d'),('e');

-- 手动加锁
lock table lock_text read;

-- 释放锁
unlock tables;

MyISAM会自动执行表的加锁,解锁操作,一般不需要手动加锁

  • 对MyISAM表的读操作(读锁),不会阻塞其他进程对同一表的读取请求,但会阻塞同一表的写请求,只有当锁释放后,才能执行其他写操作
  • 对MyISAM表的写操作(写锁),会阻塞其他进程对同一表的读写操作,直到锁释放,才能执行其他读写操作

行锁

innodb引擎有行锁和表锁,行锁开销大,加锁慢,会出现死锁。锁定力度小,发生锁冲突的概率最低,并发度也高。

-- 创建锁测试表
create table lock_text(
    a tinyint(3),
    b varchar(3)
)engine=innodb charset=utf8;

-- 插入数据
insert into lock_text values(1,'b2'),
(3,'san'),(4,'两个二'),(5,'嘤嘤嘤');

-- 建索引
create index idx_name on lock_text(name);

-- 分析行锁
show status like 'innodb_row_lock%';
mysql> show status like 'innodb_row_lock%';
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| Innodb_row_lock_current_waits | 0     |
| Innodb_row_lock_time          | 34481 |
| Innodb_row_lock_time_avg      | 17240 |
| Innodb_row_lock_time_max      | 27045 |
| Innodb_row_lock_waits         | 2     |
+-------------------------------+-------+
5 rows in set (0.00 sec)

MySql-锁

锁定一行

select * from lock_text where a=1 for update;
variable_name translate
Innodb_row_lock_current_waits 当前正在等待锁定的数量
*Innodb_row_lock_time 从系统启动到现在锁定的总时间长度
*Innodb_row_lock_time_avg 每次等待所花费平均时间
Innodb_row_lock_time_max 从系统启动到现在等待最长的一次花费的时间
*Innodb_row_lock_waits 系统启动后到现在总共等待的次数

间隙锁

当我们用范围条件而不是常量条件索引数据,并请求共享锁(读锁)或排它锁时(写锁),innodb会给复活条件的已有数据记录的索引项加锁,对于键值在条件范围内但不存在的记录,叫’间隙’,innodb会对这个间隙加锁,这种锁称为间隙锁。

间隙锁的危害

因为sql执行过程中使用范围查找时,它会锁定整个范围内所有的索引值,即使这个键值并不存在,这是一个致命弱点,在锁定范围内无法插入任何数据。

相关标签: