PostgreSQL V9.6 LWLock实现分析(六)

时间:2023-02-05 05:56:26

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;

}