Postgres中的ResourceOwner对象简介

来源:互联网 发布:js实现文字跑马灯效果 编辑:程序博客网 时间:2024/05/17 23:00
 ResourceOwner对象

    为简化查询相关资源的管理(如pin和表级锁等),PG中引入了ResourceOwner对象

的概念。这些与查询相关的资源必须以某种可靠的方式被跟踪,以确保当查询结束后

被释放,甚至是查询由于错误被中止时资源被释放。相对于期望整个执行过程拥有牢

不可破的数据结构,PG更愿意采用单例模式去跟踪这些资源。

     ResourceOwner的API建立在MemoryContext API之上,MemoryContext API已经

被证明是十分灵活的,并且在防止内存泄漏上十分有效。另外,ResourceOwner可以

有子对象(child ResourceOwner),可以形成对象树,当释放父对象(parent

ResourceOwner)时,所有直接和间接的子节点都将被释放。
   
    (看起来十分具有诱惑力,统一ResourceOwner和MemoryContext到一个统一的对

象,但他们的使用方式差异很大,实际上并没有多大好处。)

    PG中为每个事务、子事务以及每个Portal创建一个ResourceOwner。在Portal的

整个生命周期中,全局变量CurrentResourceOwner指向Portal的ResourceOwner,这

有助于类似这样的操作(如ReadBuffer、LockAcquire等)都可以记录所需的资源到这

个ResourceOwner中。

    当Portal关闭时,任何未释放的资源(典型的主要是锁)成为当前事务的责任。这

体现在将Portal的ResourceOwner变成当前事务的ResourceOwner的子对象。

resowner.c中当释放子对象时,自动传输资源给父对象。同样,子事务的

ResourceOwner也是他们直接父对象的子对象。

    PG既需要事务相关的ResourceOwner也需要Portal相关的ResourceOwner,因为事

务可能在尚未有Portal关联时进行要求资源的初始化工作(如查询分析query

parsing)。

API 一览
--------------------------------------------------
基本API:

* 创建ResourceOwner
* 资源关联或解除关联到ResourceOwner
* 释放ResourceOwner的拥有资源(释放所有拥有资源,但不包括对象自身)
* 删除ResourceOwner对象(包括子对象),所有拥有资源必须提前被释放掉

    锁被特殊处理,因为在非错误情况下,无论是在子事务中或是Portal申请的锁,

锁的持有会直到事务结束。因此,当isCommit为true时,在子对象(child

ResourceOwner中的释放操作锁操作会将锁的所有权(lock ownership)传递给父对象

,而不是真的释放掉锁。
  
    目前,ResourceOwner直接支持缓冲区pin、lgmr锁、catcache、relcache及

tupdesc引用等的属主关系维护,其它对象可通过记录所属ResourceOwner的指针与

ResourceOwner进行关联。在其它模块中有这样一个API,当ResourceOwner释放时会

得到控制权(get control),来扫描自己的数据以发现需要被删除的对象。

    当unpin缓冲区、释放锁秋或cache引用时,当前CurrentResourceOwner必须指向

它们申请时相同的ResourceOwner。通过额外的记录可以放松这个限制,但目前来看

没有这个必要。

    代码中,若有CurrentResourceOwner的暂时变化,应使用PG_TRY结构,以确保当

出现错误退出时,前一CurrentResourceOwner能正确恢复。

 

原文见postgresql源码中resowner目录的readme

原创粉丝点击