How to break connections TCP/IP by keepalive postg

2020-08-01 08:04发布

问题:

I have a system working with the client-server structure and PostgreSQL 8.4. My problem is that if a client is editing a record and lose his connection to the server, the TCPIP connection is still considered! So, the record stay allocated for the client in my database. I need the records to be free for edit in a few minutes. Therefore I set the KEEPALIVE configuration in my "postgresql.conf":

tcp_keepalives_idle = 60 # TCP_KEEPIDLE, in seconds; 
tcp_keepalives_interval = 60 # TCP_KEEPINTVL, in seconds; 
tcp_keepalives_count  = 5 # TCP_KEEPCNT

After making these settings and restart the server the system continues to function the same way: Just breaks the connection TCPIP after two hours and then deallocates the records in PostgreSQL. I need an efficient and safe way for the PostgreSQL to understand that it has to break these connections as configured!

回答1:

PostgreSQL on Windows does not support keepalive settings for one connection. It is using setsockopt(s, IPPROTO_TCP, TCP_KEEPIDLE, ...) which is IMHO Linux-specific.

You can implement a patch for Postgres so it uses SIO_KEEPALIVE_VALS. Something like this in src/backend/libpq/pqcomm.c in StreamConnection function.

{
    DWORD bytesReturned = 0;
    tcp_keepalive vals;
    vals.keepalivetime = 60*1000; /* milliseconds */
    vals.keepaliveinterval = 60*1000; /* milliseconds */
    vals.onoff = 1;
    err = WSAIoctl(
        port->sock,
        SIO_KEEPALIVE_VALS,
        (char *)&vals, sizeof(vals), NULL, 0,
        &bytesReturned, NULL, NULL);
    if (err == -1) {
        elog(LOG, "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %m");
    }
}

Or you can set system-wide settings in Windows registry HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters using KeepAliveInterval and KeepAliveTime settings (count is always 10 on Windows Vista and later).