mysql的锁机制

来源:互联网 发布:淘宝进入卖家中心 编辑:程序博客网 时间:2024/05/05 15:12

今天没事就学习一下mysql的三种锁机制的优缺点:

MySQL各存储引擎使用了三种类型(级别)的锁定机制:行级锁定,页级锁定和表级锁定。下面我们先分析一下MySQL这三种锁定的特点和各自的优劣所在。
● 行级锁定(row-level)
行级锁定最大的特点就是锁定对象的颗粒度很小,也是目前各大数据库管理软件所实现的锁定颗粒度最小的。由于锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予应用程序尽可能大的并发处理能力而提高一些需要高并发应用系统的整体性能。虽然能够在并发处理能力上面有较大的优势,但是行级锁定也因此带来了不少弊端。由于锁定资源的颗粒度很小,所以每次获取锁和释放锁需要做的事情也更多,带来的消耗自然也就更大了。此外,行级锁定也最容易发生死锁。
● 表级锁定(table-level)
和行级锁定相反,表级别的锁定是MySQL各存储引擎中最大颗粒度的锁定机制。该锁定机制最大的特点是实现逻辑非常简单,带来的系统负面影响最小。所以获取锁和释放锁的速度很快。由于表级锁一次会将整个表锁定,所以可以很好的避免困扰我们的死锁问题。当然,锁定颗粒度大所带来最大的负面影响就是出现锁定资源争用的概率也会最高,致使并大度大打折扣。
● 页级锁定(page-level)
页级锁定是MySQL 中比较独特的一种锁定级别,在其他数据库管理软件中也并不是太常见。页级锁定的特点是锁定颗粒度介于行级锁定与表级锁之间,所以获取锁定所需要的资源开销,以及所能提供的并发处理能力也同样是介于上面二者之间。另外,页级锁定和行级锁定一样,会发生死锁。

在数据库实现资源锁定的过程中,随着锁定资源颗粒度的减小,锁定相同数据量的数据所需要消耗的内存数量是越来越多的,实现算法也会越来越复杂。不过,随着锁定资源颗粒度的减小,应用程序的访问请求遇到锁等待的可能性也会随之降低,系统整体并发度也随之提升。

MySQL 的表级锁定主要分为两种类型,一种是读锁定,另一种是写锁定。在MySQL 中,主要通过四个队列来维护这两种锁定:两个存放当前正在锁定中的读和写锁定信息,另外两个存放等待中的读写锁定信息,如下:
• Current read-lock queue (lock->read)
• Pending read-lock queue (lock->read_wait)
• Current write-lock queue (lock->write)
• Pending write-lock queue (lock->write_wait)
读锁定
一个新的客户端请求在申请获取读锁定资源的时候,需要满足两个条件:
1、请求锁定的资源当前没有被写锁定;
2、写锁定等待队列(Pending write-lock queue)中没有更高优先级的写锁定等待;
如果满足了上面两个条件之后,该请求会被立即通过,并将相关的信息存入Current read-lock queue 中,而如果上面两个条件中任何一个没有满足,都会被迫进入等待队列Pending read-lock queue中等待资源的释放。

写锁定
当客户端请求写锁定的时候,MySQL 首先检查在Current write-lock queue 是否已经有锁定相同资源的信息存在。如果Current write-lock queue 没有,则再检查Pending write-lock queue,如果在Pending write-lock queue 中找到了,自己也需要进入等待队列并暂停自身线程等待锁定资源。反之,如果Pending write-lock queue 为空,则再检测Current read-lock queue,如果有锁定存在,则同样需要进入Pending write-lock queue 等待。当然,也可能遇到以下这两种特殊情况:
1. 请求锁定的类型为WRITE_DELAYED;
2. 请求锁定的类型为WRITE_CONCURRENT_INSERT 或者是TL_WRITE_ALLOW_WRITE, 同时Current read lock 是READ_NO_INSERT 的锁定类型。

当遇到这两种特殊情况的时候,写锁定会立即获得而进入Current write-lock queue 中如果刚开始第一次检测就Current write-lock queue 中已经存在了锁定相同资源的写锁定存在,那么就只能进入等待队列等待相应资源锁定的释放了。读请求和写等待队列中的写锁请求的优先级规则主要为以下规则决定:
1. 除了READ_HIGH_PRIORITY 的读锁定之外,Pending write-lock queue 中的WRITE 写锁定能够阻塞所有其他的读锁定;
2. READ_HIGH_PRIORITY 读锁定的请求能够阻塞所有Pending write-lock queue 中的写锁定;
3. 除了WRITE 写锁定之外,Pending write-lock queue 中的其他任何写锁定都比读锁定的优先级低。

写锁定出现在Current write-lock queue 之后,会阻塞除了以下情况下的所有其他锁定的请求:
1. 在某些存储引擎的允许下,可以允许一个WRITE_CONCURRENT_INSERT 写锁定请求
2. 写锁定为WRITE_ALLOW_WRITE 的时候,允许除了WRITE_ONLY 之外的所有读和写锁定请求
3. 写锁定为WRITE_ALLOW_READ 的时候,允许除了READ_NO_INSERT 之外的所有读锁定请求
4. 写锁定为WRITE_DELAYED 的时候,允许除了READ_NO_INSERT 之外的所有读锁定请求
5. 写锁定为WRITE_CONCURRENT_INSERT 的时候,允许除了READ_NO_INSERT 之外的所有读锁定请求