Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1ii1xv-000823-Sj for pgsql-bugs@arkaria.postgresql.org; Thu, 19 Dec 2019 20:00:08 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1ii1xu-0007EQ-Ja for pgsql-bugs@arkaria.postgresql.org; Thu, 19 Dec 2019 20:00:06 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1ii1xu-0007EJ-BW for pgsql-bugs@lists.postgresql.org; Thu, 19 Dec 2019 20:00:06 +0000 Received: from mail-lf1-x144.google.com ([2a00:1450:4864:20::144]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1ii1xr-0007Ox-Ki for pgsql-bugs@lists.postgresql.org; Thu, 19 Dec 2019 20:00:05 +0000 Received: by mail-lf1-x144.google.com with SMTP id v201so5199826lfa.11 for ; Thu, 19 Dec 2019 12:00:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-transfer-encoding:content-language; bh=3nmEi1RsIOkXB1W9U74CJfg4fqEILRNdXelDRy21I2E=; b=FBvTBz2WiO+tpg++6NMf1aJuE1P9sdKt1E/GRt3ppMLHoV7r6t2KFHX8dYPbPl0pnT vY0LPejbsh4BGg2f1bcpgLEJIEendRM2aHVOuTvC0EBtIPHafR91owJVIAfBCGABZSJk eawOnKmfss7IKbEyUi4BqF1YCH7bnvJmRYfHjH8KEtMQpDtHYaRdafDoWsID/KzvidE2 p2GUrKtbHbGBNiNex9bFsTqm3ToJG5owXCsqZJzgF9N5A/g/qb7W2uOzmCWg6gxn3b4B wPL0aILj9xWtM7P6QY0/e8o7lPo9UKe6YEfejf9Gm8EPR8bHIctZehKaDlpT8it3PBH9 F1vQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=3nmEi1RsIOkXB1W9U74CJfg4fqEILRNdXelDRy21I2E=; b=S9X0tYhrxv3ZgrC9Yq3czp0We62dFN0ACleR1rdu2V3sS060skAx82MR1DmpSOC5Mr FjblJs5FDZnL+EaxCSt9yiemqOLow8OttxpYNvO+jbWBoK4FjvmHgpCnbw+TPOU6wv8E G3nClUjalXqMfFiv8zGp5u3O9rNTqv6CbdZSWmHNsGLgR8upxDwrWbXIpJIO4GUs3eF6 cz30Keum+ePUeWWsi8fOtsR0lQdYYp/4JovA5rbI8Z/khpwPH8jk0dWhsV9dx5LzoKT7 keJPadWD9dhhxb82lBVfHfJO+ZVGqiw94DGdTujCjRCyals01BcxrOAzsqb2hZLiQygT aPbQ== X-Gm-Message-State: APjAAAWX4WLEEcrciOTgYFExrVyk6p90A/QcxxHaMRrOjEDswhiNmh3L h4M9mc6t9AvzWV/YkdnP+ISWxyAV X-Google-Smtp-Source: APXvYqxTl6Mzqnj70QzYMM3kk9lfwYit9s/bUPNPIdDnBkOd14FwLkQX3lomVhquwUc9iGZeWot3Kg== X-Received: by 2002:a19:c3cc:: with SMTP id t195mr6796424lff.144.1576785602587; Thu, 19 Dec 2019 12:00:02 -0800 (PST) Received: from [1.0.0.7] ([178.155.4.214]) by smtp.gmail.com with ESMTPSA id i9sm3009461lfd.6.2019.12.19.12.00.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Dec 2019 12:00:01 -0800 (PST) Subject: Re: BUG #16161: pg_ctl stop fails sometimes (on Windows) To: Tom Lane Cc: Kyotaro Horiguchi , pgsql-bugs@lists.postgresql.org References: <4741.1576684991@sss.pgh.pa.us> <26441.1576706955@sss.pgh.pa.us> <20191219.103948.2182167132387989763.horikyota.ntt@gmail.com> <32374.1576770248@sss.pgh.pa.us> From: Alexander Lakhin Message-ID: <5c7eaa87-8670-2008-3a15-337c133c12c2@gmail.com> Date: Thu, 19 Dec 2019 23:00:00 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.2 MIME-Version: 1.0 In-Reply-To: <32374.1576770248@sss.pgh.pa.us> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit Content-Language: en-US List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk 19.12.2019 18:44, Tom Lane wrote: > Alexander Lakhin writes: >> Please look at the patch that implements (2). It makes `vcregress >> recoverycheck` pass (and my demo restart test still passes too). > I think we could be a little smarter here. If the problem is > STATUS_DELETE_PENDING, doesn't that affect stat() as well? That is, > if stat() succeeds, we needn't wait, independently of whether it > says S_ISDIR or not? This seems like a noticeable improvement if > true, because it would mean that ordinary file-permission failures > also need not wait. We'd still get confused if we get a permission > failure on a containing directory rather than the file itself, but > that I'm prepared to dismiss as an uncommon case. > > Entirely-untested patch along this line attached. I have tested it with my demo restart test and it works. Yes, stat() is resulted in the CreateFile() call too, so it should fail the same way.  I haven't managed to catch both CreateFile() and stat() failing with STATUS_DELETE_PENDING (CreateFile() failed for me 37 times per 1000 loops), but I believe that sleep() will work correctly in this case. `vcregress recoverytest` is passed too. The DELETE_PENDING conflict now looks like this: 1 "8:50:44.9928200 PM","postgres.exe","2792","CreateFile","...\pgdata\postmaster.pid","SUCCESS","Desired Access: Read Attributes, Delete, ..." 2 "8:50:44.9928951 PM","postgres.exe","2792","QueryAttributeTagFile","...\pgdata\postmaster.pid","SUCCESS",... 3 "8:50:44.9929114 PM","pg_ctl.exe","2996","CreateFile","...\pgdata\postmaster.pid","DELETE PENDING","Desired Access: Generic Read, Disposition: Open, ..." 4 "8:50:44.9929162 PM","postgres.exe","2792","SetDispositionInformationFile","...\pgdata\postmaster.pid","SUCCESS","Delete: True" 5 "8:50:44.9929377 PM","postgres.exe","2792","CloseFile","...\pgdata\postmaster.pid","SUCCESS","" 6 "8:50:44.9932617 PM","pg_ctl.exe","2996","CreateFile","...\pgdata\postmaster.pid","NAME NOT FOUND","Desired Access: Read Attributes, ..." 7 "8:50:45.1042027 PM","pg_ctl.exe","2996","CreateFile","...\pgdata\postmaster.pid","NAME NOT FOUND","Desired Access: Generic Read, ..." 8 "8:50:45.9926445 PM","pg_ctl.exe","2396","CreateFile","...\pgdata\postmaster.pid","NAME NOT FOUND","Desired Access: Generic Read ..." Here 1, 2, 4, 5 are calls behind unlink() in postmaster, 3 is CreateFile() in pgwin32_open(), 6 is stat() in pgwin32_safestat(), then we have sleep for 0.1 sec, 7 is CreateFile() in pgwin32_open() again, and 8 is CreateFile() performed by a new pg_ctl instance. Maybe we should change the condition to 'if (stat(fileName, &st) != 0 && (err = GetLastError()) == ERROR_ACCESS_DENIED)' to avoid unnecessary sleep with a loop iteration... With this change the same conflict looks like this: 1 "10:23:12.9940793 PM","postgres.exe","1908","CreateFile","...\pgdata\postmaster.pid","SUCCESS","Desired Access: Read Attributes, ..." 2 "10:23:12.9941500 PM","postgres.exe","1908","QueryAttributeTagFile","...\pgdata\postmaster.pid","SUCCESS", ... 3 "10:23:12.9941713 PM","postgres.exe","1908","SetDispositionInformationFile","...\pgdata\postmaster.pid","SUCCESS","Delete: True" 4 "10:23:12.9941766 PM","pg_ctl.exe","2420","CreateFile","...\pgdata\postmaster.pid","DELETE PENDING","Desired Access: Generic Read ..." 5 "10:23:12.9941936 PM","postgres.exe","1908","CloseFile","...\pgdata\postmaster.pid","SUCCESS","" 6 "10:23:12.9945254 PM","pg_ctl.exe","2420","CreateFile","...\pgdata\postmaster.pid","NAME NOT FOUND","Desired Access: Read Attributes, ..." 7 "10:23:13.9940261 PM","pg_ctl.exe","1676","CreateFile","...\pgdata\postmaster.pid","NAME NOT FOUND","Desired Access: Generic Read, ..." Here 1, 2, 3, 5 are calls behind unlink() in postmaster, 4 is CreateFile() in pgwin32_open(), 6 is stat() in pgwin32_safestat(), 7 is CreateFile() performed by a new pg_ctl instance. `vcregress recoverytest` is passed. The log of access to the logical decoding slot now looks like this: 1 "10:37:22.9496662 PM","postgres.exe","2956","CreateFile","...\pgdata\pg_replslot\otherdb_slot","IS DIRECTORY","Desired Access: Generic Read, ..." 2 "10:37:22.9498061 PM","postgres.exe","2956","CreateFile","...\pgdata\pg_replslot\otherdb_slot","SUCCESS","Desired Access: Read Attributes, ..." 3 "10:37:22.9498478 PM","postgres.exe","2956","QueryInformationVolume","...\pgdata\pg_replslot\otherdb_slot","SUCCESS","VolumeCreationTime: ... " 4 "10:37:22.9498634 PM","postgres.exe","2956","QueryAllInformationFile","...\pgdata\pg_replslot\otherdb_slot","BUFFER OVERFLOW","CreationTime: ..." 5 "10:37:22.9498860 PM","postgres.exe","2956","CloseFile","...\pgdata\pg_replslot\otherdb_slot","SUCCESS","" 6 "10:37:22.9499936 PM","postgres.exe","2956","QueryOpen","...\pgdata\pg_replslot\otherdb_slot","FAST IO DISALLOWED","" 7 "10:37:22.9500733 PM","postgres.exe","2956","CreateFile","...\pgdata\pg_replslot\otherdb_slot","SUCCESS","Desired Access: ..." 8 "10:37:22.9500973 PM","postgres.exe","2956","QueryNetworkOpenInformationFile","...\pgdata\pg_replslot\otherdb_slot","SUCCESS","CreationTime:..." 9 "10:37:22.9501108 PM","postgres.exe","2956","CloseFile","...\pgdata\pg_replslot\otherdb_slot","SUCCESS","" > BTW ... it's likely that stat() here is actually going to invoke > pgwin32_safestat(), which has its own opinions about this, and > indeed seems to think we'll get ERROR_DELETE_PENDING. I think > that's harmless here, but it makes me wonder if we should use > a native Windows API instead of going through stat(). Yes, I would call native stat(), as we don't need to perform an excessive call to get file size (for directories). It seems that the check for ERROR_DELETE_PENDING was added to pgwin32_safestat() blindly, the issue wasn't reproduced at that time: https://www.postgresql.org/message-id/CAB7nPqRJV6trFta-Qzgi6j2feuYR2ZC%2BKHvWdHnbpDG2scTrxw%40mail.gmail.com >> As open(dir) is getting a little more expensive than before, maybe it's >> still worthwhile to patch fsync*(..., isdir,...). I can prepare such a >> patch if so. > I think we should leave that for later, so that the buildfarm can > actually test whatever logic we put in here. Agreed. It doesn't directly affect this bug and should be done separately. Best regards, Alexander