iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >PostgreSQL 源码解读(219)- Locks(Overview)
  • 124
分享到

PostgreSQL 源码解读(219)- Locks(Overview)

2024-04-02 19:04:59 124人浏览 薄情痞子
摘要

本节是postgresql Loc

本节是postgresql Locks的概要部分,翻译自README文件.

一、Overview


src/backend/storage/lmgr/README
Locking Overview
================
Postgres uses four types of interprocess locks:
PG使用四种类型的:
* Spinlocks.  These are intended for *very* short-term locks.  If a lock
is to be held more than a few dozen instructions, or across any sort of
kernel call (or even a call to a nontrivial subroutine), don't use a
spinlock. Spinlocks are primarily used as infrastructure for lightweight
locks. They are implemented using a hardware atomic-test-and-set
instruction, if available.  Waiting processes busy-loop until they can
get the lock. There is no provision for deadlock detection, automatic
release on error, or any other nicety.  There is a timeout if the lock
cannot be Gotten after a minute or so (which is approximately forever in
comparison to the intended lock hold time, so this is certainly an error
condition).
* Spinlocks(自旋锁).这种一种非常短期的锁.如果持有锁会超过几十个指令周期,或者
  跨越多个类型的内核调用,那么不要使用自旋锁.
  如可用的话(部分平台并不可用),Spinlocks主要用于轻量级锁的基础"设施".
  等待进程会一直等待直至获取到锁(等待1分钟则超时).没有提供死锁检测/错误时自动释放.
* Lightweight locks (LWLocks).  These locks are typically used to
interlock access to datastructures in shared memory.  LWLocks support
both exclusive and shared lock modes (for read/write and read-only
access to a shared object). There is no provision for deadlock
detection, but the LWLock manager will automatically release held
LWLocks during elog() recovery, so it is safe to raise an error while
holding LWLocks.  Obtaining or releasing an LWLock is quite fast (a few
dozen instructions) when there is no contention for the lock.  When a
process has to wait for an LWLock, it blocks on a SysV semaphore so as
to not consume CPU time.  Waiting processes will be granted the lock in
arrival order.  There is no timeout.
* Lightweight locks (轻量级锁,LWLocks).这些锁典型的用于保护共享内存中的数据结构.
  LWLocks提供了共享和独占模式,没有提供死锁检测,但在elog()恢复期间自动释放持有的锁,
  因此在持有轻量级锁时抛出异常是安全的.
  没有冲突的情况下,获取或者释放轻量级锁是相当快的(几十个指令周期).
  如进程从必须等到LWLock,则会阻塞等待SysV信号量,这样可以不需要耗费CPU时间.
  等待进程按到达顺序授予锁.LWLocks没有超时机制.
* Regular locks (a/k/a heavyweight locks).  The regular lock manager
supports a variety of lock modes with table-driven semantics, and it has
full deadlock detection and automatic release at transaction end.
Regular locks should be used for all user-driven lock requests.
* Regular locks (重量级锁,a/k/a heavyweight locks). 
  常规的锁管理支持多种表驱动语义上的锁模式,有完善的死锁检测机制并在事务结束时自动释放锁.
  常规锁应在所有用户驱动的锁请求中使用.
* SIReadLock predicate locks.  See separate README-SSI file for details.
* SIReadLock predicate locks(SIReadLock谓词锁).详情参见README-SSI.
Acquisition of either a spinlock or a lightweight lock causes query
cancel and die() interrupts to be held off until all such locks are
released. No such restriction exists for regular locks, however.  Also
note that we can accept query cancel and die() interrupts while waiting
for a regular lock, but we will not accept them while waiting for
spinlocks or LW locks. It is therefore not a good idea to use LW locks
when the wait time might exceed a few seconds.
自旋锁/轻量级锁都会导致取消查询和die()中断被延迟,直至释放锁.
对于常规锁就没有这样的限制.
同时,要注意在等待常规锁时可以接受取消查询和die()中断,但在等待自旋锁/轻量级锁时则不接受.
如果等待时间超过几十秒,使用LWLocks并不是明智的选择.
The rest of this README file discusses the regular lock manager in detail.
Lock Data Structures
--------------------
Lock数据结构
Lock methods describe the overall locking behavior.  Currently there are
two lock methods: DEFAULT and USER.
锁定方法描述了锁定动作的概览.目前有两种锁定方法:DEFAULT和USER.
Lock modes describe the type of the lock (read/write or shared/exclusive).
In principle, each lock method can have its own set of lock modes with
different conflict rules, but currently DEFAULT and USER methods use
identical lock mode sets. See src/include/storage/lock.h for more details.
(Lock modes are also called lock types in some places in the code and
documentation.)
锁定模式描述了lock(R/W或共享/独占)的类型.
原则上,每一种锁方法可以有自己的锁模式集合和不同的冲突原则,但当前的DEFAULT/USER方法
会使用相同的锁模式集合,详情参见src/include/storage/lock.h
(锁模式在代码和文档中的某些地方也被称为锁类型)
There are two main methods for recording locks in shared memory.  The primary
mechanism uses two main structures: the per-lockable-object LOCK struct, and
the per-lock-and-requestor PROCLOCK struct.  A LOCK object exists for each
lockable object that currently has locks held or requested on it.  A PROCLOCK
struct exists for each backend that is holding or requesting lock(s) on each
LOCK object.
在共享内存中保存锁信息有两种主要的方法.其中一种主要的机制使用两种结构体:
LOCK:每一个锁定对象一个,per-lockable-object.存储每一个锁定的对象(持有锁或者等待锁).
PROCLOCK:每一个锁和请求者一个,per-lock-and-requestor.存储每一个持有/请求LOCK对象的后端进程.
There is also a special "fast path" mechanism which backends may use to
record a limited number of locks with very specific characteristics: they must
use the DEFAULT lockmethod; they must represent a lock on a database relation
(not a shared relation), they must be a "weak" lock which is unlikely to
conflict (AccessshareLock, RowShareLock, or RowExclusiveLock); and the system
must be able to quickly verify that no conflicting locks could possibly be
present.  See "Fast Path Locking", below, for more details.
另外,还有一种成为"fast path"的机制,后台进程可使用非常规特性的用于记录有限数量的锁,
这种情况下必须使用DEFAULT锁方法.它们必须表示数据库关系(非共享关系)上的锁,
它们必须是一个不太可能出现冲突的"弱"锁(AccessShareLock, RowShareLock, or RowExclusiveLock);
系统必须能够快速的验证冲突锁有没有可能出现.详细参见下面的"Fast Path Locking".
Each backend also maintains an unshared LOCALLOCK structure for each lockable
object and lock mode that it is currently holding or requesting.  The shared
lock structures only allow a single lock grant to be made per lockable
object/lock mode/backend.  Internally to a backend, however, the same lock may
be requested and perhaps released multiple times in a transaction, and it can
also be held both transactionally and session-wide.  The internal request
counts are held in LOCALLOCK so that the shared data structures need not be
accessed to alter them.
每一个后台进程同时会维护非共享的LOCALLOCK结构体,该结构体存储锁定对象和当前持有/请求的锁模式.
共享锁结构体只允许为每个锁定对象/锁模式/后台进程授予一个锁.
但是,在后台进程内部,同一个锁可能在同一个事务中请求和释放多次,并且可以事务/会话模式持有.
内部请求的计数在LOCALLOCK结构体中存储以便共享数据结构体在更新时不需要访问.

LOCK




typedef struct LOCK
{
    
    LOCKTAG     tag;            
    
    LOCKMASK    grantMask;      
    LOCKMASK    waitMask;       
    SHM_QUEUE   procLocks;      
    PROC_QUEUE  waitProcs;      
    int         requested[MAX_LOCKMODES];   
    int         nRequested;     
    int         granted[MAX_LOCKMODES]; 
    int         nGranted;       
} LOCK;
#define LOCK_LOCKMETHOD(lock) ((LOCKMETHODID) (lock).tag.locktag_lockmethodid)

PROCLOCK




typedef struct PROCLOCKTAG
{
    
    LOCK       *myLock;         
    PGPROC     *myProc;         
} PROCLOCKTAG;
typedef struct PROCLOCK
{
    
    PROCLOCKTAG tag;            
    
    PGPROC     *groupLeader;    
    LOCKMASK    holdMask;       
    LOCKMASK    releaseMask;    
    SHM_QUEUE   lockLink;       
    SHM_QUEUE   procLink;       
} PROCLOCK;
#define PROCLOCK_LOCKMETHOD(proclock) \
    LOCK_LOCKMETHOD(*((proclock).tag.myLock))

LOCALLOCK




typedef struct LOCALLOCKTAG
{
    LOCKTAG     lock;           
    LOCKMODE    mode;           
} LOCALLOCKTAG;
typedef struct LOCALLOCKOWNER
{
    
    struct ResourceOwnerData *owner;
    int64       nLocks;         
} LOCALLOCKOWNER;
typedef struct LOCALLOCK
{
    
    LOCALLOCKTAG tag;           
    
    uint32      hashcode;       
    LOCK       *lock;           
    PROCLOCK   *proclock;       
    int64       nLocks;         
    int         numLockOwners;  
    int         maxLockOwners;  
    LOCALLOCKOWNER *lockOwners; 
    bool        holdsStrongLockCount;   
    bool        lockCleared;    
} LOCALLOCK;
#define LOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.locktag_lockmethodid)

二、参考资料

README

您可能感兴趣的文档:

--结束END--

本文标题: PostgreSQL 源码解读(219)- Locks(Overview)

本文链接: https://www.lsjlt.com/news/48730.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作