*** a/src/backend/utils/mmgr/aset.c
--- b/src/backend/utils/mmgr/aset.c
***************
*** 500,505 **** AllocSetContextCreate(MemoryContext parent,
--- 500,508 ----
  					 errdetail("Failed while creating memory context \"%s\".",
  							   name)));
  		}
+ 
+ 		((MemoryContext) set)->mem_allocated += blksize;
+ 
  		block->aset = set;
  		block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ;
  		block->endptr = ((char *) block) + blksize;
***************
*** 590,595 **** AllocSetReset(MemoryContext context)
--- 593,600 ----
  		else
  		{
  			/* Normal case, release the block */
+ 			context->mem_allocated -= block->endptr - ((char*) block);
+ 
  #ifdef CLOBBER_FREED_MEMORY
  			wipe_mem(block, block->freeptr - ((char *) block));
  #endif
***************
*** 632,637 **** AllocSetDelete(MemoryContext context)
--- 637,644 ----
  	{
  		AllocBlock	next = block->next;
  
+ 		context->mem_allocated -= block->endptr - ((char *) block);
+ 
  #ifdef CLOBBER_FREED_MEMORY
  		wipe_mem(block, block->freeptr - ((char *) block));
  #endif
***************
*** 672,677 **** AllocSetAlloc(MemoryContext context, Size size)
--- 679,687 ----
  		block = (AllocBlock) malloc(blksize);
  		if (block == NULL)
  			return NULL;
+ 
+ 		context->mem_allocated += blksize;
+ 
  		block->aset = set;
  		block->freeptr = block->endptr = ((char *) block) + blksize;
  
***************
*** 861,866 **** AllocSetAlloc(MemoryContext context, Size size)
--- 871,878 ----
  		if (block == NULL)
  			return NULL;
  
+ 		context->mem_allocated += blksize;
+ 
  		block->aset = set;
  		block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ;
  		block->endptr = ((char *) block) + blksize;
***************
*** 964,969 **** AllocSetFree(MemoryContext context, void *pointer)
--- 976,984 ----
  			set->blocks = block->next;
  		else
  			prevblock->next = block->next;
+ 
+ 		context->mem_allocated -= block->endptr - ((char*) block);
+ 
  #ifdef CLOBBER_FREED_MEMORY
  		wipe_mem(block, block->freeptr - ((char *) block));
  #endif
***************
*** 1077,1082 **** AllocSetRealloc(MemoryContext context, void *pointer, Size size)
--- 1092,1098 ----
  		AllocBlock	prevblock = NULL;
  		Size		chksize;
  		Size		blksize;
+ 		Size		oldblksize;
  
  		while (block != NULL)
  		{
***************
*** 1094,1102 **** AllocSetRealloc(MemoryContext context, void *pointer, Size size)
--- 1110,1123 ----
  		/* Do the realloc */
  		chksize = MAXALIGN(size);
  		blksize = chksize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
+ 		oldblksize = block->endptr - ((char *)block);
+ 
  		block = (AllocBlock) realloc(block, blksize);
  		if (block == NULL)
  			return NULL;
+ 
+ 		context->mem_allocated += blksize - oldblksize;
+ 
  		block->freeptr = block->endptr = ((char *) block) + blksize;
  
  		/* Update pointers since block has likely been moved */
*** a/src/backend/utils/mmgr/mcxt.c
--- b/src/backend/utils/mmgr/mcxt.c
***************
*** 477,482 **** MemoryContextIsEmpty(MemoryContext context)
--- 477,505 ----
  }
  
  /*
+  * Find the memory allocated to blocks for this memory context. If recurse is
+  * true, also include children.
+  */
+ int64
+ MemoryContextMemAllocated(MemoryContext context, bool recurse)
+ {
+ 	int64 total = context->mem_allocated;
+ 
+ 	AssertArg(MemoryContextIsValid(context));
+ 
+ 	if (recurse)
+ 	{
+ 		MemoryContext child = context->firstchild;
+ 		for (child = context->firstchild;
+ 			 child != NULL;
+ 			 child = child->nextchild)
+ 			total += MemoryContextMemAllocated(child, true);
+ 	}
+ 
+ 	return total;
+ }
+ 
+ /*
   * MemoryContextStats
   *		Print statistics about the named context and all its descendants.
   *
***************
*** 636,641 **** MemoryContextCreate(NodeTag tag, Size size,
--- 659,665 ----
  	node->firstchild = NULL;
  	node->nextchild = NULL;
  	node->isReset = true;
+ 	node->mem_allocated = 0;
  	node->name = ((char *) node) + size;
  	strcpy(node->name, name);
  
*** a/src/include/nodes/memnodes.h
--- b/src/include/nodes/memnodes.h
***************
*** 63,68 **** typedef struct MemoryContextData
--- 63,69 ----
  	MemoryContext nextchild;	/* next child of same parent */
  	char	   *name;			/* context name (just for debugging) */
  	MemoryContextCallback *reset_cbs;	/* list of reset/delete callbacks */
+ 	int64		mem_allocated;	/* track memory allocated for this context */
  } MemoryContextData;
  
  /* utils/palloc.h contains typedef struct MemoryContextData *MemoryContext */
*** a/src/include/utils/memutils.h
--- b/src/include/utils/memutils.h
***************
*** 103,108 **** extern Size GetMemoryChunkSpace(void *pointer);
--- 103,109 ----
  extern MemoryContext GetMemoryChunkContext(void *pointer);
  extern MemoryContext MemoryContextGetParent(MemoryContext context);
  extern bool MemoryContextIsEmpty(MemoryContext context);
+ extern int64 MemoryContextMemAllocated(MemoryContext context, bool recurse);
  extern void MemoryContextStats(MemoryContext context);
  extern void MemoryContextAllowInCriticalSection(MemoryContext context,
  									bool allow);
