Postgres中的ResourceOwner对象简介
ResourceOwner对象
为简化查询相关资源的管理(如pin和表级锁等),PG中引入了ResourceOwner对象 的概念。这些与查询相关的资源必须以某种可靠的方式被跟踪,以确保当查询结束后 被释放,甚至是查询由于错误被中止时资源被释放。相对于期望整个执行过程拥有牢 不可破的数据结构,PG更愿意采用单例模式去跟踪这些资源。 ResourceOwner的API建立在MemoryContext API之上,MemoryContext API已经 被证明是十分灵活的,并且在防止内存泄漏上十分有效。另外,ResourceOwner可以 有子对象(child ResourceOwner),可以形成对象树,当释放父对象(parent ResourceOwner)时,所有直接和间接的子节点都将被释放。 象,但他们的使用方式差异很大,实际上并没有多大好处。) 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 一览 * 创建ResourceOwner 锁被特殊处理,因为在非错误情况下,无论是在子事务中或是Portal申请的锁, 锁的持有会直到事务结束。因此,当isCommit为true时,在子对象(child ResourceOwner中的释放操作锁操作会将锁的所有权(lock ownership)传递给父对象 ,而不是真的释放掉锁。 tupdesc引用等的属主关系维护,其它对象可通过记录所属ResourceOwner的指针与 ResourceOwner进行关联。在其它模块中有这样一个API,当ResourceOwner释放时会 得到控制权(get control),来扫描自己的数据以发现需要被删除的对象。 当unpin缓冲区、释放锁秋或cache引用时,当前CurrentResourceOwner必须指向 它们申请时相同的ResourceOwner。通过额外的记录可以放松这个限制,但目前来看 没有这个必要。 代码中,若有CurrentResourceOwner的暂时变化,应使用PG_TRY结构,以确保当 出现错误退出时,前一CurrentResourceOwner能正确恢复。 原文见postgresql源码中resowner目录的readme (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |