On 02/03/2014 09:09 AM, Craig Ringer wrote:
> At a guess, we're looking at a case where a new child context is created
> at every call, so every MemoryContextResetChildren call has to deal with
> more child contexts.
That would be "yes". After a short run, I see 32849 lines like:
json_array_elements temporary cxt: 8192 total in 1 blocks; 8160 free (0
chunks); 32 used
under the context:
PortalMemory: 8192 total in 1 blocks
PortalHeapMemory: 7168 total in 3 blocks
ExecutorState: 65600 total in 4 blocks
ExprContext: 8192 total in 1 blocks
json_array_elements temporary cxt: 8192 total in 1 blocks;
8160 free (0 chunks); 32 used
The attached patch deletes the context after use, bringing performance
back into line. It should be backpatched to 9.3.
--
Craig Ringer http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
>From f4ae516d643dee43200053533dbcc8b362e3f92b Mon Sep 17 00:00:00 2001
From: Craig Ringer <[email protected]>
Date: Mon, 3 Feb 2014 09:47:34 +0800
Subject: [PATCH] Fix leaked memory context in json_array_each and json_each
json_array_each and json_each leaked a memory context with each
invocation, causing profiles involving many invocations in a single
query context to be dominated by MemoryContextReset because of
MemoryContextResetChildren calls made after each tuple is emitted.
See initial bug report:
http://stackoverflow.com/q/21507127/398670
and list discussion:
http://www.postgresql.org/message-id/[email protected]
---
src/backend/utils/adt/jsonfuncs.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c
index a19b222..116d7a0 100644
--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -975,6 +975,9 @@ each_worker(PG_FUNCTION_ARGS, bool as_text)
rsi->setResult = state->tuple_store;
rsi->setDesc = state->ret_tdesc;
+ MemoryContextDelete(state->tmp_cxt);
+ state->tmp_cxt = NULL;
+
PG_RETURN_NULL();
}
@@ -1157,6 +1160,9 @@ elements_worker(PG_FUNCTION_ARGS, bool as_text)
rsi->setResult = state->tuple_store;
rsi->setDesc = state->ret_tdesc;
+ MemoryContextDelete(state->tmp_cxt);
+ state->tmp_cxt = NULL;
+
PG_RETURN_NULL();
}
--
1.8.3.1
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers