Skip to content

Commit 39b28c2

Browse files
committed
[yugabyte#24951] Create separate memory context for RelationBuildTriggers
Summary: Currently, there is an issue where on certain customer schemas, PG backend memory usage spikes up to 1GB during connection startup. In short, this is caused by our relcache preloading combined with inefficient memory management. The issue is as follows: 1. First, we prefetch the `pg_trigger` table by loading it from the master leader into the local tserver's memory. 2. For every table, we call `RelationBuildTriggers` to build the triggers section of the table's relcache entry. 3. Inside `RelationBuildTriggers`, we scan `pg_trigger` for the relevant triggers. Normally, we can use the `pg_trigger_tgrelid_tgname_index` index to seek directly to the triggers we want using the table's OID. But we can't do index seeks on the prefetched table, so we do a sequential scan on the entire table, copying every row of `pg_trigger` into PG memory and then filtering for the triggers we want. The entire YbUpdateRelationCache process uses a single memory context (`UpdateRelationCacheContext`), so each call to `RelationBuildTriggers` will allocate memory from this memory context which isn't freed until the entire relation cache is built. 4. As a result, we are using a lot of extra memory. If we have `m` total triggers and `n` total tables, we are allocating memory for `mn` rows in the `UpdateRelationCacheContext`. As a shorter-term fix for this issue, this revision creates a new memory context every time we invoke `RelationBuildTriggers` which gets freed at the end of `RelationBuildTriggers`. This way, even though we are still copying `mn` rows into memory, we are only allocating memory for `m` rows at a time before freeing the memory, avoiding the spike in memory usage. This issue does not address the CPU overhead of doing all of these extra copies—this is addressed in the longer-term fix D40003. Test Plan: Jenkins Reviewers: mihnea, myang Reviewed By: myang Subscribers: yql Differential Revision: https://phorge.dev.yugabyte.com/D40005
1 parent 4b99c2e commit 39b28c2

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

src/postgres/src/backend/commands/trigger.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,8 +1924,19 @@ RelationBuildTriggers(Relation relation)
19241924
SysScanDesc tgscan;
19251925
HeapTuple htup;
19261926
MemoryContext oldContext;
1927+
MemoryContext ybSavedContext;
1928+
MemoryContext ybTriggerContext;
19271929
int i;
19281930

1931+
if (IsYugaByteEnabled())
1932+
{
1933+
ybTriggerContext =
1934+
AllocSetContextCreate(CurrentMemoryContext,
1935+
"RelationBuildTriggers context",
1936+
ALLOCSET_DEFAULT_SIZES);
1937+
ybSavedContext = MemoryContextSwitchTo(ybTriggerContext);
1938+
}
1939+
19291940
/*
19301941
* Allocate a working array to hold the triggers (the array is extended if
19311942
* necessary)
@@ -2042,6 +2053,11 @@ RelationBuildTriggers(Relation relation)
20422053
if (numtrigs == 0)
20432054
{
20442055
pfree(triggers);
2056+
if (IsYugaByteEnabled())
2057+
{
2058+
MemoryContextSwitchTo(ybSavedContext);
2059+
MemoryContextDelete(ybTriggerContext);
2060+
}
20452061
return;
20462062
}
20472063

@@ -2059,6 +2075,12 @@ RelationBuildTriggers(Relation relation)
20592075

20602076
/* Release working memory */
20612077
FreeTriggerDesc(trigdesc);
2078+
2079+
if (IsYugaByteEnabled())
2080+
{
2081+
MemoryContextSwitchTo(ybSavedContext);
2082+
MemoryContextDelete(ybTriggerContext);
2083+
}
20622084
}
20632085

20642086
/*

0 commit comments

Comments
 (0)