Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kWQe5-0007Ra-Jy for pgsql-bugs@arkaria.postgresql.org; Sat, 24 Oct 2020 21:00:13 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1kWQe3-0001TN-DP for pgsql-bugs@arkaria.postgresql.org; Sat, 24 Oct 2020 21:00:11 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kWQe3-0001T3-5U for pgsql-bugs@lists.postgresql.org; Sat, 24 Oct 2020 21:00:11 +0000 Received: from mail-lj1-x244.google.com ([2a00:1450:4864:20::244]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1kWQdw-0003aZ-Am for pgsql-bugs@lists.postgresql.org; Sat, 24 Oct 2020 21:00:09 +0000 Received: by mail-lj1-x244.google.com with SMTP id i2so5479937ljg.4 for ; Sat, 24 Oct 2020 14:00:04 -0700 (PDT) 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-language; bh=K9dNkuWcylsGsdi+pUCisSYRL9KqYJQy0izH+QKyVQg=; b=r/xyCsgzbpJdaKSzp/UZdouOMVb3jdt5OBzewxLfW4+OCFJi7lWa08WOVePVu5BdZd HUrmP0n0qZOlzoQ5ltRa7Y9MH+II3FUmq24wKTTRRemRzH9yg7Z9DlacdcNSOnmNxu+e 7zZMIO0ozcXzpRtEWJ5oa63beFEinl/vmcJ22X3fzGYrMshh8DAxpvmLpAjrYm4LBAOC t7UYRfw0uejxyOZCTC2kZWoWkZgGiV1W4xk5Dlp5bTm/c580Z07d2BlNG0VewKq905jW ix43YvqNUhgYH5RPtL4qZV09WtPahuKZTPm28h8FxMLoo5X7b94sA9HE4HrIGm0fJ+o1 +GZA== 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-language; bh=K9dNkuWcylsGsdi+pUCisSYRL9KqYJQy0izH+QKyVQg=; b=o49GLC8rVnubQ7b744uyHlPX9Ca1t/9HkF5jpzhlDwduoqpOVKnSDe6JdBn/lMcPxr S1iI1b7Dmdkyit+0dkx33dEnhAoQ/MLbm6o90S+T3Q6gO6mHxhPbqP3xjVC0z82w6YUC ECGssCpagJEF/YSFeJ4Lnfj7BKqBAEq/gSHz/sV2H4LsXXdL1ckn+50npZbZH4/iO92+ hzgyk5kHseP9+q7iCkOdckYfloaB3qKV0QyBIM1o7g602EOaqM4Mb9Prp5P2EEHA3w4E RfyXF+E1GMIqhCdK+JF01ss3OhsuaqebVm83GBspmRBn/JhlkQQ1RAQaPvGKY85N0jeE fm1Q== X-Gm-Message-State: AOAM533WiVx+F7KWnoDz9zkr3HWqpvj16nKtFRyY99YBAbhMvyZ7QvEp iym32oYx3JYH3SmeajTg9WXR9HGlGMw= X-Google-Smtp-Source: ABdhPJyTdt8pJfDbdqEa42crjT8O9Wl7lLwMLjQCM7vqqw70lHFCt5CbL9cCigHNV1zrcSB5E5IjXQ== X-Received: by 2002:a2e:7601:: with SMTP id r1mr2882309ljc.54.1603573201925; Sat, 24 Oct 2020 14:00:01 -0700 (PDT) Received: from [1.0.0.7] ([178.155.6.144]) by smtp.gmail.com with ESMTPSA id m20sm539301lfr.9.2020.10.24.14.00.01 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 24 Oct 2020 14:00:01 -0700 (PDT) Subject: Re: BUG #16678: The ecpg connect/test5 test sometimes fails on Windows To: Tom Lane Cc: pgsql-bugs@lists.postgresql.org References: <16678-253e48d34dc0c376@postgresql.org> <434311.1603135136@sss.pgh.pa.us> <383222.1603561145@sss.pgh.pa.us> From: Alexander Lakhin Message-ID: Date: Sun, 25 Oct 2020 00:00:00 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: <383222.1603561145@sss.pgh.pa.us> Content-Type: multipart/mixed; boundary="------------C835F28B0FCDAF56A0F9DF6F" Content-Language: en-US List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk This is a multi-part message in MIME format. --------------C835F28B0FCDAF56A0F9DF6F Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit 24.10.2020 20:39, Tom Lane wrote: > Alexander Lakhin writes: >> So I've also tested on Windows the following version: >>         secure_close(MyProcPort); >>         shutdown(MyProcPort->sock, SD_SEND); >>         for(;;) { >>             char buffer[1000]; >>             int res = recv(MyProcPort->sock, buffer, 1000, 0); >>             if (res <= 0) >>                 break; >>         } >>         closesocket(MyProcPort->sock); >> And it works too. > I'm afraid this cure is probably worse than the disease, because > now the backend's exiting is held hostage by whether the client > closes its socket (and the resulting FIN reaches us, which it > might not if there's a network problem). On a next level of this game we could make something like that:         secure_close(MyProcPort);         timeout = 1000; // 1 sec         setsockopt(MyProcPort->sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));         shutdown(MyProcPort->sock, SD_SEND);         for(;;) {             char buffer[1000];             int res = recv(MyProcPort->sock, buffer, 1000, 0);             if (res <= 0) {                 break;             }         }         closesocket(MyProcPort->sock); (I can't get this timeout working yet.) But I'm inclined to stay on the previous level with "shutdown && closesocket" as recommended for server side: https://docs.microsoft.com/en-us/windows/win32/winsock/graceful-shutdown-linger-options-and-socket-closure-2 Please look at the draft patch. By the way, the delay added to pqReadData():     pg_usleep(10000L); // Wait for 10 ms. makes the src/test/recovery test fail on Linux too (pg_ctl can't stop the primary node). So it seems that slow reading from a socket breaks things not only on Windows and the fix should be more comprehensive. Best regards, Alexander --------------C835F28B0FCDAF56A0F9DF6F Content-Type: text/x-patch; charset=UTF-8; name="graceful_socket_shutdown.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="graceful_socket_shutdown.patch" diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index ac986c0505..df681df103 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -285,16 +285,26 @@ socket_close(int code, Datum arg) * call this, so this is safe when interrupting BackendInitialize(). */ secure_close(MyProcPort); +#ifdef WIN32 + /* + * Shutdown and close the socket explicitly to allow clients to receive + * a message sent just before the backend exit, e.g., a FATAL error. + * Otherwise Windows resets the connection and doesn't transmit data + * when the process dies. + */ + shutdown(MyProcPort->sock, SD_BOTH); + closesocket(MyProcPort->sock); +#endif /* - * Formerly we did an explicit close() here, but it seems better to - * leave the socket open until the process dies. This allows clients - * to perform a "synchronous close" if they care --- wait till the - * transport layer reports connection closure, and you can be sure the - * backend has exited. + * Formerly we did an explicit close() here on other OSes too, but it + * seems better to leave the socket open until the process dies. + * This allows clients to perform a "synchronous close" if they care + * --- wait till the transport layer reports connection closure, + * and you can be sure the backend has exited. * - * We do set sock to PGINVALID_SOCKET to prevent any further I/O, - * though. + * We do set sock to PGINVALID_SOCKET to prevent any further I/O + * in any case. */ MyProcPort->sock = PGINVALID_SOCKET; } --------------C835F28B0FCDAF56A0F9DF6F--