Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9a86f03

Browse files
committed
Rearrange postmaster's startup sequence for better syslogger results.
This is a second try at what commit 57431a9 tried to do, namely, launch the syslogger before we open postmaster sockets so that our messages about the sockets end up in the syslogger files. That commit fell foul of a bunch of subtle issues caused by trying to launch a postmaster child process before creating shared memory. Rather than messing with that interaction, let's postpone opening the sockets till after we launch the syslogger. This would not have been terribly safe before commit 7de19fb, because we relied on socket opening to detect whether any competing postmasters were using the same port number. But now that we choose IPC keys without regard to the port number, there's no interaction to worry about. Also delay creation of the external PID file (if requested) till after the sockets are open, since external code could plausibly be relying on that ordering of events. And postpone most of the work of RemovePgTempFiles() so that that potentially-slow processing still happens after we make the external PID file. We have to be a bit careful about that last though: as noted in the discussion subsequent to bug #15804, EXEC_BACKEND builds still have to clear the parameter-file temp dir before launching the syslogger. Patch by me; thanks to Michael Paquier for review/testing. Discussion: https://postgr.es/m/15804-3721117bf40fb654@postgresql.org
1 parent 75f46ea commit 9a86f03

File tree

4 files changed

+116
-102
lines changed

4 files changed

+116
-102
lines changed

src/backend/postmaster/postmaster.c

Lines changed: 108 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -993,7 +993,113 @@ PostmasterMain(int argc, char *argv[])
993993
*/
994994
InitializeMaxBackends();
995995

996-
/* Report server startup in log */
996+
/*
997+
* Set up shared memory and semaphores.
998+
*/
999+
reset_shared();
1000+
1001+
/*
1002+
* Estimate number of openable files. This must happen after setting up
1003+
* semaphores, because on some platforms semaphores count as open files.
1004+
*/
1005+
set_max_safe_fds();
1006+
1007+
/*
1008+
* Set reference point for stack-depth checking.
1009+
*/
1010+
set_stack_base();
1011+
1012+
/*
1013+
* Initialize pipe (or process handle on Windows) that allows children to
1014+
* wake up from sleep on postmaster death.
1015+
*/
1016+
InitPostmasterDeathWatchHandle();
1017+
1018+
#ifdef WIN32
1019+
1020+
/*
1021+
* Initialize I/O completion port used to deliver list of dead children.
1022+
*/
1023+
win32ChildQueue = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
1024+
if (win32ChildQueue == NULL)
1025+
ereport(FATAL,
1026+
(errmsg("could not create I/O completion port for child queue")));
1027+
#endif
1028+
1029+
#ifdef EXEC_BACKEND
1030+
/* Write out nondefault GUC settings for child processes to use */
1031+
write_nondefault_variables(PGC_POSTMASTER);
1032+
1033+
/*
1034+
* Clean out the temp directory used to transmit parameters to child
1035+
* processes (see internal_forkexec, below). We must do this before
1036+
* launching any child processes, else we have a race condition: we could
1037+
* remove a parameter file before the child can read it. It should be
1038+
* safe to do so now, because we verified earlier that there are no
1039+
* conflicting Postgres processes in this data directory.
1040+
*/
1041+
RemovePgTempFilesInDir(PG_TEMP_FILES_DIR, true, false);
1042+
#endif
1043+
1044+
/*
1045+
* Forcibly remove the files signaling a standby promotion request.
1046+
* Otherwise, the existence of those files triggers a promotion too early,
1047+
* whether a user wants that or not.
1048+
*
1049+
* This removal of files is usually unnecessary because they can exist
1050+
* only during a few moments during a standby promotion. However there is
1051+
* a race condition: if pg_ctl promote is executed and creates the files
1052+
* during a promotion, the files can stay around even after the server is
1053+
* brought up to new master. Then, if new standby starts by using the
1054+
* backup taken from that master, the files can exist at the server
1055+
* startup and should be removed in order to avoid an unexpected
1056+
* promotion.
1057+
*
1058+
* Note that promotion signal files need to be removed before the startup
1059+
* process is invoked. Because, after that, they can be used by
1060+
* postmaster's SIGUSR1 signal handler.
1061+
*/
1062+
RemovePromoteSignalFiles();
1063+
1064+
/* Do the same for logrotate signal file */
1065+
RemoveLogrotateSignalFiles();
1066+
1067+
/* Remove any outdated file holding the current log filenames. */
1068+
if (unlink(LOG_METAINFO_DATAFILE) < 0 && errno != ENOENT)
1069+
ereport(LOG,
1070+
(errcode_for_file_access(),
1071+
errmsg("could not remove file \"%s\": %m",
1072+
LOG_METAINFO_DATAFILE)));
1073+
1074+
/*
1075+
* If enabled, start up syslogger collection subprocess
1076+
*/
1077+
SysLoggerPID = SysLogger_Start();
1078+
1079+
/*
1080+
* Reset whereToSendOutput from DestDebug (its starting state) to
1081+
* DestNone. This stops ereport from sending log messages to stderr unless
1082+
* Log_destination permits. We don't do this until the postmaster is
1083+
* fully launched, since startup failures may as well be reported to
1084+
* stderr.
1085+
*
1086+
* If we are in fact disabling logging to stderr, first emit a log message
1087+
* saying so, to provide a breadcrumb trail for users who may not remember
1088+
* that their logging is configured to go somewhere else.
1089+
*/
1090+
if (!(Log_destination & LOG_DESTINATION_STDERR))
1091+
ereport(LOG,
1092+
(errmsg("ending log output to stderr"),
1093+
errhint("Future log output will go to log destination \"%s\".",
1094+
Log_destination_string)));
1095+
1096+
whereToSendOutput = DestNone;
1097+
1098+
/*
1099+
* Report server startup in log. While we could emit this much earlier,
1100+
* it seems best to do so after starting the log collector, if we intend
1101+
* to use one.
1102+
*/
9971103
ereport(LOG,
9981104
(errmsg("starting %s", PG_VERSION_STR)));
9991105

@@ -1172,51 +1278,13 @@ PostmasterMain(int argc, char *argv[])
11721278
if (!listen_addr_saved)
11731279
AddToDataDirLockFile(LOCK_FILE_LINE_LISTEN_ADDR, "");
11741280

1175-
/*
1176-
* Set up shared memory and semaphores.
1177-
*/
1178-
reset_shared();
1179-
1180-
/*
1181-
* Estimate number of openable files. This must happen after setting up
1182-
* semaphores, because on some platforms semaphores count as open files.
1183-
*/
1184-
set_max_safe_fds();
1185-
1186-
/*
1187-
* Set reference point for stack-depth checking.
1188-
*/
1189-
set_stack_base();
1190-
1191-
/*
1192-
* Initialize pipe (or process handle on Windows) that allows children to
1193-
* wake up from sleep on postmaster death.
1194-
*/
1195-
InitPostmasterDeathWatchHandle();
1196-
1197-
#ifdef WIN32
1198-
1199-
/*
1200-
* Initialize I/O completion port used to deliver list of dead children.
1201-
*/
1202-
win32ChildQueue = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
1203-
if (win32ChildQueue == NULL)
1204-
ereport(FATAL,
1205-
(errmsg("could not create I/O completion port for child queue")));
1206-
#endif
1207-
12081281
/*
12091282
* Record postmaster options. We delay this till now to avoid recording
1210-
* bogus options (eg, NBuffers too high for available memory).
1283+
* bogus options (eg, unusable port number).
12111284
*/
12121285
if (!CreateOptsFile(argc, argv, my_exec_path))
12131286
ExitPostmaster(1);
12141287

1215-
#ifdef EXEC_BACKEND
1216-
/* Write out nondefault GUC settings for child processes to use */
1217-
write_nondefault_variables(PGC_POSTMASTER);
1218-
#endif
1219-
12201288
/*
12211289
* Write the external PID file if requested
12221290
*/
@@ -1247,60 +1315,6 @@ PostmasterMain(int argc, char *argv[])
12471315
*/
12481316
RemovePgTempFiles();
12491317

1250-
/*
1251-
* Forcibly remove the files signaling a standby promotion request.
1252-
* Otherwise, the existence of those files triggers a promotion too early,
1253-
* whether a user wants that or not.
1254-
*
1255-
* This removal of files is usually unnecessary because they can exist
1256-
* only during a few moments during a standby promotion. However there is
1257-
* a race condition: if pg_ctl promote is executed and creates the files
1258-
* during a promotion, the files can stay around even after the server is
1259-
* brought up to new master. Then, if new standby starts by using the
1260-
* backup taken from that master, the files can exist at the server
1261-
* startup and should be removed in order to avoid an unexpected
1262-
* promotion.
1263-
*
1264-
* Note that promotion signal files need to be removed before the startup
1265-
* process is invoked. Because, after that, they can be used by
1266-
* postmaster's SIGUSR1 signal handler.
1267-
*/
1268-
RemovePromoteSignalFiles();
1269-
1270-
/* Do the same for logrotate signal file */
1271-
RemoveLogrotateSignalFiles();
1272-
1273-
/* Remove any outdated file holding the current log filenames. */
1274-
if (unlink(LOG_METAINFO_DATAFILE) < 0 && errno != ENOENT)
1275-
ereport(LOG,
1276-
(errcode_for_file_access(),
1277-
errmsg("could not remove file \"%s\": %m",
1278-
LOG_METAINFO_DATAFILE)));
1279-
1280-
/*
1281-
* If enabled, start up syslogger collection subprocess
1282-
*/
1283-
SysLoggerPID = SysLogger_Start();
1284-
1285-
/*
1286-
* Reset whereToSendOutput from DestDebug (its starting state) to
1287-
* DestNone. This stops ereport from sending log messages to stderr unless
1288-
* Log_destination permits. We don't do this until the postmaster is
1289-
* fully launched, since startup failures may as well be reported to
1290-
* stderr.
1291-
*
1292-
* If we are in fact disabling logging to stderr, first emit a log message
1293-
* saying so, to provide a breadcrumb trail for users who may not remember
1294-
* that their logging is configured to go somewhere else.
1295-
*/
1296-
if (!(Log_destination & LOG_DESTINATION_STDERR))
1297-
ereport(LOG,
1298-
(errmsg("ending log output to stderr"),
1299-
errhint("Future log output will go to log destination \"%s\".",
1300-
Log_destination_string)));
1301-
1302-
whereToSendOutput = DestNone;
1303-
13041318
/*
13051319
* Initialize stats collection subsystem (this does NOT start the
13061320
* collector process!)

src/backend/storage/file/fd.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,6 @@ static int FreeDesc(AllocateDesc *desc);
307307

308308
static void AtProcExit_Files(int code, Datum arg);
309309
static void CleanupTempFiles(bool isCommit, bool isProcExit);
310-
static void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok,
311-
bool unlink_all);
312310
static void RemovePgTempRelationFiles(const char *tsdirname);
313311
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname);
314312

@@ -2919,11 +2917,10 @@ RemovePgTempFiles(void)
29192917

29202918
/*
29212919
* In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
2922-
* DataDir as well.
2920+
* DataDir as well. However, that is *not* cleaned here because doing so
2921+
* would create a race condition. It's done separately, earlier in
2922+
* postmaster startup.
29232923
*/
2924-
#ifdef EXEC_BACKEND
2925-
RemovePgTempFilesInDir(PG_TEMP_FILES_DIR, true, false);
2926-
#endif
29272924
}
29282925

29292926
/*
@@ -2941,7 +2938,7 @@ RemovePgTempFiles(void)
29412938
* (These two flags could be replaced by one, but it seems clearer to keep
29422939
* them separate.)
29432940
*/
2944-
static void
2941+
void
29452942
RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
29462943
{
29472944
DIR *temp_dir;

src/include/storage/fd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ extern void AtEOXact_Files(bool isCommit);
135135
extern void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid,
136136
SubTransactionId parentSubid);
137137
extern void RemovePgTempFiles(void);
138+
extern void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok,
139+
bool unlink_all);
138140
extern bool looks_like_temp_rel_name(const char *name);
139141

140142
extern int pg_fsync(int fd);

src/include/utils/pidfile.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
*
2929
* Lines 6 and up are added via AddToDataDirLockFile() after initial file
3030
* creation; also, line 5 is initially empty and is changed after the first
31-
* Unix socket is opened.
31+
* Unix socket is opened. Onlookers should not assume that lines 4 and up
32+
* are filled in any particular order.
3233
*
3334
* Socket lock file(s), if used, have the same contents as lines 1-5, with
3435
* line 5 being their own directory.

0 commit comments

Comments
 (0)