Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sZBSs-00GxAC-0K for pgsql-hackers@arkaria.postgresql.org; Wed, 31 Jul 2024 15:42:10 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sZBSp-009X65-FC for pgsql-hackers@arkaria.postgresql.org; Wed, 31 Jul 2024 15:42:07 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sZBSo-009X0p-Ru for pgsql-hackers@lists.postgresql.org; Wed, 31 Jul 2024 15:42:07 +0000 Received: from mail-io1-xd34.google.com ([2607:f8b0:4864:20::d34]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sZBSl-002OtM-LJ for pgsql-hackers@postgresql.org; Wed, 31 Jul 2024 15:42:05 +0000 Received: by mail-io1-xd34.google.com with SMTP id ca18e2360f4ac-8111f946f04so249178439f.3 for ; Wed, 31 Jul 2024 08:42:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ilm.com; s=google; t=1722440522; x=1723045322; darn=postgresql.org; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=PtzLxNvDSL1GBrq47RgRR0iQL2Vel5mW5posf7okw/g=; b=OG0rOuYdE78TXKDE1RYDbAjLxC5Mvd0MaiBbAmVvah7NvIfQaDk/Ur9JFvTyerhIZj d+kObj5TFMUetAaTYPgoNQ33bjOooQ+s64aFIARBFhtAGEw/jreCkqSpdMEQKjb0XO1q LuJrRYQWxFHuuBz66sPmbGV+vVIg3y3J9Njto= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722440522; x=1723045322; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=PtzLxNvDSL1GBrq47RgRR0iQL2Vel5mW5posf7okw/g=; b=vLlcT6r8EZzy9caE6JML/RpNUgozZoQYJZuEgigZXtOlU0AnxmWux3vJP01cYnzbo7 W+d3Vtuz2vIUXBgZ8OcvqxnS2D05I9LcoGFgb7FqDWt6iahOqwNHOviQKbEmgHsFh0+b bI2kGg48vVt+xoxxzKU5TlHai0xxVkzmWcyd74JnvJWN7NFm9dTSCDJwPZZkJqnq911+ LHJQ8Zd5PCdlZJckBtLAPHEExy9BvfYmLOM5OYHm4DjkonVOmIDnmxJb/Sm3Sc33gEBA +jUBcxe4E3YE0T5+ZviAlZ/YlbLemBrIalTyesVDiMLJCENeDOuQnBET1aUvEl35+Umw 9DQQ== X-Gm-Message-State: AOJu0YxEMHk/gfJnmLvoCJn11vo/yDVa4coT1r1uMRC8XTDcNICx7aiA eE6ks+0HVpokkTo41cmeCyE+ipcqlEOrkTCjlkuA2afJVLdVasNuv33BsW3k8/PPl+LvOn+wlhD vmyHzx4bUaGm+6Wmh7WEY2oNX8zVT5Ums8X8wuqJdCa2EfRRR X-Google-Smtp-Source: AGHT+IF8QMEE+tC3l3yIWhmaFyDTlFhKCfr5fN/0ZMjyfM92s885n97xch/EjjHJioR0AIQ5TOIzwzWCGhO1vsNMtQ0= X-Received: by 2002:a6b:310e:0:b0:814:9cb6:4272 with SMTP id ca18e2360f4ac-81f95bc67bdmr1507566039f.17.1722440522584; Wed, 31 Jul 2024 08:42:02 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Jim Vanns Date: Wed, 31 Jul 2024 16:41:51 +0100 Message-ID: Subject: Re: Suggestions to overcome 'multixact "members" limit exceeded' in temporary tables To: PostgreSQL-development Content-Type: multipart/alternative; boundary="0000000000007ef1b8061e8cef01" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000007ef1b8061e8cef01 Content-Type: text/plain; charset="UTF-8" I've been able to observe that the performance degradation with TRUNCATE appears to happen when other ancillary processes are running that are also heavy users of temporary tables. If I used an exclusive tablespace, would that improve things? Cheers Jim On Wed, 31 Jul 2024 at 15:16, Jim Vanns wrote: > I've reached the limit of my understanding and attempts at correcting my > code/use of temporary tables in the face of multixact members and have come > to ask for your help! Here's a brief description of my software; > > Pool of N connection sessions, persistent for the duration of the program > lifetime. > Upon each session initialisation, a set of CREATE TEMPORARY TABLE ON > COMMIT DELETE ROWS statements are made for bulk ingest. > Each session is acquired by a thread for use when ingesting data and > therefore each temporary table remains until the session is terminated > The thread performs a COPY FROM STDIN in binary format > Then an INSERT INTO
SELECT FROM WHERE... > > This has been working great for a while and with excellent throughput. > However, upon scaling up I eventually hit this error; > > ERROR: multixact "members" limit exceeded > DETAIL: This command would create a multixact with 2 members, but the > remaining space is only enough for 0 members. > HINT: Execute a database-wide VACUUM in database with OID 16467 with > reduced vacuum_multixact_freeze_min_age and > vacuum_multixact_freeze_table_age settings. > > And it took me quite a while to identify that it appears to be coming from > the temporary table (the other 'main' tables were being autovacuumed OK) - > which makes sense because they have a long lifetime, aren't auto vacuumed > and shared by transactions (in turn). > > I first attempted to overcome this by introducing an initial step of > always creating the temporary table before the copy (and using on commit > drop) but this lead to a terrible performance degradation. > Next, I reverted the above and instead I introduced a VACUUM step every > 1000000 (configurable) ingest operations > Finally, I introduced a TRUNCATE step in addition to the occasional VACUUM > since the TRUNCATE allowed the COPY option of FREEZE. > > The new overhead appears minimal until after several hours and again I've > hit a performance degradation seemingly dominated by the TRUNCATE. > > My questions are; > > 1) Is the VACUUM necessary if I use TRUNCATE + COPY FREEZE (on the > temporary table)? > 2) Is there really any benefit to using FREEZE here or is it best to just > VACUUM the temporary tables occasionally? > 3) Is there a better way of managing all this!? Perhaps re-CREATING the TT > every day or something? > > I understand that I can create a Linux tmpfs partition for a tablespace > for the temporary tables and that may speed up the TRUNCATE but that seems > like a hack and I'd rather not do it at all if it's avoidable. > > Thanks for your help, > > Jim > > PS. PG version in use is 15.4 if that matters here > > -- > Jim Vanns > Principal Production Engineer > Industrial Light & Magic, London > -- Jim Vanns Principal Production Engineer Industrial Light & Magic, London --0000000000007ef1b8061e8cef01 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
I've been able to observe that the performance degrada= tion=C2=A0with TRUNCATE appears to happen when other ancillary=C2=A0process= es are running that are also heavy users of temporary tables. If I used an = exclusive tablespace, would that improve things?

Cheers<= /div>

Jim


On Wed, 31 Jul 2024 at 15:= 16, Jim Vanns <jvann= s@ilm.com> wrote:
I've reached the limit of my understanding = and attempts at correcting my code/use of temporary tables in the face of= =C2=A0multixact members and have come to ask for your help! Here's a br= ief description of my software;

Pool of N connection ses= sions, persistent for the duration of the program lifetime.
Upon = each session initialisation, a set of CREATE TEMPORARY TABLE ON COMMIT DELE= TE ROWS statements are made for bulk ingest.
Each session is acqu= ired by a thread for use when ingesting=C2=A0data and therefore each tempor= ary table remains until the session is terminated
The thread perf= orms a COPY <temp table> FROM STDIN in binary format
Then a= n INSERT INTO <main table> SELECT FROM <temp table> WHERE...

This has been working great for a while and with exc= ellent throughput. However, upon scaling up I eventually hit this error;

ERROR: =C2=A0multixact "members" limit exc= eeded
DETAIL: =C2=A0This command would create a multixact with 2 members= , but the remaining space is only enough for 0 members.
HINT: =C2=A0Exec= ute a database-wide VACUUM in database with OID 16467 with reduced vacuum_m= ultixact_freeze_min_age and vacuum_multixact_freeze_table_age settings.
=

And it took me quite a while to identify tha= t it appears to be coming from the temporary table (the other 'main'= ; tables were being autovacuumed=C2=A0OK) - which makes sense because they = have a long lifetime, aren't auto vacuumed and shared by transactions (= in turn).

I first attempted to overcome this by in= troducing an initial step of always creating the temporary table before the= copy (and using on commit drop) but this lead to a terrible performance de= gradation.
Next, I reverted the above and instead I introduced a = VACUUM step every 1000000 (configurable) ingest operations
Finall= y, I introduced a TRUNCATE step in addition to the occasional VACUUM since = the TRUNCATE allowed the COPY option of FREEZE.

Th= e new overhead appears minimal until after several hours and again I've= hit a performance degradation=C2=A0seemingly dominated=C2=A0by the TRUNCAT= E.

My questions are;

1) I= s the VACUUM necessary if I use TRUNCATE=C2=A0+ COPY FREEZE (on the tempora= ry table)?
2) Is there really any benefit to using FREEZE here or= is it best to just VACUUM the temporary tables occasionally?
3) = Is there a better way of managing all this!? Perhaps re-CREATING the TT eve= ry day or something?

I understand that I can creat= e a Linux tmpfs partition for a tablespace for the temporary tables and tha= t may speed up the TRUNCATE but that seems like a hack and I'd rather n= ot do it at all if it's avoidable.

Thanks for = your help,

Jim

PS. PG ver= sion in use is 15.4 if that matters here

--
Jim Vanns
Principal Production Engineer
Indus= trial Light & Magic, London


--
Jim Vanns
Principal Production Engineer
Industrial Lig= ht & Magic, London
--0000000000007ef1b8061e8cef01--