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 1sZE3T-00HAJv-9s for pgsql-general@arkaria.postgresql.org; Wed, 31 Jul 2024 18:28:07 +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 1sZE3R-00BfsG-Sj for pgsql-general@arkaria.postgresql.org; Wed, 31 Jul 2024 18:28:05 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sZE3R-00Bfs7-GW for pgsql-general@lists.postgresql.org; Wed, 31 Jul 2024 18:28:05 +0000 Received: from mail-io1-xd2f.google.com ([2607:f8b0:4864:20::d2f]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sZE3P-002TiW-14 for pgsql-general@lists.postgresql.org; Wed, 31 Jul 2024 18:28:04 +0000 Received: by mail-io1-xd2f.google.com with SMTP id ca18e2360f4ac-81f96eaa00fso240059039f.1 for ; Wed, 31 Jul 2024 11:28:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ilm.com; s=google; t=1722450481; x=1723055281; darn=lists.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=QFakYQy71zJPJmauA1gGUgVxJhb7xOuqeAaP53hrVgg=; b=Bclz3xy6k7Xg6/5nUBufRzVPVdK+T6xNohERqjQ4dCijurBf/CyJltEdyjwULvybEV Q5+5Vo00Wdn8yV226hKxSAktRVY06uLgAQ4u2tsozuWwRYtch5gWMyGAPjUN64EjEkz+ yNPovisoI+b2QJSDu2mfftnFm825kRghjHGa0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722450481; x=1723055281; 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=QFakYQy71zJPJmauA1gGUgVxJhb7xOuqeAaP53hrVgg=; b=AbqunKZaHEFQb0YN3p40FN+iE+/Xd11sVuoqDI3fzFtJ+uXXv62ft1InP2U/CazA+F umbvjXn6g94ySgLyfiEl9VaBQCvT7s5HlfXRyDg2Db0TqVBZZLZAu49j7T9nIFNBQJ4i 6CiHplxh1giSEfbJ/+0LycHH4lHNRI6cW8SBTPTrZs55BA4IYhvl86pDNletadflniD8 YFzcuevUfbuXDR5l1FyfKPUvjXo1TDhK3m6rDQXG0VelHVR5Yd7WOqSsk7eDysKgi4Km 7+7FkYEjvPgBYHe+innGogdArkmBPl5ULb3I8mjCP/BPgdh1EgNzUU6xIpaLtBYXqFRi 9+Xw== X-Gm-Message-State: AOJu0Yxz7u2DsMOVKBKsAjfHfA0/8hnAdHsMetFZtZYL7fmBmIZB5ih4 LVLxku6iKJsm+nUvrm4Phx18SmNELg7/+pI/sgPoJgaecCtZWJ1DVOqjDV5oLiR1fCgd8sGEUEW 036/oc792SRVJJKOSX56ylCSwbDMD2qG0fjI1+zSDsL1K1XJFXec= X-Google-Smtp-Source: AGHT+IGh2k68oHEaIDJmDVxdJIreT5Ly87LX6i/ndyAtPzlsmS5igPZBwApZ6GpBcK1fkTdx/8pJwHp8jElE+tCazoo= X-Received: by 2002:a05:6602:489:b0:7f9:beb8:7952 with SMTP id ca18e2360f4ac-81fcc2c0531mr12429639f.13.1722450481034; Wed, 31 Jul 2024 11:28:01 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Jim Vanns Date: Wed, 31 Jul 2024 19:27:50 +0100 Message-ID: Subject: Re: Suggestions to overcome 'multixact "members" limit exceeded' in temporary tables To: pgsql-general@lists.postgresql.org Content-Type: multipart/alternative; boundary="00000000000010db9f061e8f41a1" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000010db9f061e8f41a1 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 19:27, Jim Vanns wrote: > (resending to general since I believe I originally sent it to hackers by > mistake) > > 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 > --00000000000010db9f061e8f41a1 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
I've been able to observe that the pe= rformance degradation=C2=A0with TRUNCATE appears to happen when other ancil= lary=C2=A0processes are running that are also heavy users of temporary tabl= es. If I used an exclusive tablespace, would that improve things?

<= /div>
Cheers

Jim

On Wed, 31 Ju= l 2024 at 19:27, Jim Vanns <jvanns@ilm= .com> wrote:
(resending to general = since I believe I originally sent it to hackers by mistake)

<= /div>
I've reached the limit of my understanding and at= tempts at correcting my code/use of temporary tables in the face of=C2=A0mu= ltixact members and have come to ask for your help! Here's a brief desc= ription of my software;

Pool of N connection sessions, p= ersistent for the duration of the program lifetime.
Upon each ses= sion 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=C2=A0data and therefore each temporary tabl= e remains until the session is terminated
The thread performs a C= OPY <temp table> FROM STDIN in binary format
Then an INSERT= INTO <main table> SELECT FROM <temp table> WHERE...
=
This has been working great for a while and with excellent t= hroughput. However, upon scaling up I eventually hit this error;
=
ERROR: =C2=A0multixact "members" limit exceededDETAIL: =C2=A0This command would create a multixact with 2 members, but th= e remaining space is only enough for 0 members.
HINT: =C2=A0Execute a da= tabase-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 app= ears to be coming from the temporary table (the other 'main' tables= were being autovacuumed=C2=A0OK) - which makes sense because they have a l= ong lifetime, aren't auto vacuumed and shared by transactions (in turn)= .

I first attempted to overcome this by introducin= g an initial step of always creating the temporary table before the copy (a= nd using on commit drop) but this lead to a terrible performance degradatio= n.
Next, I reverted the above and instead I introduced a VACUUM s= tep every 1000000 (configurable) ingest operations
Finally, I int= roduced a TRUNCATE step in addition to the occasional VACUUM since the TRUN= CATE allowed the COPY option of FREEZE.

The new ov= erhead appears minimal until after several hours and again I've hit a p= erformance degradation=C2=A0seemingly dominated=C2=A0by the TRUNCATE.
=

My questions are;

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

I understand that I can create a Linu= x tmpfs partition for a tablespace for the temporary tables and that may sp= eed 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 hel= p,

Jim

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

--
Jim Vanns
Principal Production Enginee= r
Industrial Light & Magic, London
--00000000000010db9f061e8f41a1--