Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eMLHD-0000cd-18 for pgsql-bugs@arkaria.postgresql.org; Tue, 05 Dec 2017 22:01:19 +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 1eMLHC-0005Bm-F3 for pgsql-bugs@arkaria.postgresql.org; Tue, 05 Dec 2017 22:01:18 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1eMLHC-0005Bc-2J for pgsql-bugs@lists.postgresql.org; Tue, 05 Dec 2017 22:01:18 +0000 Received: from mail-wm0-x22e.google.com ([2a00:1450:400c:c09::22e]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1eMLH4-00045m-OW for pgsql-bugs@postgresql.org; Tue, 05 Dec 2017 22:01:16 +0000 Received: by mail-wm0-x22e.google.com with SMTP id n138so3972881wmg.2 for ; Tue, 05 Dec 2017 14:01:10 -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=veRXOZIQ/dF0f+g2XUsaBzMXv8yw+Y6U+LAZm9ODNx4=; b=Q5HiT+f4eJOPlGgibtT+rsGvqwmDU5s3unMKxuABLWZub0+n5gyffO+ITQBKpD2sEE e/PPObq7Ig7MSSaxE9hiRrcZgQt3RAD57z+B5SePHzrHsU3VDsdLlkjPQ19HcsfW6hZ6 F3dsbt5+0AywGH27bqZ8mUoJMMm4PB1/LAGlt2+iAgCpExA5OPkVazDPtnlyMgkXgiS7 yXFA5ArkF3uBy8QZm3fnh9C/HSKk/esPJqw+Je3rxEo8KvktON9vdGEnxFlLr7ZYJCAO vY7y/QcgYE4jwEpN027JJgXNcwhM35xmX8PlnpHw03nZyGIdrtOmakIpcQITRtu2uyEA YMvg== 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=veRXOZIQ/dF0f+g2XUsaBzMXv8yw+Y6U+LAZm9ODNx4=; b=URMIgEmMIMxyVzzjVqJVZ6pd2uLGOCqxvUVmdC+bWU9a3nW3ieFIQK0MBcwIhbUWfd gqK3gHOGX5XU4geFNTqFGr00cVA6pZs4hD1g4eqCQJNZed2PKuuTU3raPudmyhZS8LpL kwFRV+yB9CycUlcKwxxTCN/JkQA4TDxBw7wtfrZ7/teZIAHjUH7QAYqWl8xLR/9pFj8L PZZopBp35Lyf0KsCCH5WIDk3cjGc5Wj0za+8qNFJo/2Z013ZKjhEm1fntIB7elhDH/Ca lGGZKOnlZl7mPcPXQvMdUvDpR1DtpHUvRGsgPLC7OgzO+MEzc8A1fzj41rDYGTK6vk/3 lrSA== X-Gm-Message-State: AJaThX7Sy8BWs6c/EAcEQecEC5fEp2+1/wz4jU26o/92AOg52LSgJBhS VNTG7r1WEFVum9XsFjqMpv6mrzcKlPv0hCKg/LWEbY0h20lFm1mJYD5vfIH3UnZrSwa4+Wk3Olc uqYkMc3nz8n1Yg7mykXTgRSkQWNNEnn96BGmMfunbiEdn4yULtWycKNTPpTGr1ipuHK1ffdqJF+ IiVGzh X-Google-Smtp-Source: AGs4zMbE0HT9sgIfOOF3lvQfr4m4tUHwyZV+4FiMnDLZHwVGvkxe+Ca67Mx4DpI1Ql9qkfUDoo/H+g== X-Received: by 10.28.91.20 with SMTP id p20mr11356396wmb.126.1512511267412; Tue, 05 Dec 2017 14:01:07 -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 k2sm1114982wrg.4.2017.12.05.14.01.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 05 Dec 2017 14:01:05 -0800 (PST) Subject: Re: BUG #14932: SELECT DISTINCT val FROM table gets stuck in an infinite loop To: "Todd A. Cook" , Tom Lane , Thomas Munro Cc: Andres Freund , 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> From: Tomas Vondra Message-ID: <2a76784c-06cb-46ec-35be-9895d144b839@2ndquadrant.com> Date: Tue, 5 Dec 2017 23:01:01 +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: <9cd29b81-7ba1-91a2-f491-9014f4ac87e6@blackducksoftware.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On 12/05/2017 10:23 PM, Todd A. Cook wrote: > On 11/27/17 23:03, Tom Lane wrote: >> Thomas Munro writes: >>> When SH_INSERT tries to insert that final extra value, insertdist >>> keeps exceeding SH_GROW_MAX_DIB (25) no matter how many times we >>> double the size (at least until my computer gives up, somewhere around >>> 11 doublings and 75GB of virtual memory).  If you set SH_GROW_MAX_DIB >>> to 26 then it succeeds, but I guess some other attack could be crafted >>> for that.  What is the theory behind this parameter? >> >> You beat me to it --- after looking at simplehash.h I'd guessed that >> either the SH_GROW_MAX_DIB or SH_GROW_MAX_MOVE code path was causing >> an infinite loop, but I'd not gotten to determining which one yet. >> >> I'd ask what's the theory behind SH_GROW_MAX_MOVE, as well.  Neither >> of them are obviously loop-proof. >> >> Note that the sample data has a lot of collisions: >> >> regression=# select hashint8(val), count(*) from reproducer group by 1 >> order by 2 desc; >>    hashint8   | count >> -------------+------- >>     441526644 |  2337 >>   -1117776826 |  1221 >>   -1202007016 |   935 >>   -2068831050 |   620 >>    1156644653 |   538 >>     553783815 |   510 >>     259780770 |   444 >>     371047036 |   394 >>     915722575 |   359 >>   ... etc etc ... >> >> It's evidently more complicated than just that the code fails with >> more than SH_GROW_MAX_DIB duplicate hashcodes, but I suspect not >> by a lot.  There needs to be a safety valve that prevents letting >> the hash fill factor approach zero, which is what's happening in >> this test case. > > FWIW, I can also reproduce the infinite loop with 167834 unique values. > Unique values or unique *hash* values? Can you share the data, so that whoever fixes the bug can verify it also fixes your example? > It kinda looks like the problematic collisions arise from masking the > computed hash values; e.g.: > >     SH_INITIAL_BUCKET(SH_TYPE * tb, uint32 hash) >     { >     return hash & tb->sizemask; >     } > That's pretty standard way to do modulo (when computing index of the hash bucket), and certainly not the root cause. > (Also FWIW, changing SH_FILLFACTOR to 0.5 (from 0.9) did not help any.) > 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). This causes the insane growth to the largest possible hash table. Secondly, there's a bug that for the largest hash table we set sizemask=0, which means we never ever get bucket index other than 0. This causes the infinite loop. regards -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services