In pg_ctl, work around ERROR_SHARING_VIOLATION on the postmaster log file.
On Windows, we use CMD.EXE to redirect the postmaster's stdout/stderr
into a log file. CMD.EXE will open that file with non-sharing-friendly
parameters, and the file will remain open for a short time after the
postmaster has removed postmaster.pid. This can result in an
ERROR_SHARING_VIOLATION failure if we attempt to start a new postmaster
immediately with the same log file (e.g. during "pg_ctl restart").
This seems to explain intermittent buildfarm failures we've been seeing
on Windows machines.
To fix, just open and close the log file using our own pgwin32_open(),
which will wait if necessary to avoid the failure. (Perhaps someday
we should stop using CMD.EXE, but that would be a far more complex
patch, and it doesn't seem worth the trouble ... yet.)
Back-patch to v12. This only solves the problem when frontend fopen()
is redirected to pgwin32_fopen(), which has only been true since commit
0ba06e0bf
. Hence, no point in back-patching further, unless we care
to back-patch that change too.
Diagnosis and patch by Alexander Lakhin (bug #16154).
Discussion: https://postgr.es/m/16154-1ccf0b537b24d5e0@postgresql.org
This commit is contained in:
parent
547e454cbc
commit
be9d4b9280
|
@ -519,8 +519,29 @@ start_postmaster(void)
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
|
|
||||||
if (log_file != NULL)
|
if (log_file != NULL)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* First, touch the log file. The main value of this is that if the
|
||||||
|
* file is still locked by a previous postmaster run, we'll wait until
|
||||||
|
* it comes free, instead of failing with ERROR_SHARING_VIOLATION.
|
||||||
|
* (It'd be better to open the file in a sharing-friendly mode, but we
|
||||||
|
* can't use CMD.EXE to do that, so work around it. Note that the
|
||||||
|
* previous postmaster will still have the file open for a short time
|
||||||
|
* after removing postmaster.pid.)
|
||||||
|
*/
|
||||||
|
FILE *fd = fopen(log_file, "a");
|
||||||
|
|
||||||
|
if (fd == NULL)
|
||||||
|
{
|
||||||
|
write_stderr(_("%s: could not create log file \"%s\": %s\n"),
|
||||||
|
progname, log_file, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
snprintf(cmd, MAXPGPATH, "CMD /C \"\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1\"",
|
snprintf(cmd, MAXPGPATH, "CMD /C \"\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1\"",
|
||||||
exec_path, pgdata_opt, post_opts, DEVNULL, log_file);
|
exec_path, pgdata_opt, post_opts, DEVNULL, log_file);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
snprintf(cmd, MAXPGPATH, "CMD /C \"\"%s\" %s%s < \"%s\" 2>&1\"",
|
snprintf(cmd, MAXPGPATH, "CMD /C \"\"%s\" %s%s < \"%s\" 2>&1\"",
|
||||||
exec_path, pgdata_opt, post_opts, DEVNULL);
|
exec_path, pgdata_opt, post_opts, DEVNULL);
|
||||||
|
|
Loading…
Reference in New Issue