We observed, that every update on a row of a temporal enables tables leads to ~15KB additional memory usage of the processes for a connection.
Our researches showed that this memory usage is caused by lookup_versioning_hash_entry because already created entries are not found.
Steps we did to analyse:
Debugging showed, that all calls of function "lookup_versioning_hash_entry" entered block “if (!*found)”, even the second call in a row for the same table.
Uncommenting “memset” command showed:
All fields of “entry” (except relid) are 0/NULL.
Without "memset" all non first calls of function "lookup_versioning_hash_entry" skipped block “if (!*found)” (as intended).
Memory usage was constant (wanted behaviour)
Reactivating “memset” command and subsequent setting entry->relid = relid;
Same behaviour as seen with uncommenting “memset” (s. above).
We don't really understand
why the first call of “hash_search” for a table returns an initialized struct “entry” with "relid" set and all other fields filled with null values.
why setting "entry->relid" to null leads to not finding the entry on subsequent calls of “hash_search”.
But ensuring "entry->relid" is set after the "memset" solves the issue for us.
diff --git a/versioning.c b/versioning.c
index 2497c2f..0599530 100644
--- a/versioning.c
+++ b/versioning.c
@@ -1080,6 +1080,7 @@ lookup_versioning_hash_entry(Oid relid,
if (!*found)
{
memset(entry, 0, sizeof(VersioningHashEntry));
+ entry->relid = relid;
/* Mark a newly created entry invalid. */
entry->natts = -1;
We observed, that every update on a row of a temporal enables tables leads to ~15KB additional memory usage of the processes for a connection.
Our researches showed that this memory usage is caused by lookup_versioning_hash_entry because already created entries are not found.
Steps we did to analyse:
entry->relid = relid;
We don't really understand
But ensuring "entry->relid" is set after the "memset" solves the issue for us.