mysql innodb读写锁_Mysql存储引擎Innodb的读写锁、行级锁-Go语言中文社区

读写锁

Mysql存储引擎Innodb在处理并发读或者写的时候,通过两种类型的锁来解决并发问题,这两种锁通常称为共享锁和排他锁,也叫读锁和写锁。

读锁是共享的,即多个客户端可以同时读取同一资源。

写锁是排他的,也就是说写锁会阻塞其他的写锁和读锁。

举个例子:

客户端A读取操作不需要等待客户端B读取完成并释放锁。但客户端A进行写操作的时候,会阻塞其他客户端的读和写操作,直到客户端A写操作完成并释放锁,其他客户端才可以进行读写。

71635c0c86d5de75db7b975b40b02f1a.png

上面说了这么多,但实际上当客户端A更新某行记录的同时,客户端B任然可读取到数据,不会被阻塞,这是为什么呢?

先来了解两个东西,Redo Log(重做日志)和Undo Log(回滚日志)

redo log通常是物理日志,记录的是数据页的物理修改,它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)。

undo用来回滚行记录到某个版本。undo log一般是逻辑日志,根据每行记录进行记录。

如果看不懂,就这样理解:当发生写操作时,Innodb会把旧数据存储到Undo Log(回滚日志)中,新数据写到Redo Log(重做日志)中。

当客户端A更新某行记录的同时,客户端B会被写锁阻塞,这时,客户端B会去Undo Log中读取旧数据。

下面来实践下。

CREATE TABLE `test001` (

`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,

`first_name` char(50) DEFAULT NULL,

`last_name` char(50) DEFAULT NULL,

PRIMARY KEY (`id`) USING BTREE

) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `test001`(`id`, `first_name`, `last_name`) VALUES (1, 'fn001', 'ln001');

INSERT INTO `test001`(`id`, `first_name`, `last_name`) VALUES (2, 'fn002', 'ln002');

INSERT INTO `test001`(`id`, `first_name`, `last_name`) VALUES (3, 'fn003', 'ln003');

在一个终端执行

BEGIN;

UPDATE test001 SET first_name='update_name' WHERE last_name='ln001';

另一个终端执行

SELECT * FROM `test001` WHERE last_name='ln001';

查询依旧可以获取数据

439e9bd592ac712f8656577bd697fb05.png

ps:试验完成后,记得commit或者rollback结束事物。

行级锁

Innodb使用行级锁,然而这并不意味着Innodb只会锁住被修改的行。请看下面的操作。

在一个终端连接中执行

BEGIN;

UPDATE test001 SET first_name='update_name' WHERE last_name='ln001';

在另一个终端连接中执行

BEGIN;

UPDATE test001 SET first_name='update_name2222' WHERE last_name='ln002';

f9819a93bfdff0d868ced67d5c3f012f.png

第二条SQL被阻塞超时,即更新操作不仅仅锁住了 last_name='ln001'的行,还锁住了其他行。在这个例子中,实际上锁住了整张表。

回滚上面的事物再进行下面的操作。运行  rollback

那为什么说Innodb实现了行级锁呢?我们来给last_name行加一个索引。

a3157d136bbfb940920faafc6fc9d829.png

再次执行刚才的语句

665f914c5f949dfabfbac1edbac5fbb1.png

可以看到两条更新语句互不干扰,由此可知Innodb通过索引,筛选出了last_name='ln001'的数据行,然后仅对last_name='ln001'的数据行加了锁,其他数据行不会被锁住,所以此时可以更新last_name='ln002'的数据行。

没加索引前,Innodb就没法通过索引筛选出指定的数据行,只能锁住整张表了。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值