2023-03-23
原文作者:一直不懂 原文地址:https://blog.csdn.net/shenchaohao12321/article/details/82798275

锁升级(Lock Escalation)是指将当前锁的粒度降低。举例来说,数据库可以把一个表的1000个行锁升级为一个页锁,或者将页锁升级为表锁。如果在数据库的设计中认为锁是一种稀有资源,而且想避免锁的开销,那数据库中会频繁出现锁升级现象。
Microsoft SQL Server数据库的设计认为锁是一种稀有的资源,在适合的时候会自动地将行、键或分页锁升级为更粗粒度的表级锁。这种升级保护了系统资源,防止系统使用太多的内存来维护锁,在一定程度上提高了效率。
即使在 Microsoft SQL Server2005版本之后, SQL Server数据库支持了行锁,但是其设计和 InnoDB存储引擎完全不同,在以下情况下依然可能发生锁升级:

  • 由一句单独的SQL语句在一个对象上持有的锁的数量超过了阈值,默认这个阈值为5000。值得注意的是,如果是不同对象,则不会发生锁升级
  • 锁资源占用的内存超过了激活内存的40%时就会发生锁升级

在 Microsoft SQL Server数据库中,由于锁是一种稀有的资源,因此锁升级会带来一定的效率提高。但是锁升级带来的一个问题却是因为锁粒度的降低而导致并发性能的降低。
InnoDB存储引擎不存在锁升级的问题。因为其不是根据每个记录来产生行锁的,相反,其根据每个事务访问的每个页对锁进行管理的,采用的是位图的方式。因此不管个事务锁住页中一个记录还是多个记录,其开销通常都是一致的。

假设一张表有3000000个数据页,每个页大约有100条记录,那么总共有300000000条记录。若有一个事务执行全表更新的SQL语句,则需要对所有记录加锁。若根据每行记录产生锁对象进行加锁,并且每个锁占用10字节,则仅对锁管理就需要差不多需要3GB的内存。而 InnoDB存储引擎根据页进行加锁,并采用位图方式,假设每个页存储的锁信息占用30个字节,则锁对象仅需90MB的内存。由此可见两者对于锁资源开销的差距之大。

阅读全文