《HighPerformance MySQL》概译 锁的粒度
一种提高共享资源并发效率的方式是合理的规划锁的范围。仅仅锁住你要修改的部分当然比全表锁住要好。所以,我们尽可能的最小化锁的范围,因为不相干的部分,本身也互不干扰。
不过,也要考虑到,锁是消耗资源的。每种锁的操作都有消耗,例如:获得锁,检查锁是否可用,释放锁等。如果系统花了过多的资源在锁的操作上,那么并发的性能就会受到影响。
锁的策略就是在锁的消耗和数据安全之间寻求一种平衡,这种平衡会影响到性能。大部分商业数据库没有给你选择的机会,一般都采用人们所熟知的行锁,并通过内部一系列复杂的机制保持效率。
MySQL给了你选择的权力。它的存储引擎可以选择自己锁策略和粒度。因此,锁的设计对于存储引擎的实现来说是非常重要的。不同的存储引擎,可以根据不同应用场景设计出特定的高效的锁策略。下面,我们来看下两种熟知的锁策略。
表锁
MySQL中最基本的锁策略,也是消耗最低的锁。表锁跟之前提到的邮箱的锁类似,它锁住整张表。当客户端想要写表(insert,delete,updata)的时候,它获得写锁。此时所有其他的读写操作都被阻止。当没有人写的时候,读操作可以获得锁,并且不和其他的读锁互斥。
表锁针对特定的场景有很多变种,以提供更好的性能。比如,READ LOCAL 表锁,允许一些类型并发写操作。写锁比读锁有更高的优先级。也就是说,即使读请求早于写请求排在队列中,写请求也可以有先获得锁。
尽管存储引擎本身可以管理锁。MySQL自身也拥有很多表级的锁用于一些特定的场合。比如,对于ALTER Table操作,MySQL就用了表级锁,而不管你选择了何种存储引擎。
行锁
这种锁的类型提供了最好的并发效率同时也消耗最多的资源。行级锁在InnoDB和XtraDB存储引擎中提供。行级锁在存储引擎层而不是服务器实现。服务层完全不关心存储引擎层锁的实现方式,在本章后面的部分以及本书中,都将看到各种存储引擎有其自己的锁的实现方式。