From: Alexander Lakhin <exclusion@gmail.com>
To: pgsql-bugs@lists.postgresql.org, PG Bug reporting form <noreply@postgresql.org>
Subject: Re: BUG #16161: pg_ctl stop fails sometimes (on Windows)
Date: Wed, 11 Dec 2019 23:30:01 +0300
Message-ID: <4d28c7e1-fe91-b9fd-3227-478e549b05d5@gmail.com> (raw)
In-Reply-To: <16161-7a985d2f1bbe8f71@postgresql.org>
References: <16161-7a985d2f1bbe8f71@postgresql.org>
11.12.2019 23:00, PG Bug reporting form wrote:
> The following bug has been logged on the website:
>
> Bug reference: 16161
> Logged by: Alexander Lakhin
> Email address: exclusion@gmail.com
> PostgreSQL version: 12.1
> Operating system: Windows
> Description:
>
> The regression tests on Windows sometimes fail with 'Permission denied'
> errors. For example:
> https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=dory&dt=2019-12-11%2007%3A45%3A33
>
> ============== shutting down postmaster ==============
> pg_ctl: could not open PID file
> "c:/pgbuildfarm/pgbuildroot/HEAD/pgsql.build/src/test/regress/./tmp_check/data/postmaster.pid":
> Permission denied
>
> This error occurs when pg_ctl is trying to open postmaster.pid while this
> file is in "delete pending" state
> (https://stackoverflow.com/questions/3764072/).
To reproduce the issue reliably I propose a simple modification to
synchronize unlink() with open() and a simple test
(sync_pid_ops+test.patch).
With the patch applied, `vcregress taptest src/test/restart` fails for
me on iteration 47, 6, 7, 42, 51, 26, ...
I see two ways to fix the issue:
1) Unlink postmaster.pid using rename operation (adopt the solution from
https://stackoverflow.com/questions/3764072/).
2) Ignore such 'Permission denied' error and just try to open the file
once again (attached fix_open_for_unlink.patch implements this).
I'm inclined to the second approach as pgwin32_open() already handles
two transient states (Windows-only), and it could be useful not only for
postmaster.pid, but for some other files.
Best regards,
Alexander
Attachments:
[text/x-patch] sync_pid_ops+test.patch (1.6K, ../4d28c7e1-fe91-b9fd-3227-478e549b05d5@gmail.com/3-sync_pid_ops+test.patch)
download | inline diff:diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.cindex de554e28cf..0594b6649f 100644--- a/src/backend/utils/init/miscinit.c+++ b/src/backend/utils/init/miscinit.c@@ -838,6 +838,13 @@ UnlinkLockFiles(int status, Datum arg)
{
ListCell *l;
+#ifdef WIN32+{+FILETIME time;+do { GetSystemTimePreciseAsFileTime(&time); }+while (((((ULONGLONG) time.dwHighDateTime) << 32) + time.dwLowDateTime) % 10000000L > (10000L));+}+#endif
foreach(l, lock_files)
{
char *curfile = (char *) lfirst(l);
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.cindex b0858411ed..3ab1608a5d 100644--- a/src/bin/pg_ctl/pg_ctl.c+++ b/src/bin/pg_ctl/pg_ctl.c@@ -276,6 +276,14 @@ get_pgpid(bool is_status_request)
exit(is_status_request ? 4 : 1);
}
+#ifdef WIN32+{+FILETIME time;+do { GetSystemTimePreciseAsFileTime(&time); }+while (((((ULONGLONG) time.dwHighDateTime) << 32) + time.dwLowDateTime) % 10000000L > (10000L));+}+#endif+
pidf = fopen(pid_file, "r");
if (pidf == NULL)
{
diff --git a/src/test/restart/t/001_restart.pl b/src/test/restart/t/001_restart.plnew file mode 100644index 0000000000..f0621d7f27--- /dev/null+++ b/src/test/restart/t/001_restart.pl@@ -0,0 +1,20 @@+use strict;+use warnings;+use PostgresNode;+use TestLib;+use Test::More;+use Config;++my $node = get_new_node('master');+$node->init();++for ( my $i = 1; $i <= 1000; $i++ ) {+ my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();+ diag( sprintf("%02d:%02d:%02d iteration %d", $hour, $min, $sec, $i) );+ $node->start;+ $node->stop;+}++ok(1, 'node start/stop test');++done_testing();
[text/x-patch] fix_open_for_unlink.patch (667B, ../4d28c7e1-fe91-b9fd-3227-478e549b05d5@gmail.com/4-fix_open_for_unlink.patch)
download | inline diff:diff --git a/src/port/open.c b/src/port/open.cindex f37afc7512..dad328f000 100644--- a/src/port/open.c+++ b/src/port/open.c@@ -135,6 +135,21 @@ pgwin32_open(const char *fileName, int fileFlags,...)
continue;
}
+ /*+ * ERROR_ACCESS_DENIED can be returned while the file is deleted+ * (Windows NT status code is STATUS_DELETE_PENDING).+ * https://stackoverflow.com/questions/3764072/+ * Try again for 1 second to check whether the "access denied"+ * condition persists.+ */+ if (err == ERROR_ACCESS_DENIED) {+ if (loops < 10) {+ pg_usleep(100000);+ loops++;+ continue;+ }+ }+
_dosmaperr(err);
return -1;
}
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: exclusion@gmail.com, noreply@postgresql.org
Subject: Re: BUG #16161: pg_ctl stop fails sometimes (on Windows)
In-Reply-To: <4d28c7e1-fe91-b9fd-3227-478e549b05d5@gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox