MySQL的”锁”

129 阅读3分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

猫和老鼠.jpg

前言: 本篇文章是我关于MySQL的第五篇文章,水平一般、能力有限。文章写的比较浅,适合新手来看。本篇主要来简单介绍MySQL中关于颗粒度控制,事务相关内容。

一。颗粒度

前文讲过了我们在处理多连接并发可能造成的安全问题时加入了锁系统的概念。按照对数据操作类型的不同,又可以分为读锁(read lock)和写锁(write lock)。

1,为什么需要细分颗粒度

但是锁出现势必会降低处理数据的性能,如何在保证安全的情况下增加并发的能力呢?😑

提供共享资源并发性的方式是让锁定的对象更有选择性。尽量只锁定需要修改的部分数据,而不是所有的资源。任何时候,只要在确保资源不冲突的情况下,锁定的资源越少,数据库的并发能力越高。 这里引入思考:无脑加锁的方式就是对的吗?

2. 加锁的影响

加锁需要消耗额外的资源。关于获得锁、检查锁状态、释放锁等对锁的操作,都会增加系统的开销。如果系统在管理锁上消耗过长的时间,对系统的性能也会有一定的影响。

二.锁策略

为了寻求性能和安全性之间的平衡,选择合适的锁管理的策略是尤为重要的。MySQL给出了多种锁策略的方案。不同的MySQL存储引擎可以选择合适的颗粒度,自定义自己的锁策略。

所以,在设计存储引擎时锁策略的设计也是其中重要的一环。对于业务场景不同需要不同的锁策略时,我们可以直接选择不同的存储引擎来解决。其中最重要的是下面的两种锁策略。

1,表锁(table lock)

表锁顾名思义就是直接锁整张表。这种锁的机制是锁开销最小的策略,也是最基础的锁策略。单个连接在对表进行写操作时,需要获得表锁。这样其他连接想要对表的所有读写操作都会等待,直到该连接进行完操作并释放锁。只有别的写锁时,其他用户才能获得读锁。

如下图所示,表正在有一个写操作。后面有两个读操作,这个时候加入一个写操作到排队中。

因为写锁比读锁的优先级更高,因此写操作有可能会被排队读操作之前。但是如果是读操作新加入队列,只能拍到队列的末尾。

image.png

注意:
虽然一般由存储引擎来管理锁策略,但是如果像修改表结构等语句执行时。存储引擎的锁策略是失效,MySQL会对该表执行表锁。

2.行锁(row lock)

行级锁可以最大程度的支持并发(但是也带来了最大程度的锁开销)。行级锁只在存储引擎中有实现,MySQL服务器层没有实现。

日常开发中出现频率比较高的InnoDB等存储引擎实现了行锁的表策略。

📡今天先写到这里,明天继续更!


本文参考资料

  • 《高性能MySQL》