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

Commitdb96e1c

Browse files
committed
Rewrite PQping to be more like what we agreed to last week.
Basically, we want to distinguish all cases where the connection wasnot made from those where it was. A convenient proxy for this is tosee if we got a message with a SQLSTATE code back from the postmaster.This presumes that the postmaster will always send us a SQLSTATE ina failure message, which is true for 7.4 and later postmasters inevery case except fork failure. (We could possibly complicate thepostmaster code to do something about that, but it seems not worththe trouble, especially since pg_ctl's response for that case shouldbe to keep waiting anyway.)If we did get a SQLSTATE from the postmaster, there are basically onlytwo cases, as per last week's discussion: ERRCODE_CANNOT_CONNECT_NOWand everything else. Any other error code implies that the postmasteris in principle willing to accept connections, it just didn't like orcouldn't handle this particular request. We want to make a specialcase for ERRCODE_CANNOT_CONNECT_NOW so that "pg_ctl start -w" knowsit should keep waiting.In passing, pick names for the enum constants that are a tad lesslikely to present collision hazards in future.
1 parentbe3b666 commitdb96e1c

File tree

6 files changed

+209
-134
lines changed

6 files changed

+209
-134
lines changed

‎doc/src/sgml/libpq.sgml

Lines changed: 84 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,90 @@ PostgresPollingStatusType PQresetPoll(PGconn *conn);
10601060
</listitem>
10611061
</varlistentry>
10621062

1063+
<varlistentry id="libpq-pqpingparams">
1064+
<term><function>PQpingParams</function><indexterm><primary>PQpingParams</></></term>
1065+
<listitem>
1066+
<para>
1067+
<function>PQpingParams</function> reports the status of the
1068+
server. It accepts connection parameters identical to those of
1069+
<function>PQconnectdbParams</>, described above. It is not, however,
1070+
necessary to supply correct user name, password, or database name
1071+
values to obtain the server status.
1072+
1073+
<synopsis>
1074+
PGPing PQpingParams(const char **keywords, const char **values, int expand_dbname);
1075+
</synopsis>
1076+
1077+
The function returns one of the following values:
1078+
1079+
<variablelist>
1080+
<varlistentry id="libpq-pqpingparams-pqping-ok">
1081+
<term><literal>PQPING_OK</literal></term>
1082+
<listitem>
1083+
<para>
1084+
The server is running and appears to be accepting connections.
1085+
</para>
1086+
</listitem>
1087+
</varlistentry>
1088+
1089+
<varlistentry id="libpq-pqpingparams-pqping-reject">
1090+
<term><literal>PQPING_REJECT</literal></term>
1091+
<listitem>
1092+
<para>
1093+
The server is running but is in a state that disallows connections
1094+
(startup, shutdown, or crash recovery).
1095+
</para>
1096+
</listitem>
1097+
</varlistentry>
1098+
1099+
<varlistentry id="libpq-pqpingparams-pqping-no-response">
1100+
<term><literal>PQPING_NO_RESPONSE</literal></term>
1101+
<listitem>
1102+
<para>
1103+
The server could not be contacted.
1104+
</para>
1105+
</listitem>
1106+
</varlistentry>
1107+
1108+
<varlistentry id="libpq-pqpingparams-pqping-no-attempt">
1109+
<term><literal>PQPING_NO_ATTEMPT</literal></term>
1110+
<listitem>
1111+
<para>
1112+
No attempt was made to contact the server, because the supplied
1113+
parameters were incorrect or there was some client-side problem
1114+
(for example, out of memory).
1115+
</para>
1116+
</listitem>
1117+
</varlistentry>
1118+
</variablelist>
1119+
1120+
</para>
1121+
1122+
</listitem>
1123+
</varlistentry>
1124+
1125+
<varlistentry id="libpq-pqping">
1126+
<term><function>PQping</function><indexterm><primary>PQping</></></term>
1127+
<listitem>
1128+
<para>
1129+
<function>PQping</function> reports the status of the
1130+
server. It accepts connection parameters identical to those of
1131+
<function>PQconnectdb</>, described above. It is not, however,
1132+
necessary to supply correct user name, password, or database name
1133+
values to obtain the server status.
1134+
1135+
<synopsis>
1136+
PGPing PQping(const char *conninfo);
1137+
</synopsis>
1138+
</para>
1139+
1140+
<para>
1141+
The return values are the same as for <function>PQpingParams</>.
1142+
</para>
1143+
1144+
</listitem>
1145+
</varlistentry>
1146+
10631147
</variablelist>
10641148
</para>
10651149
</sect1>
@@ -1511,74 +1595,6 @@ int PQbackendPID(const PGconn *conn);
15111595
</listitem>
15121596
</varlistentry>
15131597

1514-
<varlistentry id="libpq-pqpingparams">
1515-
<term><function>PQpingParams</function><indexterm><primary>PQpingParams</></></term>
1516-
<listitem>
1517-
<para>
1518-
<function>PQpingParams</function> indicates the status of the
1519-
server. The currently recognized parameter key words are the
1520-
same as <function>PQconnectParams</>.
1521-
1522-
<synopsis>
1523-
PGPing PQpingParams(const char **keywords, const char **values, int expand_dbname);
1524-
</synopsis>
1525-
1526-
It returns one of the following values:
1527-
1528-
<variablelist>
1529-
<varlistentry id="libpq-pqpingparams-pqaccess">
1530-
<term><literal>PQACCESS</literal></term>
1531-
<listitem>
1532-
<para>
1533-
The server is running and allows access.
1534-
</para>
1535-
</listitem>
1536-
</varlistentry>
1537-
1538-
<varlistentry id="libpq-pqpingparams-pqreject">
1539-
<term><literal>PQREJECT</literal></term>
1540-
<listitem>
1541-
<para>
1542-
The server is running but rejected a connection request.
1543-
</para>
1544-
</listitem>
1545-
</varlistentry>
1546-
1547-
<varlistentry id="libpq-pqpingparams-pqnoresponse">
1548-
<term><literal>PQNORESPONSE</literal></term>
1549-
<listitem>
1550-
<para>
1551-
The server did not respond.
1552-
</para>
1553-
</listitem>
1554-
</varlistentry>
1555-
</variablelist>
1556-
1557-
</para>
1558-
1559-
</listitem>
1560-
</varlistentry>
1561-
1562-
<varlistentry id="libpq-pqping">
1563-
<term><function>PQping</function><indexterm><primary>PQping</></></term>
1564-
<listitem>
1565-
<para>
1566-
Returns the status of the server.
1567-
1568-
<synopsis>
1569-
PGPing PQping(const char *conninfo);
1570-
</synopsis>
1571-
</para>
1572-
1573-
<para>
1574-
This function uses the same <literal>conninfo</literal> parameter
1575-
key words as <function>PQconnectdb</>. It returns the same
1576-
values as <function>PQpingParams</> above.
1577-
</para>
1578-
1579-
</listitem>
1580-
</varlistentry>
1581-
15821598
<varlistentry id="libpq-pqconnectionneedspassword">
15831599
<term><function>PQconnectionNeedsPassword</function><indexterm><primary>PQconnectionNeedsPassword</></></term>
15841600
<listitem>

‎src/bin/pg_ctl/pg_ctl.c

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -397,20 +397,21 @@ start_postmaster(void)
397397

398398
/*
399399
* Find the pgport and try a connection
400+
*
400401
* Note that the checkpoint parameter enables a Windows service control
401402
* manager checkpoint, it's got nothing to do with database checkpoints!!
402403
*/
403404
staticPGPing
404405
test_postmaster_connection(booldo_checkpoint)
405406
{
406-
PGPingret=PQACCESS;/* assume success forzerowait */
407+
PGPingret=PQPING_OK;/* assume success for wait == zero */
407408
inti;
408409
charportstr[32];
409410
char*p;
410411
char*q;
411412
charconnstr[128];/* Should be way more than enough! */
412413

413-
*portstr='\0';
414+
portstr[0]='\0';
414415

415416
/*
416417
* Look in post_opts for a -p switch.
@@ -453,7 +454,7 @@ test_postmaster_connection(bool do_checkpoint)
453454
* This parsing code isn't amazingly bright either, but it should be okay
454455
* for valid port settings.
455456
*/
456-
if (!*portstr)
457+
if (!portstr[0])
457458
{
458459
char**optlines;
459460

@@ -491,11 +492,11 @@ test_postmaster_connection(bool do_checkpoint)
491492
}
492493

493494
/* Check environment */
494-
if (!*portstr&&getenv("PGPORT")!=NULL)
495+
if (!portstr[0]&&getenv("PGPORT")!=NULL)
495496
strlcpy(portstr,getenv("PGPORT"),sizeof(portstr));
496497

497498
/* Else use compiled-in default */
498-
if (!*portstr)
499+
if (!portstr[0])
499500
snprintf(portstr,sizeof(portstr),"%d",DEF_PGPORT);
500501

501502
/*
@@ -507,34 +508,32 @@ test_postmaster_connection(bool do_checkpoint)
507508

508509
for (i=0;i<wait_seconds;i++)
509510
{
510-
if ((ret=PQping(connstr))!=PQNORESPONSE)
511-
returnret;
512-
else
513-
{
511+
ret=PQping(connstr);
512+
if (ret==PQPING_OK||ret==PQPING_NO_ATTEMPT)
513+
break;
514+
/* No response, or startup still in process; wait */
514515
#if defined(WIN32)
515-
if (do_checkpoint)
516-
{
517-
/*
518-
* Increment the wait hint by 6 secs (connection timeout +
519-
* sleep) We must do this to indicate to the SCM that our
520-
* startup time is changing, otherwise it'll usually send a
521-
* stop signal after 20 seconds, despite incrementing the
522-
* checkpoint counter.
516+
if (do_checkpoint)
517+
{
518+
/*
519+
* Increment the wait hint by 6 secs (connection timeout +
520+
* sleep) We must do this to indicate to the SCM that our
521+
* startup time is changing, otherwise it'll usually send a
522+
* stop signal after 20 seconds, despite incrementing the
523+
* checkpoint counter.
523524
*/
524-
status.dwWaitHint+=6000;
525-
status.dwCheckPoint++;
526-
SetServiceStatus(hStatus, (LPSERVICE_STATUS)&status);
527-
}
528-
529-
else
525+
status.dwWaitHint+=6000;
526+
status.dwCheckPoint++;
527+
SetServiceStatus(hStatus, (LPSERVICE_STATUS)&status);
528+
}
529+
else
530530
#endif
531-
print_msg(".");
531+
print_msg(".");
532532

533-
pg_usleep(1000000);/* 1 sec */
534-
}
533+
pg_usleep(1000000);/* 1 sec */
535534
}
536535

537-
/*value of last call to PQping */
536+
/*return result of last call to PQping */
538537
returnret;
539538
}
540539

@@ -738,24 +737,30 @@ do_start(void)
738737

739738
if (do_wait)
740739
{
741-
intstatus;
742-
743740
print_msg(_("waiting for server to start..."));
744741

745-
if ((status=test_postmaster_connection(false))==PQNORESPONSE)
746-
{
747-
write_stderr(_("%s: could not start server\n"
748-
"Examine the log output.\n"),
749-
progname);
750-
exit(1);
751-
}
752-
else
742+
switch (test_postmaster_connection(false))
753743
{
754-
print_msg(_(" done\n"));
755-
print_msg(_("server started\n"));
756-
if (status==PQREJECT)
757-
write_stderr(_("warning: could not connect; might be caused by invalid authentication or\n"
758-
"misconfiguration.\n"));
744+
casePQPING_OK:
745+
print_msg(_(" done\n"));
746+
print_msg(_("server started\n"));
747+
break;
748+
casePQPING_REJECT:
749+
print_msg(_(" stopped waiting\n"));
750+
print_msg(_("server is still starting up\n"));
751+
break;
752+
casePQPING_NO_RESPONSE:
753+
print_msg(_(" stopped waiting\n"));
754+
write_stderr(_("%s: could not start server\n"
755+
"Examine the log output.\n"),
756+
progname);
757+
exit(1);
758+
break;
759+
casePQPING_NO_ATTEMPT:
760+
print_msg(_(" failed\n"));
761+
write_stderr(_("%s: could not wait for server because of misconfiguration\n"),
762+
progname);
763+
exit(1);
759764
}
760765
}
761766
else
@@ -1289,7 +1294,7 @@ pgwin32_ServiceMain(DWORD argc, LPTSTR *argv)
12891294
if (do_wait)
12901295
{
12911296
write_eventlog(EVENTLOG_INFORMATION_TYPE,_("Waiting for server startup...\n"));
1292-
if (test_postmaster_connection(true)== false)
1297+
if (test_postmaster_connection(true)!=PQPING_OK)
12931298
{
12941299
write_eventlog(EVENTLOG_INFORMATION_TYPE,_("Timed out waiting for server startup\n"));
12951300
pgwin32_SetServiceStatus(SERVICE_STOPPED);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp