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

Commit075354a

Browse files
committed
Improve "pg_ctl -w start" server detection by writing the postmaster
port and socket directory into postmaster.pid, and have pg_ctl read fromthat file, for use by PQping().
1 parent4b1742a commit075354a

File tree

3 files changed

+112
-158
lines changed

3 files changed

+112
-158
lines changed

‎doc/src/sgml/ref/pg_ctl-ref.sgml

Lines changed: 4 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -348,21 +348,12 @@ PostgreSQL documentation
348348
<para>
349349
Wait for the startup or shutdown to complete.
350350
Waiting is the default option for shutdowns, but not startups.
351+
When waiting for startup, <command>pg_ctl</command> repeatedly
352+
attempts to connect to the server.
351353
When waiting for shutdown, <command>pg_ctl</command> waits for
352354
the server to remove its <acronym>PID</acronym> file.
353-
When waiting for startup, <command>pg_ctl</command> repeatedly
354-
attempts to connect to the server via <application>psql</>, and
355-
reports success when this is successful.
356-
<command>pg_ctl</command> will attempt to use the proper port for
357-
<application>psql</>. If the environment variable
358-
<envar>PGPORT</envar> exists, that is used. Otherwise,
359-
<command>pg_ctl</command> will see if a port has been set in the
360-
<filename>postgresql.conf</filename> file. If not, it will use the
361-
default port that <productname>PostgreSQL</productname> was compiled
362-
with (5432 by default).
363-
When waiting, <command>pg_ctl</command> will
364-
return an exit code based on the success of the startup
365-
or shutdown.
355+
<command>pg_ctl</command> returns an exit code based on the
356+
success of the startup or shutdown.
366357
</para>
367358
</listitem>
368359
</varlistentry>
@@ -442,28 +433,6 @@ PostgreSQL documentation
442433
</listitem>
443434
</varlistentry>
444435

445-
<varlistentry>
446-
<term><envar>PGHOST</envar></term>
447-
448-
<listitem>
449-
<para>
450-
Default host name or Unix-domain socket location for <xref
451-
linkend="app-psql"> (used when waiting for startup).
452-
</para>
453-
</listitem>
454-
</varlistentry>
455-
456-
<varlistentry>
457-
<term><envar>PGPORT</envar></term>
458-
459-
<listitem>
460-
<para>
461-
Default port number for <xref linkend="app-psql">
462-
(used when waiting for startup).
463-
</para>
464-
</listitem>
465-
</varlistentry>
466-
467436
</variablelist>
468437

469438
<para>
@@ -506,18 +475,6 @@ PostgreSQL documentation
506475
</listitem>
507476
</varlistentry>
508477

509-
<varlistentry>
510-
<term><filename>postgresql.conf</filename></term>
511-
512-
<listitem>
513-
<para>
514-
This file, located in the data directory, is parsed to find the
515-
proper port to use with <application>psql</application>
516-
when waiting for startup.
517-
</para>
518-
</listitem>
519-
</varlistentry>
520-
521478
</variablelist>
522479
</refsect1>
523480

‎src/backend/utils/init/miscinit.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include"mb/pg_wchar.h"
3434
#include"miscadmin.h"
3535
#include"postmaster/autovacuum.h"
36+
#include"postmaster/postmaster.h"
3637
#include"storage/fd.h"
3738
#include"storage/ipc.h"
3839
#include"storage/pg_shmem.h"
@@ -658,7 +659,7 @@ CreateLockFile(const char *filename, bool amPostmaster,
658659
boolisDDLock,constchar*refName)
659660
{
660661
intfd;
661-
charbuffer[MAXPGPATH+100];
662+
charbuffer[MAXPGPATH*2+256];
662663
intntries;
663664
intlen;
664665
intencoded_pid;
@@ -868,9 +869,9 @@ CreateLockFile(const char *filename, bool amPostmaster,
868869
/*
869870
* Successfully created the file, now fill it.
870871
*/
871-
snprintf(buffer,sizeof(buffer),"%d\n%s\n",
872+
snprintf(buffer,sizeof(buffer),"%d\n%s\n%d\n%s\n",
872873
amPostmaster ? (int)my_pid :-((int)my_pid),
873-
DataDir);
874+
DataDir,PostPortNumber,UnixSocketDir);
874875
errno=0;
875876
if (write(fd,buffer,strlen(buffer))!=strlen(buffer))
876877
{
@@ -994,8 +995,9 @@ RecordSharedMemoryInLockFile(unsigned long id1, unsigned long id2)
994995
{
995996
intfd;
996997
intlen;
998+
intlineno;
997999
char*ptr;
998-
charbuffer[BLCKSZ];
1000+
charbuffer[MAXPGPATH*2+256];
9991001

10001002
fd=open(DIRECTORY_LOCK_FILE,O_RDWR |PG_BINARY,0);
10011003
if (fd<0)
@@ -1019,18 +1021,20 @@ RecordSharedMemoryInLockFile(unsigned long id1, unsigned long id2)
10191021
buffer[len]='\0';
10201022

10211023
/*
1022-
* Skip over firsttwo lines (PID and path).
1024+
* Skip over firstfour lines (PID, pgdata, portnum, socketdir).
10231025
*/
1024-
ptr=strchr(buffer,'\n');
1025-
if (ptr==NULL||
1026-
(ptr=strchr(ptr+1,'\n'))==NULL)
1026+
ptr=buffer;
1027+
for (lineno=1;lineno <=4;lineno++)
10271028
{
1028-
elog(LOG,"bogus data in \"%s\"",DIRECTORY_LOCK_FILE);
1029-
close(fd);
1030-
return;
1029+
if ((ptr=strchr(ptr,'\n'))==NULL)
1030+
{
1031+
elog(LOG,"bogus data in \"%s\"",DIRECTORY_LOCK_FILE);
1032+
close(fd);
1033+
return;
1034+
}
1035+
ptr++;
10311036
}
1032-
ptr++;
1033-
1037+
10341038
/*
10351039
* Append key information.Format to try to keep it the same length
10361040
* always (trailing junk won't hurt, but might confuse humans).

‎src/bin/pg_ctl/pg_ctl.c

Lines changed: 91 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ static bool postmaster_is_alive(pid_t pid);
141141

142142
staticcharpostopts_file[MAXPGPATH];
143143
staticcharpid_file[MAXPGPATH];
144-
staticcharconf_file[MAXPGPATH];
145144
staticcharbackup_file[MAXPGPATH];
146145
staticcharrecovery_file[MAXPGPATH];
147146

@@ -404,113 +403,108 @@ start_postmaster(void)
404403
staticPGPing
405404
test_postmaster_connection(booldo_checkpoint)
406405
{
406+
intportnum=0;
407+
charsocket_dir[MAXPGPATH];
408+
charconnstr[MAXPGPATH+256];
407409
PGPingret=PQPING_OK;/* assume success for wait == zero */
410+
char**optlines;
408411
inti;
409-
charportstr[32];
410-
char*p;
411-
char*q;
412-
charconnstr[128];/* Should be way more than enough! */
413412

414-
portstr[0]='\0';
415-
416-
/*
417-
* Look in post_opts for a -p switch.
418-
*
419-
* This parsing code is not amazingly bright; it could for instance get
420-
* fooled if ' -p' occurs within a quoted argument value. Given that few
421-
* people pass complicated settings in post_opts, it's probably good
422-
* enough.
423-
*/
424-
for (p=post_opts;*p;)
413+
socket_dir[0]='\0';
414+
connstr[0]='\0';
415+
416+
for (i=0;i<wait_seconds;i++)
425417
{
426-
/* advance past whitespace */
427-
while (isspace((unsignedchar)*p))
428-
p++;
429-
430-
if (strncmp(p,"-p",2)==0)
418+
/* Do we need a connection string? */
419+
if (connstr[0]=='\0')
431420
{
432-
p+=2;
433-
/* advance past any whitespace/quoting */
434-
while (isspace((unsignedchar)*p)||*p=='\''||*p=='"')
435-
p++;
436-
/* find end of value (not including any ending quote!) */
437-
q=p;
438-
while (*q&&
439-
!(isspace((unsignedchar)*q)||*q=='\''||*q=='"'))
440-
q++;
441-
/* and save the argument value */
442-
strlcpy(portstr,p,Min((q-p)+1,sizeof(portstr)));
443-
/* keep looking, maybe there is another -p */
444-
p=q;
445-
}
446-
/* Advance to next whitespace */
447-
while (*p&& !isspace((unsignedchar)*p))
448-
p++;
449-
}
421+
/*
422+
* The number of lines in postmaster.pid tells us several things:
423+
*
424+
*# of lines
425+
*0lock file created but status not written
426+
*2pre-9.1 server, shared memory not created
427+
*3pre-9.1 server, shared memory created
428+
*49.1+ server, shared memory not created
429+
*59.1+ server, shared memory created
430+
*
431+
*For pre-9.1 Unix servers, we grab the port number from the
432+
*shmem key (first value on line 3). Pre-9.1 Win32 has no
433+
*written shmem key, so we fail. 9.1+ writes both the port
434+
*number and socket address in the file for us to use.
435+
*(PG_VERSION could also have told us the major version.)
436+
*/
437+
438+
/* Try to read a completed postmaster.pid file */
439+
if ((optlines=readfile(pid_file))!=NULL&&
440+
optlines[0]!=NULL&&
441+
optlines[1]!=NULL&&
442+
optlines[2]!=NULL)
443+
{
444+
/* A 3-line file? */
445+
if (optlines[3]==NULL)
446+
{
447+
/*
448+
*Pre-9.1: on Unix, we get the port number by
449+
*deriving it from the shmem key (the first number on
450+
*on the line); see
451+
*miscinit.c::RecordSharedMemoryInLockFile().
452+
*/
453+
portnum=atoi(optlines[2]) /1000;
454+
/* Win32 does not give us a shmem key, so we fail. */
455+
if (portnum==0)
456+
{
457+
write_stderr(_("%s: -w option is not supported on this platform\nwhen connecting to a pre-9.1 server\n"),
458+
progname);
459+
returnPQPING_NO_ATTEMPT;
460+
}
461+
}
462+
else/* 9.1+ server */
463+
{
464+
portnum=atoi(optlines[2]);
465+
466+
/* Get socket directory, if specified. */
467+
if (optlines[3][0]!='\n')
468+
{
469+
/*
470+
*While unix_socket_directory can accept relative
471+
*directories, libpq's host must have a leading slash
472+
*to indicate a socket directory.
473+
*/
474+
if (optlines[3][0]!='/')
475+
{
476+
write_stderr(_("%s: -w option cannot use a relative socket directory specification\n"),
477+
progname);
478+
returnPQPING_NO_ATTEMPT;
479+
}
480+
strlcpy(socket_dir,optlines[3],MAXPGPATH);
481+
/* remove newline */
482+
if (strchr(socket_dir,'\n')!=NULL)
483+
*strchr(socket_dir,'\n')='\0';
484+
}
485+
}
450486

451-
/*
452-
* Search config file for a 'port' option.
453-
*
454-
* This parsing code isn't amazingly bright either, but it should be okay
455-
* for valid port settings.
456-
*/
457-
if (!portstr[0])
458-
{
459-
char**optlines;
487+
/*
488+
* We need to set connect_timeout otherwise on Windows the
489+
* Service Control Manager (SCM) will probably timeout first.
490+
*/
491+
snprintf(connstr,sizeof(connstr),
492+
"dbname=postgres port=%d connect_timeout=5",portnum);
460493

461-
optlines=readfile(conf_file);
462-
if (optlines!=NULL)
463-
{
464-
for (;*optlines!=NULL;optlines++)
465-
{
466-
p=*optlines;
467-
468-
while (isspace((unsignedchar)*p))
469-
p++;
470-
if (strncmp(p,"port",4)!=0)
471-
continue;
472-
p+=4;
473-
while (isspace((unsignedchar)*p))
474-
p++;
475-
if (*p!='=')
476-
continue;
477-
p++;
478-
/* advance past any whitespace/quoting */
479-
while (isspace((unsignedchar)*p)||*p=='\''||*p=='"')
480-
p++;
481-
/* find end of value (not including any ending quote/comment!) */
482-
q=p;
483-
while (*q&&
484-
!(isspace((unsignedchar)*q)||
485-
*q=='\''||*q=='"'||*q=='#'))
486-
q++;
487-
/* and save the argument value */
488-
strlcpy(portstr,p,Min((q-p)+1,sizeof(portstr)));
489-
/* keep looking, maybe there is another */
494+
if (socket_dir[0]!='\0')
495+
snprintf(connstr+strlen(connstr),sizeof(connstr)-strlen(connstr),
496+
" host='%s'",socket_dir);
490497
}
491498
}
492-
}
493499

494-
/* Check environment */
495-
if (!portstr[0]&&getenv("PGPORT")!=NULL)
496-
strlcpy(portstr,getenv("PGPORT"),sizeof(portstr));
497-
498-
/* Else use compiled-in default */
499-
if (!portstr[0])
500-
snprintf(portstr,sizeof(portstr),"%d",DEF_PGPORT);
501-
502-
/*
503-
* We need to set a connect timeout otherwise on Windows the SCM will
504-
* probably timeout first
505-
*/
506-
snprintf(connstr,sizeof(connstr),
507-
"dbname=postgres port=%s connect_timeout=5",portstr);
500+
/* If we have a connection string, ping the server */
501+
if (connstr[0]!='\0')
502+
{
503+
ret=PQping(connstr);
504+
if (ret==PQPING_OK||ret==PQPING_NO_ATTEMPT)
505+
break;
506+
}
508507

509-
for (i=0;i<wait_seconds;i++)
510-
{
511-
ret=PQping(connstr);
512-
if (ret==PQPING_OK||ret==PQPING_NO_ATTEMPT)
513-
break;
514508
/* No response, or startup still in process; wait */
515509
#if defined(WIN32)
516510
if (do_checkpoint)
@@ -2009,7 +2003,6 @@ main(int argc, char **argv)
20092003
{
20102004
snprintf(postopts_file,MAXPGPATH, "%s/postmaster.opts",pg_data);
20112005
snprintf(pid_file,MAXPGPATH, "%s/postmaster.pid",pg_data);
2012-
snprintf(conf_file,MAXPGPATH, "%s/postgresql.conf",pg_data);
20132006
snprintf(backup_file,MAXPGPATH, "%s/backup_label",pg_data);
20142007
snprintf(recovery_file,MAXPGPATH, "%s/recovery.conf",pg_data);
20152008
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp