Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eMgT0-0006A1-E6 for pgsql-bugs@arkaria.postgresql.org; Wed, 06 Dec 2017 20:38:54 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eMgSz-0003SY-NJ for pgsql-bugs@arkaria.postgresql.org; Wed, 06 Dec 2017 20:38:53 +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_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1eMgSz-0003SO-Du for pgsql-bugs@lists.postgresql.org; Wed, 06 Dec 2017 20:38:53 +0000 Received: from mail-wr0-x22d.google.com ([2a00:1450:400c:c0c::22d]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1eMgSv-0007Lt-Mz for pgsql-bugs@postgresql.org; Wed, 06 Dec 2017 20:38:52 +0000 Received: by mail-wr0-x22d.google.com with SMTP id q9so5250006wre.7 for ; Wed, 06 Dec 2017 12:38:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=vgLP5qeRTwx3N9fnw+HHIT+4tc6SzLZZ5cwch1LZqvU=; b=lFfaCTjakmQIenQOkgdzgEBIJADhWZo3oxsPufN//XsNHkTGvHwSYFzAcQ3NYj1Fbq jLrRBhvIowkmjNx3NBTre6CLq8IcA5LuCuz1BY7LPNX9xN0nPC9tR4hoMaDSY1Ts5EAb xjWedKOP1PlgKudx8AytIiS9QlWrGlmfWweB26JrEvr9IhhWGYL50g0OsYglqx40PvnM 36rg8gtG645A2Ssgo7xqxctWwhtAofLzHTX7tHthiMFL7XwmJl20I6RYvWwP5n56aHBc STW6wNO4Tfa7WAtHu5g/FJYUC4SRv/X6ZPsaekQWi+2gtwb0oH0Oj8t4kmJTvJNoeUoL j7iQ== 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 :content-transfer-encoding; bh=vgLP5qeRTwx3N9fnw+HHIT+4tc6SzLZZ5cwch1LZqvU=; b=EcGS73k6yjvh3VJg1eoGYdkGOSwzcas8Gh7M+XZkkHanvWDBDWjxNf1uOWdAE4gg9+ 9BPNGvWi4k3wJ+IPYheGwhy0qLNZWxB/ySVKkZ7zLObvv27WaA3hnkXtxql9eWFNpfNE zosGpMYWn+sB0in+vks1CKjyDkqZ9gIv9RLNDR0JDWYD1OMtlR1vOyO2THBc+KwCBZad 2wX+AifuBoux5HF0RqBbmym2jz2ADLnU1kXAkfqxX46cWVZdgCjgKJhlp4JPwOQhFOBF +wdCpzNSTnvnAVZp25En7nHhcd1Pb84y1apmIBNbStqFYrXlxCoAES9nLeKGWuBguyRU mvAg== X-Gm-Message-State: AJaThX7EPx1n5ikNNLgqXy8+FKjFZzVfKcv3+ZtGvVqbIhcfEiU1tYwQ C27NhrRr3EHvh2RjZU4AsGwz7JALlGpR+F9Q4tOrF+WUAStRjxxKB9mpf9928S0vcm0xvzo2VFJ AM0KnPoDkPokEPGK3cXr16s/kSY9k4YMM7c6yC6RHfwMzndvj+n5nW5kcVvN2TIUmkk4B5zqxQQ t7gLdV X-Google-Smtp-Source: AGs4zMZ4Y2Oz24vWD0aMWnt8R9gZRilvOnJ3dmqt+Eo+0NTM9Zn3ISVV1kyFtVzUUhZTTFzlg5xrxw== X-Received: by 10.223.161.158 with SMTP id u30mr21385073wru.200.1512592726759; Wed, 06 Dec 2017 12:38:46 -0800 (PST) Received: from [10.137.2.19] (ip-78-102-97-226.net.upcbroadband.cz. [78.102.97.226]) by smtp.gmail.com with ESMTPSA id 2sm3740317wre.17.2017.12.06.12.38.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Dec 2017 12:38:45 -0800 (PST) Subject: Re: BUG #14932: SELECT DISTINCT val FROM table gets stuck in an infinite loop To: Andres Freund Cc: "Todd A. Cook" , Tom Lane , Thomas Munro , PostgreSQL Bugs References: <20171127185700.1470.20362@wrigleys.postgresql.org> <7a22f496-92b5-d199-984e-183965918304@blackducksoftware.com> <20171127221041.mezzysc4zcfsqkyc@alap3.anarazel.de> <17357.1511841783@sss.pgh.pa.us> <9cd29b81-7ba1-91a2-f491-9014f4ac87e6@blackducksoftware.com> <2a76784c-06cb-46ec-35be-9895d144b839@2ndquadrant.com> <263b03b1-3e1c-49ca-165a-8ac6751419c4@2ndquadrant.com> <20171206193545.3imvbfwjgrmuho3s@alap3.anarazel.de> <790BC80E-D8E5-499B-A1E3-8EE0752B53ED@anarazel.de> From: Tomas Vondra Message-ID: <06523583-b9c5-1424-ef0a-1fc8063e9ed7@2ndquadrant.com> Date: Wed, 6 Dec 2017 21:38:42 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 In-Reply-To: <790BC80E-D8E5-499B-A1E3-8EE0752B53ED@anarazel.de> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On 12/06/2017 09:00 PM, Andres Freund wrote: > > > On December 6, 2017 11:57:44 AM PST, Tomas Vondra wrote: >> >> >> On 12/06/2017 08:35 PM, Andres Freund wrote: >>> On 2017-12-06 20:32:24 +0100, Tomas Vondra wrote: >>>> On 12/05/2017 11:01 PM, Tomas Vondra wrote: >>>>> >>>>> Based on the initial discussion, the problem here is twofold. >>>>> >>>>> Firstly, the code assumes that if it gets certain number of bucket >>>>> collisions (essentially, the initial bucket and certain number of >>>>> neighboring buckets already being full), making the table larger is >>>>> guaranteed to reduce the number of collisions. >>>>> >>>>> Which is obviously untrue for duplicate hash values, but it may >> also >>>>> happen for distinct hash values that form a chain (think a sequence >> of >>>>> hash values 1,2,3,4,5,6,7,...,K - that is never gonna get fixed). >>> >>>> I've managed to construct (by sheer brute force) an example that >> breaks >>>> simplehash in this way. It triggers the growth by having a sequence >> of >>>> distinct but consecutive hash values, e.g. 1, 2, 3, 4, ..., 1000, >> and >>>> then trying to insert a value with duplicate hash (say, 4). >>> >>> I fail to be excited by this. That's possible for any sort of >> hashtable >>> in some way. You might hit issues due to resizing or due to lookup >>> performance, but you'll hit problem. That's a fairly fundamental >> issue >>> of pure hashtables. >>> >> >> Eh? I think you misunderstood the issue this triggers. I'm perfectly >> fine with poor lookup performance - that's expected and reasonable. But >> it actually triggers the same behavior as the already presented >> example, >> i.e. the hash table grows indefinitely (so eventually gets OOM). >> >> I really doubt allocating 3GB of memory (which is when my laptop gives >> up and kills the query) to do distinct on 50MB table is a sane >> behavior. >> Even if the table is constructed in so intentionally evil way. > > No, I got that. I just don't think time and memory are that different. > It's one thing when the hash table takes longer to lookup something or when it consumes a bit more memory. Say, ~2x more than needed, give or take. I'm perfectly fine with that, particularly when it's a worst-case evil data set like this one. But it's a very different situation when it consumes tens of GBs of memory (essentially building the largest possible hash table, despite the load factor dropping to 0), because the code grows the hash table assuming it will magically resolve the collisions. And even if the machine has enough RAM, it's guaranteed to fail we'll try growing the table beyond that limit. I don't quite understand why should that be OK? It doesn't seem very sane to me. FWIW I've constructed the data sets for two reasons - to convince myself that my understanding of the simplehash code is correct, and to provide a data set triggering the other growth condition in simplehash code. My understanding is that if we stop growing the table after the load factor drops below some threshold (as TL proposed earlier in this thread), it should address both of these cases. cheers -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services