Commit 65d6e4cb authored by Tatsuo Ishii's avatar Tatsuo Ishii

Add ALTER SYSTEM command to edit the server configuration file.

Patch contributed by Amit Kapila. Reviewed by Hari Babu, Masao Fujii,
Boszormenyi Zoltan, Andres Freund, Greg Smith and others.
parent dba5a9dd
......@@ -158,6 +158,19 @@ SET ENABLE_SEQSCAN TO OFF;
require superuser permission to change via <command>SET</command> or
<command>ALTER</>.
</para>
<para>
Another way to change configuration parameters persistently is by
use of <xref linkend="SQL-ALTERSYSTEM">
command, for example:
<screen>
ALTER SYSTEM SET checkpoint_timeout TO 600;
</screen>
This command will allow users to change values persistently
through SQL command. The values will be effective after reload of server configuration
(<acronym>SIGHUP</>) or server startup. The effect of this command is similar to when
user manually changes values in <filename>postgresql.conf</filename>.
</para>
</sect2>
<sect2 id="config-setting-examining">
......
......@@ -30,6 +30,7 @@ Complete list of usable sgml source files in this directory.
<!ENTITY alterSchema SYSTEM "alter_schema.sgml">
<!ENTITY alterServer SYSTEM "alter_server.sgml">
<!ENTITY alterSequence SYSTEM "alter_sequence.sgml">
<!ENTITY alterSystem SYSTEM "alter_system.sgml">
<!ENTITY alterTable SYSTEM "alter_table.sgml">
<!ENTITY alterTableSpace SYSTEM "alter_tablespace.sgml">
<!ENTITY alterTSConfig SYSTEM "alter_tsconfig.sgml">
......
<!--
doc/src/sgml/ref/alter_system.sgml
PostgreSQL documentation
-->
<refentry id="SQL-ALTERSYSTEM">
<refmeta>
<refentrytitle>ALTER SYSTEM</refentrytitle>
<manvolnum>7</manvolnum>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
<refnamediv>
<refname>ALTER SYSTEM</refname>
<refpurpose>change a server configuration parameter</refpurpose>
</refnamediv>
<indexterm zone="sql-altersystem">
<primary>ALTER SYSTEM</primary>
</indexterm>
<refsynopsisdiv>
<synopsis>
ALTER SYSTEM SET <replaceable class="PARAMETER">configuration_parameter</replaceable> { TO | = } { <replaceable class="PARAMETER">value</replaceable> | '<replaceable class="PARAMETER">value</replaceable>' | DEFAULT }
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>ALTER SYSTEM</command> writes the configuration parameter
values to the <filename>postgresql.auto.conf</filename> file. With
<literal>DEFAULT</literal>, it removes a configuration entry from
<filename>postgresql.auto.conf</filename> file. The values will be
effective after reload of server configuration (SIGHUP) or in next
server start based on the type of configuration parameter modified.
</para>
<para>
This command is not allowed inside transaction block or function.
</para>
<para>
See <xref linkend="config-setting"> for other ways to set the parameters and
how they become effective.
</para>
</refsect1>
<refsect1>
<title>Parameters</title>
<variablelist>
<varlistentry>
<term><replaceable class="parameter">configuration_parameter</replaceable></term>
<listitem>
<para>
Name of a settable run-time parameter. Available parameters are
documented in <xref linkend="runtime-config">.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">value</replaceable></term>
<listitem>
<para>
New value of parameter. Values can be specified as string
constants, identifiers, numbers, or comma-separated lists of
these, as appropriate for the particular parameter.
<literal>DEFAULT</literal> can be written to specify to remove the
parameter and its value from <filename>postgresql.auto.conf</filename>
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
Set the <literal>wal_level</>:
<programlisting>
ALTER SYSTEM SET wal_level = hot_standby;
</programlisting>
</para>
<para>
Set the <literal>authentication_timeout</>:
<programlisting>
ALTER SYSTEM SET authentication_timeout = 10;
</programlisting></para>
</refsect1>
<refsect1>
<title>Compatibility</title>
<para>
The <command>ALTER SYSTEM</command> statement is a
<productname>PostgreSQL</productname> extension.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="SQL-SET"></member>
<member><xref linkend="SQL-SHOW"></member>
</simplelist>
</refsect1>
</refentry>
......@@ -58,6 +58,7 @@
&alterSchema;
&alterSequence;
&alterServer;
&alterSystem;
&alterTable;
&alterTableSpace;
&alterTSConfig;
......
......@@ -125,6 +125,12 @@ Item
<entry>Subdirectory containing WAL (Write Ahead Log) files</entry>
</row>
<row>
<entry><filename>postgresql.auto.conf</></entry>
<entry>A file used for storing configuration parameters that are set by
<command>ALTER SYSTEM</command></entry>
</row>
<row>
<entry><filename>postmaster.opts</></entry>
<entry>A file recording the command-line options the server was
......
......@@ -3292,6 +3292,16 @@ _copyReplicaIdentityStmt(const ReplicaIdentityStmt *from)
return newnode;
}
static AlterSystemStmt *
_copyAlterSystemStmt(const AlterSystemStmt * from)
{
AlterSystemStmt *newnode = makeNode(AlterSystemStmt);
COPY_NODE_FIELD(setstmt);
return newnode;
}
static CreateSeqStmt *
_copyCreateSeqStmt(const CreateSeqStmt *from)
{
......@@ -4368,6 +4378,9 @@ copyObject(const void *from)
case T_ReplicaIdentityStmt:
retval = _copyReplicaIdentityStmt(from);
break;
case T_AlterSystemStmt:
retval = _copyAlterSystemStmt(from);
break;
case T_CreateSeqStmt:
retval = _copyCreateSeqStmt(from);
break;
......
......@@ -1546,6 +1546,15 @@ _equalReplicaIdentityStmt(const ReplicaIdentityStmt *a, const ReplicaIdentityStm
return true;
}
static bool
_equalAlterSystemStmt(const AlterSystemStmt * a, const AlterSystemStmt * b)
{
COMPARE_NODE_FIELD(setstmt);
return true;
}
static bool
_equalCreateSeqStmt(const CreateSeqStmt *a, const CreateSeqStmt *b)
{
......@@ -2838,6 +2847,9 @@ equal(const void *a, const void *b)
case T_ReplicaIdentityStmt:
retval = _equalReplicaIdentityStmt(a, b);
break;
case T_AlterSystemStmt:
retval = _equalAlterSystemStmt(a, b);
break;
case T_CreateSeqStmt:
retval = _equalCreateSeqStmt(a, b);
break;
......
......@@ -216,7 +216,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
AlterEventTrigStmt
AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterEnumStmt
AlterFdwStmt AlterForeignServerStmt AlterGroupStmt
AlterObjectSchemaStmt AlterOwnerStmt AlterSeqStmt AlterTableStmt
AlterObjectSchemaStmt AlterOwnerStmt AlterSeqStmt AlterSystemStmt AlterTableStmt
AlterExtensionStmt AlterExtensionContentsStmt AlterForeignTableStmt
AlterCompositeTypeStmt AlterUserStmt AlterUserMappingStmt AlterUserSetStmt
AlterRoleStmt AlterRoleSetStmt
......@@ -397,7 +397,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <istmt> insert_rest
%type <vsetstmt> set_rest set_rest_more SetResetClause FunctionSetResetClause
%type <vsetstmt> generic_set set_rest set_rest_more SetResetClause FunctionSetResetClause
%type <node> TableElement TypedTableElement ConstraintElem TableFuncElement
%type <node> columnDef columnOptions
......@@ -724,6 +724,7 @@ stmt :
| AlterObjectSchemaStmt
| AlterOwnerStmt
| AlterSeqStmt
| AlterSystemStmt
| AlterTableStmt
| AlterCompositeTypeStmt
| AlterRoleSetStmt
......@@ -1333,7 +1334,7 @@ set_rest:
| set_rest_more
;
set_rest_more: /* Generic SET syntaxes: */
generic_set:
var_name TO var_list
{
VariableSetStmt *n = makeNode(VariableSetStmt);
......@@ -1364,6 +1365,9 @@ set_rest_more: /* Generic SET syntaxes: */
n->name = $1;
$$ = n;
}
set_rest_more: /* Generic SET syntaxes: */
generic_set {$$ = $1;}
| var_name FROM CURRENT_P
{
VariableSetStmt *n = makeNode(VariableSetStmt);
......@@ -8310,6 +8314,23 @@ DropdbStmt: DROP DATABASE database_name
;
/*****************************************************************************
*
* ALTER SYSTEM SET
*
* This is used to change configuration parameters persistently.
*****************************************************************************/
AlterSystemStmt:
ALTER SYSTEM_P SET generic_set
{
AlterSystemStmt *n = makeNode(AlterSystemStmt);
n->setstmt = $4;
$$ = (Node *)n;
}
;
/*****************************************************************************
*
* Manipulate a domain
......
......@@ -811,6 +811,13 @@ sendDir(char *path, int basepathlen, bool sizeonly)
strlen(PG_TEMP_FILE_PREFIX)) == 0)
continue;
/* skip auto conf temporary file */
if (strncmp(de->d_name,
PG_AUTOCONF_FILENAME ".temp",
sizeof(PG_AUTOCONF_FILENAME) + 4) == 0)
continue;
/*
* If there's a backup_label file, it belongs to a backup started by
* the user with pg_start_backup(). It is *not* correct for this
......
......@@ -687,6 +687,11 @@ standard_ProcessUtility(Node *parsetree,
ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
break;
case T_AlterSystemStmt:
PreventTransactionChain(isTopLevel, "ALTER SYSTEM");
AlterSystemSetConfigFile((AlterSystemStmt *) parsetree);
break;
case T_VariableSetStmt:
ExecSetVariableStmt((VariableSetStmt *) parsetree, isTopLevel);
break;
......@@ -2157,6 +2162,10 @@ CreateCommandTag(Node *parsetree)
tag = "REFRESH MATERIALIZED VIEW";
break;
case T_AlterSystemStmt:
tag = "ALTER SYSTEM";
break;
case T_VariableSetStmt:
switch (((VariableSetStmt *) parsetree)->kind)
{
......@@ -2726,6 +2735,10 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL;
break;
case T_AlterSystemStmt:
lev = LOGSTMT_ALL;
break;
case T_VariableSetStmt:
lev = LOGSTMT_ALL;
break;
......
......@@ -120,6 +120,9 @@ ProcessConfigFile(GucContext context)
*head,
*tail;
int i;
char ConfigAutoFileName[MAXPGPATH];
char *ErrorConfFile;
char *CallingFileName;
/*
* Config files are processed on startup (by the postmaster only)
......@@ -134,6 +137,8 @@ ProcessConfigFile(GucContext context)
*/
elevel = IsUnderPostmaster ? DEBUG2 : LOG;
ErrorConfFile = ConfigFileName;
/* Parse the file into a list of option names and values */
head = tail = NULL;
......@@ -144,6 +149,26 @@ ProcessConfigFile(GucContext context)
goto cleanup_list;
}
/*
* Parse postgresql.auto.conf file after postgresql.conf to replace
* parameters set by ALTER SYSTEM command. This file is present in
* data directory, however when called during initdb data directory is not
* set till this point, so use ConfigFile path which will be same.
*/
snprintf(ConfigAutoFileName,sizeof(ConfigAutoFileName),"%s", PG_AUTOCONF_FILENAME);
if (data_directory)
CallingFileName = NULL;
else
CallingFileName = ConfigFileName;
if (!ParseConfigFile(ConfigAutoFileName, CallingFileName, false, 0, elevel, &head, &tail))
{
/* Syntax error(s) detected in the file, so bail out */
error = true;
ErrorConfFile = ConfigAutoFileName;
goto cleanup_list;
}
/*
* Mark all extant GUC variables as not present in the config file.
* We need this so that we can tell below which ones have been removed
......@@ -192,6 +217,7 @@ ProcessConfigFile(GucContext context)
item->name,
item->filename, item->sourceline)));
error = true;
ErrorConfFile = item->filename;
}
}
......@@ -318,7 +344,10 @@ ProcessConfigFile(GucContext context)
}
}
else if (scres == 0)
{
error = true;
ErrorConfFile = item->filename;
}
/* else no error but variable's active value was not changed */
/*
......@@ -348,17 +377,17 @@ ProcessConfigFile(GucContext context)
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("configuration file \"%s\" contains errors",
ConfigFileName)));
ErrorConfFile)));
else if (apply)
ereport(elevel,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("configuration file \"%s\" contains errors; unaffected changes were applied",
ConfigFileName)));
ErrorConfFile)));
else
ereport(elevel,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("configuration file \"%s\" contains errors; no changes were applied",
ConfigFileName)));
ErrorConfFile)));
}
}
......
This diff is collapsed.
......@@ -1228,6 +1228,7 @@ setup_config(void)
char repltok[MAXPGPATH];
char path[MAXPGPATH];
const char *default_timezone;
char *autoconflines[3];
fputs(_("creating configuration files ... "), stdout);
fflush(stdout);
......@@ -1320,6 +1321,21 @@ setup_config(void)
writefile(path, conflines);
chmod(path, S_IRUSR | S_IWUSR);
/*
* create the automatic configuration file to store the configuration
* parameters set by ALTER SYSTEM command. The parameters present in this
* file will override the value of parameters that exists before parse of
* this file.
*/
autoconflines[0] = pg_strdup("# Do not edit this file manually! \n");
autoconflines[1] = pg_strdup("# It will be overwritten by the ALTER SYSTEM command. \n");
autoconflines[2] = NULL;
sprintf(path, "%s/%s", pg_data, PG_AUTOCONF_FILENAME);
writefile(path, autoconflines);
chmod(path, S_IRUSR | S_IWUSR);
free(conflines);
......
......@@ -363,6 +363,7 @@ typedef enum NodeTag
T_AlterEventTrigStmt,
T_RefreshMatViewStmt,
T_ReplicaIdentityStmt,
T_AlterSystemStmt,
/*
* TAGS FOR PARSE TREE NODES (parsenodes.h)
......
......@@ -2471,6 +2471,16 @@ typedef struct DropdbStmt
bool missing_ok; /* skip error if db is missing? */
} DropdbStmt;
/* ----------------------
* Alter System Statement
* ----------------------
*/
typedef struct AlterSystemStmt
{
NodeTag type;
VariableSetStmt *setstmt; /* SET subcommand */
} AlterSystemStmt;
/* ----------------------
* Cluster Statement (support pbrown's cluster index implementation)
* ----------------------
......
......@@ -292,3 +292,10 @@
/* #define HEAPDEBUGALL */
/* #define ACLDEBUG */
/* #define RTDEBUG */
/*
* Automatic configuration file name for ALTER SYSTEM.
* This file will be used to store values of configuration parameters
* set by ALTER SYSTEM command
*/
#define PG_AUTOCONF_FILENAME "postgresql.auto.conf"
......@@ -81,6 +81,7 @@ typedef enum LWLockId
SyncRepLock,
BackgroundWorkerLock,
DynamicSharedMemoryControlLock,
AutoFileLock,
/* Individual lock IDs end here */
FirstBufMappingLock,
FirstLockMgrLock = FirstBufMappingLock + NUM_BUFFER_PARTITIONS,
......
......@@ -326,6 +326,7 @@ 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);
extern void AlterSystemSetConfigFile(AlterSystemStmt * setstmt);
extern char *GetConfigOptionByName(const char *name, const char **varname);
extern void GetConfigOptionByNum(int varnum, const char **values, bool *noshow);
extern int GetNumConfigOptions(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment