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 1kqPbl-0003fB-2o for pgsql-hackers@arkaria.postgresql.org; Fri, 18 Dec 2020 23:56:25 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1kqPbh-00039u-Gh for pgsql-hackers@arkaria.postgresql.org; Fri, 18 Dec 2020 23:56:21 +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 1kqPbh-00039n-1c for pgsql-hackers@lists.postgresql.org; Fri, 18 Dec 2020 23:56:21 +0000 Received: from mail-ot1-x331.google.com ([2607:f8b0:4864:20::331]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1kqPbW-0004pF-IP for pgsql-hackers@postgresql.org; Fri, 18 Dec 2020 23:56:19 +0000 Received: by mail-ot1-x331.google.com with SMTP id f16so3559862otl.11 for ; Fri, 18 Dec 2020 15:56:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telsasoft-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=27IYkWsOwiT4sY7kNgRDXLgSID/UHozWGJnmm7SgcNE=; b=PBo0ghNsYJqsfqVIPJwiC2xnzyALxBKWt5bQ7nv4FBycvhtLcdlMqERnzJkNFfWOB6 UrbVYqZ8p1W0sse3kyt9NxBXXoDb/10GI5/CJyyqFTHkTc544Cm3zslFlcMqe9RzXC+r 29xyoMchMe3te6T89ykitmTsMTQ4RyOao4y9z0heJJl6np16jdYY0IqavX+NtsNioJFF B8joBHMR5R/HVcbHtuj9+GBu4BkMzwvYOK8nd5QZ4VmnqyET5eynjL7MF7tmgw+01Z8f g9E1pQSbaCDgED3nzJ5liCBnfLOO0WDH9aG6NEsVrn7iQ3/FzBEOCpymZ8t4nbfBxQIE pwbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=27IYkWsOwiT4sY7kNgRDXLgSID/UHozWGJnmm7SgcNE=; b=UPVgh1vRxos5PmDR3JE+4+oZAsLNq153J5so8nAmPzWHoVHWdQAUc6MWmpYu6QrFG1 +y9IrP3NpgV9cK9ixgweiH704tsTa3Q+1wTzCIYXwDNm/QYU/RlLoUTwrEhMHbifDHvw P/VF6qPp2E/bGQCL++ZpO4f1sR04AIr3ghtdDYVRaWBzVDvqnXNbUWUPHqq6c+AXxWrg HhxGPIXFtCbh2tTq99GMtLyyGZCCLAKK3CSEYmJxqU8Or8lMdkVeOp+JAEi7xVw6ogtg oLliC9CTsN066dLY/5dvNZUnQEZXMeRXKPt3i+5bbkqPQ+PbI4hSEVSS41Furjgz1euj TyRw== X-Gm-Message-State: AOAM5335P43LK9AApf2C0riIUWZ6VqB/P15VeII0NXAIlbOa5F2VS07u 8g0jvnmlaedpepzGkYA0VLuoHA== X-Google-Smtp-Source: ABdhPJzEFHwxHoer5I7FnOzygoUFiEzl1SmDSU4joAzxDfCOMevCeimhjGKz3suJi2PcRCz4ZbqJZw== X-Received: by 2002:a9d:3985:: with SMTP id y5mr4616821otb.202.1608335769472; Fri, 18 Dec 2020 15:56:09 -0800 (PST) Received: from pryzbyj.telsasoft (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id 11sm2210256oty.65.2020.12.18.15.56.08 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 18 Dec 2020 15:56:08 -0800 (PST) Received: by pryzbyj.telsasoft (Postfix, from userid 1000) id 60859800665; Fri, 18 Dec 2020 17:56:07 -0600 (CST) Date: Fri, 18 Dec 2020 17:56:07 -0600 From: Justin Pryzby To: Andres Freund Cc: pgsql-hackers@postgresql.org, Tom Lane Subject: Re: terminate called after throwing an instance of 'std::bad_alloc' Message-ID: <20201218235607.GC30237@telsasoft.com> References: <20201001021609.GC8476@telsasoft.com> <20201003220236.GL8476@telsasoft.com> <20201003230149.mtd7fjsjwgii3jv7@alap3.anarazel.de> <20201003233045.GM8476@telsasoft.com> <20201004020127.zbrol2ypu6tg2bei@alap3.anarazel.de> <20201007230242.rnwsbnxywvthef3w@alap3.anarazel.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20201007230242.rnwsbnxywvthef3w@alap3.anarazel.de> User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk I'm re-raising this issue (since I needed to track down why I'd reflexively saved a 512g backup of the filesystem where this first happened). I'm 99% sure the "bad_alloc" is from LLVM. It happened multiple times on different servers (running a similar report) after setting jit=on during pg13 upgrade, and never happened since re-setting jit=off. I reproduced a memory leak, but I don't think you publicized a fix for it. I *think* the memory leak probably explains the bad_alloc. We were seeing postgres killed by OOM every ~16hours, although I don't see how that's possible from such a tiny leak. Our query also uses postgis (at first I said it didn't), so it may be that they're involved. I'd be happy to run with a prototype fix for the leak to see if the other issue does (not) recur. On Wed, Oct 07, 2020 at 04:02:42PM -0700, Andres Freund wrote: > Hi, > > Sorry for the second send of this email, but somehow I managed to mangle > the headers in the last version I sent. > > On 2020-10-03 19:01:27 -0700, Andres Freund wrote: > > On 2020-10-03 18:30:46 -0500, Justin Pryzby wrote: > > > On Sat, Oct 03, 2020 at 04:01:49PM -0700, Andres Freund wrote: > > > > > I was able to make a small, apparent leak like so. This applies to > > > > > postgis3.0/postgres12/LLVM5/centos7, and > > > > > postgis3.1alpha/postgres13/LLVM9/centos8. > > > > > > > > > > Inlining is essential to see the leak, optimization is not. Showing every 9th > > > > > query: > > > > > > > > > > $ for a in `seq 1 99`; do echo "SET jit_inline_above_cost=1; SET jit_optimize_above_cost=-1; SET jit_above_cost=0; SET jit_expressions=on; SET log_executor_stats=on; SET client_min_messages=debug; SET jit=on; explain analyze SELECT st_x(site_geo) FROM sites WHERE site_geo IS NOT NULL;"; done |psql ts 2>&1 |grep 'resident' |sed -n '1~9p' > > > > > ! 46024 kB max resident size > > > > > ! 46492 kB max resident size > > > > > > > > Huh, that's certainly not good. Looking. > > > > > > Reproduce like: > > > postgres=# CREATE EXTENSION postgis; > > > postgres=# CREATE TABLE geo(g geometry(point)); > > > postgres=# INSERT INTO geo SELECT st_GeometryFromText('POINT(11 12)',0) FROM generate_series(1,99999); > > > postgres=# SET jit_above_cost=0; SET jit_inline_above_cost=0; SET client_min_messages=debug; SET log_executor_stats=on; explain analyze SELECT st_x(g) FROM geo; > > > > It's an issue inside LLVM. I'm not yet sure how to avoid it. Basically > > whenever we load an IR module to inline from, it renames its type names > > to make them not conflict with already known type names in the current > > LLVMContext. That, over time, leads to a large number of type names in > > memory. We can avoid the re-loading of the module by instead cloning it, > > but that still leads to new types being created for some internal > > reasons. It's possible to create/drop separate LLVMContext instances, > > but we'd have to figure out when to do so - it's too expensive to always > > do that. > > I spent a lot of time (probably too much time) trying to find a good way > out of that. I think I mostly figured it out, but it's gonna take me a > bit longer to nail down the loose ends. The nice part is that it > actually speeds up inlining a lot. The bad part is that it's not a small > change, so I don't yet know how to deal with existing releases. > > Details: > > The issue with the leaks is basically that when LLVM loads a bitcode > module it doesn't "unify" named types with types in other bitcode module > - they could after all be entirely independent. That means that we end > up with a lot of types after a while of running. > > That ought to be addressable by not re-loading modules we inline from > from disk every time we inline, but unfortunately that doesn't work well > either: The "cross module import" logic unfortunately modifies the types > used in the "source module", leading to subsequent imports not working > well. That last issue is why I had moved to re-loading modules from > "disk" during import. > > The partial patch I've written doesn't use the existing cross module > import code anymore, but moves to the lower level functionality it > uses. For traditional compilers, which is what that linker is mainly > written for, it makes sense to reduce memory usage by "destructively" > moving code from the source into the target - it'll only be used > once. But for the JIT case it's better to do so non-destructively. That > requires us to implement some "type resolution" between the source and > target modules, but then gains not needing to reload / copy the source > module anymore, saving a lot of the costs. > > > It's possible that for existing releases we ought to go for a simpler > approach, even if it's not as good. The only really feasible way I see > is to basically count the number of times inlining has been done, and > then just re-initialize after a certain time. But that's pretty darn > yucky. > > Greetings, > > Andres Freund