Merge pull request #2467 from citusdata/fix-crashes-on-ooms

Fix crashes caused by stack size increase under high memory load
pull/2469/head
Burak Yücesoy 2018-11-14 10:49:06 +03:00 committed by GitHub
commit ce463e9812
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 33 additions and 0 deletions

View File

@ -55,6 +55,7 @@
#include "postmaster/postmaster.h" #include "postmaster/postmaster.h"
#include "optimizer/planner.h" #include "optimizer/planner.h"
#include "optimizer/paths.h" #include "optimizer/paths.h"
#include "tcop/tcopprot.h"
#include "utils/guc.h" #include "utils/guc.h"
#include "utils/guc_tables.h" #include "utils/guc_tables.h"
@ -65,6 +66,7 @@ static char *CitusVersion = CITUS_VERSION;
void _PG_init(void); void _PG_init(void);
static void ResizeStackToMaximumDepth(void);
static void multi_log_hook(ErrorData *edata); static void multi_log_hook(ErrorData *edata);
static void CreateRequiredDirectories(void); static void CreateRequiredDirectories(void);
static void RegisterCitusConfigVariables(void); static void RegisterCitusConfigVariables(void);
@ -169,6 +171,8 @@ _PG_init(void)
"shared_preload_libraries."))); "shared_preload_libraries.")));
} }
ResizeStackToMaximumDepth();
/* /*
* Extend the database directory structure before continuing with * Extend the database directory structure before continuing with
* initialization - one of the later steps might require them to exist. * initialization - one of the later steps might require them to exist.
@ -234,6 +238,35 @@ _PG_init(void)
} }
/*
* Stack size increase during high memory load may cause unexpected crashes.
* With this alloca call, we are increasing stack size explicitly, so that if
* it is not possible to increase stack size, we will get an OOM error instead
* of a crash.
*
* This function is called on backend startup. The allocated memory will
* automatically be released at the end of the function's scope. However, we'd
* have already expanded the stack and it wouldn't shrink back. So, in a sense,
* per backend we're securing max_stack_depth kB's of memory on the stack upfront.
*
* Not all the backends require max_stack_depth kB's on the stack, so we might end
* up with unnecessary allocations. However, the default value is 2MB, which seems
* an acceptable trade-off. Also, allocating memory upfront may perform better
* under some circumstances.
*/
static void
ResizeStackToMaximumDepth(void)
{
#ifndef WIN32
volatile char *stack_resizer = NULL;
long max_stack_depth_bytes = max_stack_depth * 1024L;
stack_resizer = alloca(max_stack_depth_bytes);
stack_resizer[max_stack_depth_bytes - 1] = 0;
#endif
}
/* /*
* multi_log_hook intercepts postgres log commands. We use this to override * multi_log_hook intercepts postgres log commands. We use this to override
* postgres error messages when they're not specific enough for the users. * postgres error messages when they're not specific enough for the users.