Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5b2a877

Browse files
committed
Provide for forward compatibility with future minor protocol versions.
Previously, any attempt to request a 3.x protocol version other than3.0 would lead to a hard connection failure, which made the minorprotocol version really no different from the major protocol versionand precluded gentle protocol version breaks. Instead, when theclient requests a 3.x protocol version where x is greater than 0, sendthe new NegotiateProtocolVersion message to convey that we supportonly 3.0. This makes it possible to introduce new minor protocolversions without requiring a connection retry when the server isolder.In addition, if the startup packet includes name/value pairs wherethe name starts with "_pq_.", assume that those are protocol options,not GUCs. Include those we don't support (i.e. all of them, atpresent) in the NegotiateProtocolVersion message so that the clientknows they were not understood. This makes it possible for theclient to request previously-unsupported features without bumpingthe protocol version at all; the client can tell from the server'sresponse whether the option was understood.It will take some time before servers that support these newfacilities become common in the wild; to speed things up and makethings easier for a future 3.1 protocol version, back-patch to allsupported releases.Robert Haas and Badrul ChowdhuryDiscussion:http://postgr.es/m/BN6PR21MB0772FFA0CBD298B76017744CD1730@BN6PR21MB0772.namprd21.prod.outlook.comDiscussion:http://postgr.es/m/30788.1498672033@sss.pgh.pa.us
1 parentae772bb commit5b2a877

File tree

2 files changed

+159
-16
lines changed

2 files changed

+159
-16
lines changed

‎doc/src/sgml/protocol.sgml

Lines changed: 106 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,18 @@
2222
<productname>PostgreSQL</productname> 7.4 and later. For descriptions
2323
of the earlier protocol versions, see previous releases of the
2424
<productname>PostgreSQL</productname> documentation. A single server
25-
can support multiple protocol versions. The initial
26-
startup-request message tells the server which protocol version the
27-
client is attempting to use, and then the server follows that protocol
28-
if it is able.
25+
can support multiple protocol versions. The initial startup-request
26+
message tells the server which protocol version the client is attempting to
27+
use. If the major version requested by the client is not supported by
28+
the server, the connection will be rejected (for example, this would occur
29+
if the client requested protocol version 4.0, which does not exist as of
30+
this writing). If the minor version requested by the client is not
31+
supported by the server (e.g. the client requests version 3.1, but the
32+
server supports only 3.0), the server may either reject the connection or
33+
may respond with a NegotiateProtocolVersion message containing the highest
34+
minor protocol version which it supports. The client may then choose either
35+
to continue with the connection using the specified protocol version or
36+
to abort the connection.
2937
</para>
3038

3139
<para>
@@ -406,6 +414,21 @@
406414
</listitem>
407415
</varlistentry>
408416

417+
<varlistentry>
418+
<term>NegotiateProtocolVersion</term>
419+
<listitem>
420+
<para>
421+
The server does not support the minor protocol version requested
422+
by the client, but does support an earlier version of the protocol;
423+
this message indicates the highest supported minor version. This
424+
message will also be sent if the client requested unsupported protocol
425+
options (i.e. beginning with <literal>_pq_.</literal>) in the
426+
startup packet. This message will be followed by an ErrorResponse or
427+
a message indicating the success or failure of authentication.
428+
</para>
429+
</listitem>
430+
</varlistentry>
431+
409432
</variablelist>
410433
</para>
411434

@@ -420,8 +443,10 @@
420443
for further messages from the server. In this phase a backend process
421444
is being started, and the frontend is just an interested bystander.
422445
It is still possible for the startup attempt
423-
to fail (ErrorResponse), but in the normal case the backend will send
424-
some ParameterStatus messages, BackendKeyData, and finally ReadyForQuery.
446+
to fail (ErrorResponse) or the server to decline support for the requested
447+
minor protocol version (NegotiateProtocolVersion), but in the normal case
448+
the backend will send some ParameterStatus messages, BackendKeyData, and
449+
finally ReadyForQuery.
425450
</para>
426451

427452
<para>
@@ -4580,6 +4605,74 @@ GSSResponse (F)
45804605
</listitem>
45814606
</varlistentry>
45824607

4608+
<varlistentry>
4609+
<term>
4610+
NegotiateProtocolVersion (B)
4611+
</term>
4612+
<listitem>
4613+
<para>
4614+
4615+
<variablelist>
4616+
<varlistentry>
4617+
<term>
4618+
Byte1('v')
4619+
</term>
4620+
<listitem>
4621+
<para>
4622+
Identifies the message as a protocol version negotiation
4623+
message.
4624+
</para>
4625+
</listitem>
4626+
</varlistentry>
4627+
<varlistentry>
4628+
<term>
4629+
Int32
4630+
</term>
4631+
<listitem>
4632+
<para>
4633+
Length of message contents in bytes, including self.
4634+
</para>
4635+
</listitem>
4636+
</varlistentry>
4637+
<varlistentry>
4638+
<term>
4639+
Int32
4640+
</term>
4641+
<listitem>
4642+
<para>
4643+
Newest minor protocol version supported by the server
4644+
for the major protocol version requested by the client.
4645+
</para>
4646+
</listitem>
4647+
</varlistentry>
4648+
<varlistentry>
4649+
<term>
4650+
Int32
4651+
</term>
4652+
<listitem>
4653+
<para>
4654+
Number of protocol options not recognized by the server.
4655+
</para>
4656+
</listitem>
4657+
</varlistentry>
4658+
</variablelist>
4659+
Then, for protocol option not recognized by the server, there
4660+
is the following:
4661+
<variablelist>
4662+
<varlistentry>
4663+
<term>
4664+
String
4665+
</term>
4666+
<listitem>
4667+
<para>
4668+
The option name.
4669+
</para>
4670+
</listitem>
4671+
</varlistentry>
4672+
</variablelist>
4673+
</para>
4674+
</listitem>
4675+
</varlistentry>
45834676

45844677
<varlistentry>
45854678
<term>
@@ -5535,11 +5628,13 @@ StartupMessage (F)
55355628
</varlistentry>
55365629
</variablelist>
55375630

5538-
In addition to the above, any run-time parameter that can be
5539-
set at backend start time might be listed. Such settings
5540-
will be applied during backend start (after parsing the
5541-
command-line arguments if any). The values will act as
5542-
session defaults.
5631+
In addition to the above, others parameter may be listed.
5632+
Parameter names beginning with <literal>_pq_.</literal> are
5633+
reserved for use as protocol extensions, while others are
5634+
treated as run-time parameters to be set at backend start
5635+
time. Such settings will be applied during backend start
5636+
(after parsing the command-line arguments if any) and will
5637+
act as session defaults.
55435638
</para>
55445639
</listitem>
55455640
</varlistentry>

‎src/backend/postmaster/postmaster.c

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
#include"lib/ilist.h"
104104
#include"libpq/auth.h"
105105
#include"libpq/libpq.h"
106+
#include"libpq/pqformat.h"
106107
#include"libpq/pqsignal.h"
107108
#include"miscadmin.h"
108109
#include"pg_getopt.h"
@@ -413,6 +414,7 @@ static void ExitPostmaster(int status) pg_attribute_noreturn();
413414
staticintServerLoop(void);
414415
staticintBackendStartup(Port*port);
415416
staticintProcessStartupPacket(Port*port,boolSSLdone);
417+
staticvoidSendNegotiateProtocolVersion(List*unrecognized_protocol_options);
416418
staticvoidprocessCancelRequest(Port*port,void*pkt);
417419
staticintinitMasks(fd_set*rmask);
418420
staticvoidreport_fork_failure_to_client(Port*port,interrnum);
@@ -2050,12 +2052,9 @@ ProcessStartupPacket(Port *port, bool SSLdone)
20502052
*/
20512053
FrontendProtocol=proto;
20522054

2053-
/* Check we can handle the protocol the frontend is using. */
2054-
2055+
/* Check that the major protocol version is in range. */
20552056
if (PG_PROTOCOL_MAJOR(proto)<PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST)||
2056-
PG_PROTOCOL_MAJOR(proto)>PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST)||
2057-
(PG_PROTOCOL_MAJOR(proto)==PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST)&&
2058-
PG_PROTOCOL_MINOR(proto)>PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST)))
2057+
PG_PROTOCOL_MAJOR(proto)>PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST))
20592058
ereport(FATAL,
20602059
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
20612060
errmsg("unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u",
@@ -2077,6 +2076,7 @@ ProcessStartupPacket(Port *port, bool SSLdone)
20772076
if (PG_PROTOCOL_MAJOR(proto) >=3)
20782077
{
20792078
int32offset=sizeof(ProtocolVersion);
2079+
List*unrecognized_protocol_options=NIL;
20802080

20812081
/*
20822082
* Scan packet body for name/option pairs. We can assume any string
@@ -2126,6 +2126,16 @@ ProcessStartupPacket(Port *port, bool SSLdone)
21262126
valptr),
21272127
errhint("Valid values are: \"false\", 0, \"true\", 1, \"database\".")));
21282128
}
2129+
elseif (strncmp(nameptr,"_pq_.",5)==0)
2130+
{
2131+
/*
2132+
* Any option beginning with _pq_. is reserved for use as a
2133+
* protocol-level option, but at present no such options are
2134+
* defined.
2135+
*/
2136+
unrecognized_protocol_options=
2137+
lappend(unrecognized_protocol_options,pstrdup(nameptr));
2138+
}
21292139
else
21302140
{
21312141
/* Assume it's a generic GUC option */
@@ -2145,6 +2155,16 @@ ProcessStartupPacket(Port *port, bool SSLdone)
21452155
ereport(FATAL,
21462156
(errcode(ERRCODE_PROTOCOL_VIOLATION),
21472157
errmsg("invalid startup packet layout: expected terminator as last byte")));
2158+
2159+
/*
2160+
* If the client requested a newer protocol version or if the client
2161+
* requested any protocol options we didn't recognize, let them know
2162+
* the newest minor protocol version we do support and the names of any
2163+
* unrecognized options.
2164+
*/
2165+
if (PG_PROTOCOL_MINOR(proto)>PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST)||
2166+
unrecognized_protocol_options!=NIL)
2167+
SendNegotiateProtocolVersion(unrecognized_protocol_options);
21482168
}
21492169
else
21502170
{
@@ -2258,6 +2278,34 @@ ProcessStartupPacket(Port *port, bool SSLdone)
22582278
returnSTATUS_OK;
22592279
}
22602280

2281+
/*
2282+
* Send a NegotiateProtocolVersion to the client. This lets the client know
2283+
* that they have requested a newer minor protocol version than we are able
2284+
* to speak. We'll speak the highest version we know about; the client can,
2285+
* of course, abandon the connection if that's a problem.
2286+
*
2287+
* We also include in the response a list of protocol options we didn't
2288+
* understand. This allows clients to include optional parameters that might
2289+
* be present either in newer protocol versions or third-party protocol
2290+
* extensions without fear of having to reconnect if those options are not
2291+
* understood, while at the same time making certain that the client is aware
2292+
* of which options were actually accepted.
2293+
*/
2294+
staticvoid
2295+
SendNegotiateProtocolVersion(List*unrecognized_protocol_options)
2296+
{
2297+
StringInfoDatabuf;
2298+
ListCell*lc;
2299+
2300+
pq_beginmessage(&buf,'v');/* NegotiateProtocolVersion */
2301+
pq_sendint(&buf,PG_PROTOCOL_LATEST,4);
2302+
pq_sendint(&buf,list_length(unrecognized_protocol_options),4);
2303+
foreach(lc,unrecognized_protocol_options)
2304+
pq_sendstring(&buf,lfirst(lc));
2305+
pq_endmessage(&buf);
2306+
2307+
/* no need to flush, some other message will follow */
2308+
}
22612309

22622310
/*
22632311
* The client has sent a cancel request packet, not a normal

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp