diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 9a0afa4..ed15c74 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -814,11 +814,11 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
 	if (client_min_messages < WARNING)
 		(void) set_config_option("client_min_messages", "warning",
 								 PGC_USERSET, PGC_S_SESSION,
-								 GUC_ACTION_SAVE, true, 0);
+								 GUC_ACTION_SAVE, 0);
 	if (log_min_messages < WARNING)
 		(void) set_config_option("log_min_messages", "warning",
 								 PGC_SUSET, PGC_S_SESSION,
-								 GUC_ACTION_SAVE, true, 0);
+								 GUC_ACTION_SAVE, 0);
 
 	/*
 	 * Set up the search path to contain the target schema, then the schemas
@@ -843,7 +843,7 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
 
 	(void) set_config_option("search_path", pathbuf.data,
 							 PGC_USERSET, PGC_S_SESSION,
-							 GUC_ACTION_SAVE, true, 0);
+							 GUC_ACTION_SAVE, 0);
 
 	/*
 	 * Set creating_extension and related variables so that
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index e4d7b2c..364c763 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -2410,7 +2410,7 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
 	snprintf(workmembuf, sizeof(workmembuf), "%d", maintenance_work_mem);
 	(void) set_config_option("work_mem", workmembuf,
 							 PGC_USERSET, PGC_S_SESSION,
-							 GUC_ACTION_SAVE, true, 0);
+							 GUC_ACTION_SAVE, 0);
 
 	if (SPI_connect() != SPI_OK_CONNECT)
 		elog(ERROR, "SPI_connect failed");
diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l
index e6e1109..f1fbf43 100644
--- a/src/backend/utils/misc/guc-file.l
+++ b/src/backend/utils/misc/guc-file.l
@@ -264,7 +264,7 @@ ProcessConfigFile(GucContext context)
 		/* Now we can re-apply the wired-in default (i.e., the boot_val) */
 		if (set_config_option(gconf->name, NULL,
 							  context, PGC_S_DEFAULT,
-							  GUC_ACTION_SET, true, 0) > 0)
+							  GUC_ACTION_SET, 0) > 0)
 		{
 			/* Log the change if appropriate */
 			if (context == PGC_SIGHUP)
@@ -319,7 +319,7 @@ ProcessConfigFile(GucContext context)
 
 		scres = set_config_option(item->name, item->value,
 								  context, PGC_S_FILE,
-								  GUC_ACTION_SET, true, 0);
+								  GUC_ACTION_SET, 0);
 		if (scres > 0)
 		{
 			/* variable was updated, so log the change if appropriate */
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 6c52db8..8ff4421 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -513,6 +513,7 @@ const char *const GucContext_Names[] =
 	 /* PGC_POSTMASTER */ "postmaster",
 	 /* PGC_SIGHUP */ "sighup",
 	 /* PGC_BACKEND */ "backend",
+	 /* PGC_BACKEND_USERSET */ "backend(userset)",
 	 /* PGC_SUSET */ "superuser",
 	 /* PGC_USERSET */ "user"
 };
@@ -2898,7 +2899,7 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
-		{"local_preload_libraries", PGC_BACKEND, CLIENT_CONN_PRELOAD,
+		{"local_preload_libraries", PGC_BACKEND_USERSET, CLIENT_CONN_PRELOAD,
 			gettext_noop("Lists unprivileged shared libraries to preload into each backend."),
 			NULL,
 			GUC_LIST_INPUT | GUC_LIST_QUOTE
@@ -4552,6 +4553,8 @@ push_old_value(struct config_generic * gconf, GucAction action)
 {
 	GucStack   *stack;
 
+	Assert(action != GUC_ACTION_CHECK);
+
 	/* If we're not inside a nest level, do nothing */
 	if (GUCNestLevel == 0)
 		return;
@@ -4587,6 +4590,12 @@ push_old_value(struct config_generic * gconf, GucAction action)
 				/* Could only have a prior SAVE of same variable */
 				Assert(stack->state == GUC_SAVE);
 				break;
+			case GUC_ACTION_CHECK:
+				/*
+				 * This is compiler warning silencer.
+				 * This action is blocked at the beginning of this function.
+				 */
+				break;
 		}
 		Assert(guc_dirty);		/* must be set already */
 		return;
@@ -4613,6 +4622,12 @@ push_old_value(struct config_generic * gconf, GucAction action)
 		case GUC_ACTION_SAVE:
 			stack->state = GUC_SAVE;
 			break;
+		case GUC_ACTION_CHECK:
+			/*
+			 * This is compiler warning silencer.
+			 * This action is blocked at the beginning of this function.
+			 */
+			break;
 	}
 	stack->source = gconf->source;
 	stack->scontext = gconf->scontext;
@@ -5593,11 +5608,12 @@ validate_conf_option(struct config_generic * record, const char *name,
 int
 set_config_option(const char *name, const char *value,
 				  GucContext context, GucSource source,
-				  GucAction action, bool changeVal, int elevel)
+				  GucAction action, int elevel)
 {
 	struct config_generic *record;
 	bool		prohibitValueChange = false;
 	bool		makeDefault;
+	bool		changeVal = (action != GUC_ACTION_CHECK);
 
 	if (elevel == 0)
 	{
@@ -5681,6 +5697,30 @@ set_config_option(const char *name, const char *value,
 			 * signals to individual backends only.
 			 */
 			break;
+		case PGC_BACKEND_USERSET:
+			/*
+			 * The behavior of parameter checking for PGC_BACKEND_USERSET is
+			 * the same to PGC_USERSET.
+			 */
+			if (action == GUC_ACTION_CHECK)
+				break;
+
+			/*
+			 * Setting the value of the PGC_BACKEND_USERSET parameters should
+			 * be set during initializing backend, having
+			 * context=PGC_SUSET/source=PGC_S_USER.
+			 */
+			if (action != GUC_ACTION_SET ||
+				context != PGC_SUSET || source != PGC_S_USER ||
+				!IsInitProcessingMode())
+			{
+				ereport(elevel,
+						(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
+						 errmsg("parameter \"%s\" should be set by ALTER USER.",
+							 name)));
+				return 0;
+			}
+			break;
 		case PGC_BACKEND:
 			if (context == PGC_SIGHUP)
 			{
@@ -6311,7 +6351,7 @@ SetConfigOption(const char *name, const char *value,
 				GucContext context, GucSource source)
 {
 	(void) set_config_option(name, value, context, source,
-							 GUC_ACTION_SET, true, 0);
+							 GUC_ACTION_SET, 0);
 }
 
 
@@ -6868,7 +6908,6 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
 									 (superuser() ? PGC_SUSET : PGC_USERSET),
 									 PGC_S_SESSION,
 									 action,
-									 true,
 									 0);
 			break;
 		case VAR_SET_MULTI:
@@ -6957,7 +6996,6 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
 									 (superuser() ? PGC_SUSET : PGC_USERSET),
 									 PGC_S_SESSION,
 									 action,
-									 true,
 									 0);
 			break;
 		case VAR_RESET_ALL:
@@ -7003,7 +7041,6 @@ SetPGVariable(const char *name, List *args, bool is_local)
 							 (superuser() ? PGC_SUSET : PGC_USERSET),
 							 PGC_S_SESSION,
 							 is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET,
-							 true,
 							 0);
 }
 
@@ -7047,7 +7084,6 @@ set_config_by_name(PG_FUNCTION_ARGS)
 							 (superuser() ? PGC_SUSET : PGC_USERSET),
 							 PGC_S_SESSION,
 							 is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET,
-							 true,
 							 0);
 
 	/* get the new current value */
@@ -7169,7 +7205,7 @@ define_custom_variable(struct config_generic * variable)
 		(void) set_config_option(name, pHolder->reset_val,
 								 pHolder->gen.reset_scontext,
 								 pHolder->gen.reset_source,
-								 GUC_ACTION_SET, true, WARNING);
+								 GUC_ACTION_SET, WARNING);
 	/* That should not have resulted in stacking anything */
 	Assert(variable->stack == NULL);
 
@@ -7225,30 +7261,30 @@ reapply_stacked_values(struct config_generic * variable,
 			case GUC_SAVE:
 				(void) set_config_option(name, curvalue,
 										 curscontext, cursource,
-										 GUC_ACTION_SAVE, true, WARNING);
+										 GUC_ACTION_SAVE, WARNING);
 				break;
 
 			case GUC_SET:
 				(void) set_config_option(name, curvalue,
 										 curscontext, cursource,
-										 GUC_ACTION_SET, true, WARNING);
+										 GUC_ACTION_SET, WARNING);
 				break;
 
 			case GUC_LOCAL:
 				(void) set_config_option(name, curvalue,
 										 curscontext, cursource,
-										 GUC_ACTION_LOCAL, true, WARNING);
+										 GUC_ACTION_LOCAL, WARNING);
 				break;
 
 			case GUC_SET_LOCAL:
 				/* first, apply the masked value as SET */
 				(void) set_config_option(name, stack->masked.val.stringval,
 									   stack->masked_scontext, PGC_S_SESSION,
-										 GUC_ACTION_SET, true, WARNING);
+										 GUC_ACTION_SET, WARNING);
 				/* then apply the current value as LOCAL */
 				(void) set_config_option(name, curvalue,
 										 curscontext, cursource,
-										 GUC_ACTION_LOCAL, true, WARNING);
+										 GUC_ACTION_LOCAL, WARNING);
 				break;
 		}
 
@@ -7272,7 +7308,7 @@ reapply_stacked_values(struct config_generic * variable,
 		{
 			(void) set_config_option(name, curvalue,
 									 curscontext, cursource,
-									 GUC_ACTION_SET, true, WARNING);
+									 GUC_ACTION_SET, WARNING);
 			variable->stack = NULL;
 		}
 	}
@@ -8396,7 +8432,7 @@ read_nondefault_variables(void)
 
 		(void) set_config_option(varname, varvalue,
 								 varscontext, varsource,
-								 GUC_ACTION_SET, true, 0);
+								 GUC_ACTION_SET, 0);
 		if (varsourcefile[0])
 			set_config_sourcefile(varname, varsourcefile, varsourceline);
 
@@ -8499,7 +8535,7 @@ ProcessGUCArray(ArrayType *array,
 
 		(void) set_config_option(name, value,
 								 context, source,
-								 action, true, 0);
+								 action, 0);
 
 		free(name);
 		if (value)
@@ -8802,7 +8838,7 @@ validate_option_array_item(const char *name, const char *value,
 	/* test for permissions and valid option value */
 	(void) set_config_option(name, value,
 							 superuser() ? PGC_SUSET : PGC_USERSET,
-							 PGC_S_TEST, GUC_ACTION_SET, false, 0);
+							 PGC_S_TEST, GUC_ACTION_CHECK, 0);
 
 	return true;
 }
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 0a729c1..8284337 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -54,6 +54,7 @@ typedef enum
 	PGC_POSTMASTER,
 	PGC_SIGHUP,
 	PGC_BACKEND,
+	PGC_BACKEND_USERSET,
 	PGC_SUSET,
 	PGC_USERSET
 } GucContext;
@@ -165,7 +166,8 @@ typedef enum
 	/* Types of set_config_option actions */
 	GUC_ACTION_SET,				/* regular SET command */
 	GUC_ACTION_LOCAL,			/* SET LOCAL command */
-	GUC_ACTION_SAVE				/* function SET option, or temp assignment */
+	GUC_ACTION_SAVE,			/* function SET option, or temp assignment */
+	GUC_ACTION_CHECK			/* make no change, check only */
 } GucAction;
 
 #define GUC_QUALIFIER_SEPARATOR '.'
@@ -327,7 +329,7 @@ extern bool parse_int(const char *value, int *result, int flags,
 extern bool parse_real(const char *value, double *result);
 extern int set_config_option(const char *name, const char *value,
 				  GucContext context, GucSource source,
-				  GucAction action, bool changeVal, int elevel);
+				  GucAction action, int elevel);
 extern void AlterSystemSetConfigFile(AlterSystemStmt *setstmt);
 extern char *GetConfigOptionByName(const char *name, const char **varname);
 extern void GetConfigOptionByNum(int varnum, const char **values, bool *noshow);
