PostgreSQL关键代码段与内存上下文

原创
2020/08/17 20:53
阅读数 442

内存上下文是PG的精髓之一,没有它,内存泄漏会失控,关于这一点在为什么引入它的说明中有介绍。 本文简单说一下内存上下文与临界区(CRIT_SECTION)之间的关系。

 

1、内存上下文定义

代码在 src/include/nodes/memnodes.h

typedef struct MemoryContextData
{
...
/* allow palloc in critical section */
bool		allowInCritSection;
...
} MemoryContextData;

根据注释,是否允许在临界区中调用palloc。

 

2、默认值

如果没有parent,也就是顶级上下文,allowInCritSection 默认为false,否则与parent取相同值。

MemoryContextCreate时的代码摘要:

if (parent)
  node->allowInCritSection = parent->allowInCritSection;
else
  node->allowInCritSection = false;

 

3、设置

PG准备了一个专用的函数,而不是直接赋值,其实区别不大,多了一个断言检查。

void
MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
{
	AssertArg(MemoryContextIsValid(context));

	context->allowInCritSection = allow;
}

4、允许在临界区中分配内存的上下文:

搜索MemoryContextAllowInCriticalSection可知,内核中有四种允许在临界区中分配内存的上下文:

(1)、文件同步管理中的未决操作上下文 pendingOpsCxt (2)、错误上下文 ErrorContext (3)、预写日志调试上下文 walDebugCxt (4)、轻量锁统计上下文 lwlock_stats_cxt

5、作用

从代码中搜索,并没有发现这个属性的用处,只是有一个断言判断用到它:

#define AssertNotInCriticalSection(context) \
  Assert(CritSectionCount == 0 || (context)->allowInCritSection)

在临界区中从上下文中申请内存时会引起错误,其它并没有发现。

就在这里有一段说明:

You should not do memory allocations within a critical section, because an out-of-memory error will be escalated to a PANIC. To enforce that rule, the allocation functions Assert that.

在打开编译开关enable-cassert时,进程有可能因为它被abort,根据需要可以考虑设置allowInCritSection。

 

欢迎关注

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部