Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1gHQzD-0000ul-VA for pgsql-hackers@arkaria.postgresql.org; Tue, 30 Oct 2018 10:11:00 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gHQzA-0004EP-Un for pgsql-hackers@arkaria.postgresql.org; Tue, 30 Oct 2018 10:10:56 +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.89) (envelope-from ) id 1gHQzA-00047q-Lm for pgsql-hackers@lists.postgresql.org; Tue, 30 Oct 2018 10:10:56 +0000 Received: from tama500.ecl.ntt.co.jp ([129.60.39.148]) by magus.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gHQz2-0001UI-Ux; Tue, 30 Oct 2018 10:10:56 +0000 Received: from vc2.ecl.ntt.co.jp (vc2.ecl.ntt.co.jp [129.60.86.154]) by tama500.ecl.ntt.co.jp (8.13.8/8.13.8) with ESMTP id w9UAAhMK031212; Tue, 30 Oct 2018 19:10:43 +0900 Received: from vc2.ecl.ntt.co.jp (localhost [127.0.0.1]) by vc2.ecl.ntt.co.jp (Postfix) with ESMTP id A73DA639463; Tue, 30 Oct 2018 19:10:43 +0900 (JST) Received: from jcms-pop21.ecl.ntt.co.jp (jcms-pop21.ecl.ntt.co.jp [129.60.87.134]) by vc2.ecl.ntt.co.jp (Postfix) with ESMTP id 9B39863942F; Tue, 30 Oct 2018 19:10:43 +0900 (JST) Received: from [127.0.0.1] (unknown [129.60.241.61]) by jcms-pop21.ecl.ntt.co.jp (Postfix) with ESMTPSA id 935B240075E; Tue, 30 Oct 2018 19:10:43 +0900 (JST) Subject: Re: Should pg 11 use a lot more memory building an spgist index? References: <20181026140927.oh4gd367st47li6h@alvherre.pgsql> <26004.1540563602@sss.pgh.pa.us> <20752.1540842517@sss.pgh.pa.us> From: Amit Langote Message-ID: Date: Tue, 30 Oct 2018 19:10:31 +0900 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <20752.1540842517@sss.pgh.pa.us> Content-Type: multipart/mixed; boundary="------------5253696EAEF276D5B6588979" Content-Language: en-US X-CC-Mail-RelayStamp: 1 To: Tom Lane , Alvaro Herrera Cc: Alexander Korotkov , Bruno Wolff III , pgsql-hackers@lists.postgresql.org X-TM-AS-MML: disable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk This is a multi-part message in MIME format. --------------5253696EAEF276D5B6588979 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit On 2018/10/30 4:48, Tom Lane wrote: > I wrote: >> Alvaro Herrera writes: >>> How about modifying SysScanDescData to have a memory context member, >>> which is created by systable_beginscan and destroyed by endscan? > >> I think it would still have problems, in that it would affect in which >> context index_getnext delivers its output. We could reasonably make >> these sorts of changes in places where the entire index_beginscan/ >> index_getnext/index_endscan call structure is in one place, but that >> doesn't apply for the systable functions. > > Actually, after looking more closely, index_getnext doesn't return a > palloc'd object anyway, or at least not one that the caller is responsible > for managing. So maybe that could work. Instead of SysScanDescData, could we add one to IndexScanData? It's somewhat clear that catalog scans don't leak much, but user index scans can, as seen in this case. In this particular case, I see that it's IndexCheckExclusion() that invokes check_unique_or_exclusion_constraint() repeatedly for each heap tuple after finishing building index on the heap. The latter performs index_beginscan/endscan() for every heap tuple, but doesn't bother to release the memory allocated for IndexScanDesc and its members. I've tried to fix that with the attached patches. 0001 adds the ability for the callers of index_beginscan to specify a memory context. index_beginscan_internals switches to that context before calling ambeginscan and stores into a new field xs_scan_cxt of IndexScanData, but maybe storing it is unnecessary. 0002 builds on that and adds the ability for the callers of check_exclusion_or_unique_constraints to specify a memory context. Using that, it fixes the leak by teaching IndexCheckExclusion and ExecIndexInsertTuples to pass a memory context that's reset before calling check_exclusion_or_unique_constraints() for the next tuple. The following example shows that the patch works. With HEAD: create table foo (a int4range); alter table foo add exclude using spgist (a with &&); -- this consumes about 1GB insert into foo select int4range(i,i+1) from generate_series(1, 100000) i; alter table foo drop constraint foo_a_excl; -- this too alter table foo add exclude using spgist (a with &&); Patched: create table foo (a int4range); alter table foo add exclude using spgist (a with &&); -- memory consumption doesn't grow above 37MB insert into foo select int4range(i,i+1) from generate_series(1, 100000) i; alter table foo drop constraint foo_a_excl; -- ditto alter table foo add exclude using spgist (a with &&); Thoughts? Thanks, Amit --------------5253696EAEF276D5B6588979 Content-Type: text/plain; charset=UTF-8; name="v1-0001-Allow-IndexScanDesc-allocation-in-caller-specifie.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="v1-0001-Allow-IndexScanDesc-allocation-in-caller-specifie.pa"; filename*1="tch"