MySQL数据库--锁机制

本文详细介绍了MySQL数据库的锁机制,特别是行锁的分类和应用,包括读锁、写锁、表锁、行锁、间隙锁以及页锁。讨论了不同锁的粒度、加锁方式以及对并发性能的影响,强调了正确使用索引避免行锁升级为表锁的重要性。
摘要由CSDN通过智能技术生成

锁机制

锁的分类

从锁的操作类型分
读锁(共享锁)

​ 针对于同一份数据,多个读操作可以同时进行而不会互相影响

写锁(排它锁)

​ 当前写操作没有完成前,它会阻断其他写锁和读锁

从对数据操作的粒度分
表锁

偏向于Myisam存储引擎,开销小,加锁快,无思索,锁定粒度大

建表sql

create table mylock(
id int not null primary key auto_increment,
name varchar(20)) engine myisam;

insert into mylock(name) values('a');
insert into mylock(name) values('b');
insert into mylock(name) values('c');
insert into mylock(name) values('d');
insert into mylock(name) values('e');

手动加锁: lock table 表名字 read,表名字2 write;

查看锁:show open tables;

释放锁:unlock tables;

加了读锁后:多个连接可以同时读取,但是不可修改,其他表想修改该表会处于阻塞状态。锁表的连接不能读取其他表。

加了写锁后:锁表的连接,可以访问和修改被锁的表,但是不能读取其他表。其他表若想查询该表,会处于阻塞状态。若没发生阻塞就是该表从缓存中取得的数据。

简而言之:就是读表会阻塞写,但不会阻塞读,而写锁则会把写和读都堵塞

myisam 执行查询语句之前,会自动给涉及的所有表加读锁,在执行增删改操作之前,会自动给涉及的表加写锁,mysql的表级锁有两种模式:

表共享读锁

表独占写锁

Table_locks_immediate:产生表级锁定的次数,表示可以立即获取锁的查询次数,没立即获取值加一

Table_locks_waited:出现表级锁定征用而发生等待的次数(不能立即获取锁的次数,每次加一),此值高则说明存在较严重的表级锁征用情况。

MyIsam的读写锁调度是写优先,这也是它不适合做写为主表的引擎,因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,从而操作永久阻塞

行锁

偏向于innodb引擎,开销大,加锁慢,会出现死锁,锁定粒度最小,发生锁冲突的概率最低,并发度最高。和myisam最大的不同:支持事务,采用行级锁

建表sql

create table test_innodb_lock(a int(11),b varchar(16)) engine=innodb;

insert into test_innodb_lock values(1,'b2');
insert into test_innodb_lock values(2,'b3');
insert into test_innodb_lock values(3,'b5');
insert into test_innodb_lock values(4,'b58');
insert into test_innodb_lock values(5,'b45');

set autocommit=0;开启事务

如事务一对一行进行修改,事务二也对该行修改会阻塞。直到事务一提交。

索引失效导致行锁变表锁

若varchar类型不写单引号,导致索引失效会导致行锁变表锁,从而阻塞其他表对其他行的修改。在两表都提交后,索引重新排列后才ok

间隙锁

当使用范围条件时,innodb会给所有符合条件的已有数据记录的索引项加锁,对于键值在条件范围内并不存在的值称间隙,同时也加锁。

间隙锁对不存在的值也加锁,影响了插入效率,可能对性能造成极大危害。

面试题:如何锁定一行

begin;

select * from test_innodb_lock where a=8 for update

commit;

for update:锁定某一行,其他的操作会被阻塞,直到锁定行commit;

改了配置参数,应当重启重连

总结

innodb存储引擎实现了行级锁定,锁定机制带来的性能损耗更强一点,但是整体并发处理能力要更强,当系统并发量该是,就有明显的优势了。当使用不当时,有可能更差。

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:总等待次数 !

尽可能的让所有数据减速都通过所有来完成,避免无索引升级为表锁

合理设计索引,尽量缩小锁的范围

尽可能的减少检索条件,避免间隙锁

尽量控制事务大小,减少锁定资源量和时间长度

尽可能江都事务隔离级别

页锁

锁定粒度,开销和加锁时间介于两者之间,会有死锁,并发一般。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值