1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

Clean up parsing of synchronous_standby_names GUC variable.

Commit 989be0810d added a flex/bison lexer/parser to interpret
synchronous_standby_names.  It was done in a pretty crufty way, though,
making assorted end-use sites responsible for calling the parser at the
right times.  That was not only vulnerable to errors of omission, but made
it possible that lexer/parser errors occur at very undesirable times,
and created memory leakages even if there was no error.

Instead, perform the parsing once during check_synchronous_standby_names
and let guc.c manage the resulting data.  To do that, we have to flatten
the parsed representation into a single hunk of malloc'd memory, but that
is not very hard.

While at it, work a little harder on making useful error reports for
parsing problems; the previous code felt that "synchronous_standby_names
parser returned 1" was an appropriate user-facing error message.  (To
be fair, it did also log a syntax error message, but separately from the
GUC problem report, which is at best confusing.)  It had some outright
bugs in the face of invalid input, too.

I (tgl) also concluded that we need to restrict unquoted names in
synchronous_standby_names to be just SQL identifiers.  The previous coding
would accept darn near anything, which (1) makes the quoting convention
both nearly-unnecessary and formally ambiguous, (2) makes it very hard to
understand what is a syntax error and what is a creative interpretation of
the input as a standby name, and (3) makes it impossible to further extend
the syntax in future without a compatibility break.  I presume that we're
intending future extensions of the syntax, else this parsing infrastructure
is massive overkill, so (3) is an important objection.  Since we've taken
a compatibility hit for non-identifier names with this change anyway, we
might as well lock things down now and insist that users use double quotes
for standby names that aren't identifiers.

Kyotaro Horiguchi and Tom Lane
This commit is contained in:
Tom Lane
2016-04-27 17:55:19 -04:00
parent 372ff7cae2
commit 4c804fbdfb
7 changed files with 211 additions and 197 deletions

View File

@ -2983,7 +2983,7 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
Specifies a list of standby names that can support
Specifies a list of standby servers that can support
<firstterm>synchronous replication</>, as described in
<xref linkend="synchronous-replication">.
There will be one or more active synchronous standbys;
@ -2991,7 +2991,7 @@ include_dir 'conf.d'
these standby servers confirm receipt of their data.
The synchronous standbys will be those whose names appear
earlier in this list, and
that is both currently connected and streaming data in real-time
that are both currently connected and streaming data in real-time
(as shown by a state of <literal>streaming</literal> in the
<link linkend="monitoring-stats-views-table">
<literal>pg_stat_replication</></link> view).
@ -3002,7 +3002,7 @@ include_dir 'conf.d'
Specifying more than one standby name can allow very high availability.
</para>
<para>
This parameter specifies a list of standby servers by using
This parameter specifies a list of standby servers using
either of the following syntaxes:
<synopsis>
<replaceable class="parameter">num_sync</replaceable> ( <replaceable class="parameter">standby_name</replaceable> [, ...] )
@ -3013,17 +3013,17 @@ include_dir 'conf.d'
wait for replies from,
and <replaceable class="parameter">standby_name</replaceable>
is the name of a standby server. For example, a setting of
<literal>'3 (s1, s2, s3, s4)'</> makes transaction commits wait
until their WAL records are received by three higher priority standbys
<literal>3 (s1, s2, s3, s4)</> makes transaction commits wait
until their WAL records are received by three higher-priority standbys
chosen from standby servers <literal>s1</>, <literal>s2</>,
<literal>s3</> and <literal>s4</>.
</para>
<para>
The second syntax was used before <productname>PostgreSQL</>
version 9.6 and is still supported. It's the same as the first syntax
with <replaceable class="parameter">num_sync</replaceable>=1.
For example, both settings of <literal>'1 (s1, s2)'</> and
<literal>'s1, s2'</> have the same meaning; either <literal>s1</>
with <replaceable class="parameter">num_sync</replaceable> equal to 1.
For example, <literal>1 (s1, s2)</> and
<literal>s1, s2</> have the same meaning: either <literal>s1</>
or <literal>s2</> is chosen as a synchronous standby.
</para>
<para>
@ -3039,11 +3039,12 @@ include_dir 'conf.d'
</para>
<note>
<para>
The <replaceable class="parameter">standby_name</replaceable>
must be enclosed in double quotes if a comma (<literal>,</>),
a double quote (<literal>"</>), <!-- " font-lock sanity -->
a left parentheses (<literal>(</>), a right parentheses (<literal>)</>)
or a space is used in the name of a standby server.
Each <replaceable class="parameter">standby_name</replaceable>
should have the form of a valid SQL identifier, unless it
is <literal>*</>. You can use double-quoting if necessary. But note
that <replaceable class="parameter">standby_name</replaceable>s are
compared to standby application names case-insensitively, whether
double-quoted or not.
</para>
</note>
<para>