LWLock锁的创建
LWLock用于系统级共享资源的*操作,在系统的运行期间,系统级的资源需要加锁,实施操作后,被释放,如缓存区*的相关操作即如此。所以LWLock锁需要在整个数据库Server启动期间完成LWLock的准备工作,即被创建好然后再被使用(加锁或解锁)。CreateLWLocks()函数完成共享内存中预留锁的空间的工作,调用InitializeLWLocks()完成锁的初始化工作。
/*
* Allocateshmem space for the main LWLock array and all tranches and
* initializeit. We also register all the LWLocktranches here.
*/
void
CreateLWLocks(void) //在共享内存中创建所有的系统级LWLock
{...
if(!IsUnderPostmaster)
{
Size spaceLocks= LWLockShmemSize(); //可以求知LWLock锁需要的空间大小,从中可以分析出有多少种系统级LWLock,详情如下
...
ptr =(char *) ShmemAlloc(spaceLocks);//在共享内存中分配空间
...
MainLWLockArray = (LWLockPadded *)ptr; //记录地址
...
/*Initialize all LWLocks */
InitializeLWLocks(); //在共享内存中分配了空间给系统级的LWLock后,对他们进行初始化
}
/*Register all LWLock tranches */
RegisterLWLockTranches(); //注册即加载已经所有的系统级的LWLock(如"main"、"buffer_mapping"、"lock_manager"、"predicate_lock_manager")
}
CreateLWLocks()调用LWLockShmemSize()求锁使用的空间大小。
Size
LWLockShmemSize(void)
{...
int numLocks = NUM_FIXED_LWLOCKS; //PostgreSQL提供的固定的LWLock个数
numLocks+= NumLWLocksByNamedTranches();//获得“a group of related lightweight locks”的个数(也是预定义好的LWLock)
/* Spacefor the LWLock array. */
size =mul_size(numLocks, sizeof(LWLockPadded));//取2个参数的乘积,每个LWlock的结构体是LWLockPadded定义的,在LWLock上又封装一层
/* Spacefor dynamic allocation counter, plus room for alignment. */
size =add_size(size, sizeof(int) + LWLOCK_PADDED_SIZE);
/* spacefor named tranches. */ //获得“a specific named lightweight lock”的个数(也是预定义好的LWLock)
size =add_size(size, mul_size(NamedLWLockTrancheRequests, sizeof(NamedLWLockTranche)));
/* spacefor name of each tranche. */
for (i =0; i < NamedLWLockTrancheRequests;i++) //NamedLWLockTrancheRequests个
size = add_size(size,strlen(NamedLWLockTrancheRequestArray[i].tranche_name) + 1);
...
returnsize;
}