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.96) (envelope-from ) id 1wEMUo-003vH2-0X for pgsql-performance@arkaria.postgresql.org; Sun, 19 Apr 2026 07:23:10 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wEMUl-00ES4f-13 for pgsql-performance@arkaria.postgresql.org; Sun, 19 Apr 2026 07:23:07 +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.96) (envelope-from ) id 1wEMUk-00ES4W-3A for pgsql-performance@lists.postgresql.org; Sun, 19 Apr 2026 07:23:07 +0000 Received: from mail-dl1-x122b.google.com ([2607:f8b0:4864:20::122b]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wEMUi-00000001wUG-3TKJ for pgsql-performance@lists.postgresql.org; Sun, 19 Apr 2026 07:23:06 +0000 Received: by mail-dl1-x122b.google.com with SMTP id a92af1059eb24-12c565476d7so3358205c88.1 for ; Sun, 19 Apr 2026 00:23:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1776583382; cv=none; d=google.com; s=arc-20240605; b=ho1jvurRwC/CDx7Gji95l8DAZ/wRdopgIUT+WFxEsxjl7kMv4qUR8D6qQUWivMARjl ePINB7BYIwbsWa+n4WDh/DU8BOE6elW6kF+sDaoHguG5nG8AOQE1GLxY7ugfIvod/Dah X5046bFMCVY7tPWGcTJVy0ylDQDA57Ai/ZQARvI3AfUSUQebuoPG5eZ2qXHpzWmTkcZk zAi+4WqQKL8vQZtg5uLUBmpzbKGCAJxXKOkyvVxBYcIYeaih2ggcxiMesT7jykSOEqC/ z/eGDfVoF2fuT3KaEADmgnqz3kGy3oq8A3ZCbrz8YuHhOjiAkr84X5NOwRq7C3zSQy+e YjYA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=OaOxdtnr21AQ2wkI34jeNQlbEjlr/PHILQiBAVp8yMA=; fh=RBdLylifHZQ6hdeyM9csp+Hbmy3lavlGOmrSGvkGBP8=; b=b8Ic7v2lNJzprwm7H0rbOmHwCJQ2eqCu+z5DhiHTxR418oNI4qnUgH1KcIrZLlgB9w qU+zVlH9D9er5pbFUap5kC5Fh7IdBhLX2zzwNCeQB51coO4qnvQKeE2pZQwG1dPsTVYJ M6Pguc3pqC09wokx9+DT+TjJB/c2ptxiH+yK0AgiaGCSM8u4P0rLH2RccON5Ct9h3bK4 7NZanoNXVAw/LaCcxU8FPFBimWECP89w/0Rc4JU02Lr/qXikBeNZddmilQ5TruPoztWl xEBJNdSAqt9LRYJoNC9EYEhLFN+BlZ/A1wztQWzypTigp6TwdnVoheY5iyiS4xGeDx2b UuBw==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776583382; x=1777188182; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=OaOxdtnr21AQ2wkI34jeNQlbEjlr/PHILQiBAVp8yMA=; b=X8XxqRburXFns8qsRHsE76NP9pvpj/Aca4gC1/4lyhCOuhO+nZ3S3xa6jhvtaU1IHg sk4siTyIqWnUke2zzjCurIvP1gaJaeteTjxKFI1cFQYNEQsKPacfBaLkBz7uNBTqX0GJ eLaZHkQd5KH3jiUF3ea0IOUTizhSrPdxQyKjismTUM3dvqd7NdRE2pHyHxP7xZ7ikli2 QHxa9RY6luiWTmxQ531aE3PW8M7u97+aNK7CHEjsCl9td+QbWYne4cjUkm8+Io0TYLBi Yb9NmtpfT2Oj5Dm9i4Tg/BPRfqBj2/3tvvjLXzSWRlZK8Pny5m1NWmWMAcsvamZuPudS 9L0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776583382; x=1777188182; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=OaOxdtnr21AQ2wkI34jeNQlbEjlr/PHILQiBAVp8yMA=; b=l2w41RRkcENEtun69DubMP9aeYglOYmhfLvrqTbLQP6XFPpLP3t3SMYjzzuA8Bmpbk s3h/Q2WxvhYy4eFgbztaCoMwv/q1rqgDU7DUr+PFhv6rrdhYnPmIcPCSyeOaRYH6nZEm BGjYwiLr76eyfxAjLmKgx0PJvo5us+q0/YfRW7H7MH95BNx3iCna/9mB85pEz1nuTX9h LBg3Y/i0YjVqIoxCqr3qQ39GajCZj5Ac2ioJLDAfSedNzqYdcFZQytBy4KQgQQGEo73j ZNNtTWTrN7gqLUnJK87tLHQqWHi6u2PLydZpBIl3cae9J8I9Ri/qub5YBvjf08GQxhom zXcw== X-Gm-Message-State: AOJu0Yzlb35ZoFUI24WNYs8lHJ8uz6dNhF7KQOa1NnDND1oldHNKc02S NrrRVlYaFsNB3flzCiDyyMnlpBOSg6WSaHu728+0LCsZlQ+fZJhqlIznkcz5y+aVI8YLfxzPCY8 GOyrnydQjjZEw+1x6l0SJVFm0Zct0tuKmlo6m X-Gm-Gg: AeBDieuiqf1XufYN0GDnOyhvmXl8Hn36LZ+Istr/WIYRpdpNj22ptcSHuKxxEAzBWq8 WGKeEiA6LzGMSzQGHz6qG+vFA8Pqqd3DJX2Myer7IRAfo2XW6P0aUG7XNz8dtJBPkslbjj5n1oy 7ydcChjz0ook16XQgGrYzEYJ8/woN7OMaD8bz6ETV1gdESUQXM59vJkQrPZ56ERO1PVizmDelAX U5y2lAgApXX0dKAHIAGOD24ETrXF1fkV1xXbnJNPe8JChOoIN4X934BTgbXDNxWa+d9FRbIOYOG XJPoxCCjALDZmTlH6w== X-Received: by 2002:a05:7301:3d17:b0:2dd:405f:89b3 with SMTP id 5a478bee46e88-2e4528ce85cmr4614897eec.0.1776583381746; Sun, 19 Apr 2026 00:23:01 -0700 (PDT) MIME-Version: 1.0 References: <6EEE234B-D3DC-48D9-97EE-0A86D63554BC@thebuild.com> In-Reply-To: <6EEE234B-D3DC-48D9-97EE-0A86D63554BC@thebuild.com> From: James Pang Date: Sun, 19 Apr 2026 15:22:51 +0800 X-Gm-Features: AQROBzBPgO3HzuGNvzsDLYp7SBzc3WNbSjMWu5gcqXLRG-G2wBmZTm7hZxZx89w Message-ID: Subject: Re: table bloat very fast and free space can not be reused To: Christophe Pettus Cc: pgsql-performance@lists.postgresql.org Content-Type: multipart/alternative; boundary="000000000000620893064fcb0d0f" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000620893064fcb0d0f Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 1. we use default fill factor in both source and target, sorry, we have two environment, v14-->v17, v16-->v17. both see similar issue. 2. any key difference between in-core and pglogical extension to apply UPDATEs? we want to use pglogical extension conflict resolution, it's a bi-directional replication(when workload on source v16 it replicate data to v17, when it running on v17, so it can replication back to v16) 3. free space is high in source and target, but the size of freespace show big difference we found this issue , and try to vacuum full several time on v17, but after vacuum full , it bloating very quickly.you see total toast size much more than source (workload is still running), target v17(by pglogical= ) xxx=3D> select * from pgstattuple('xxxx'); table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent -----------+-------------+-----------+---------------+------------------+--= --------------+--------------------+------------+-------------- 191160320 | 81911 | 107823097 | 56.4 | 1439 | 2020471 | 1.06 | 79614944 | 41.65 (1 row) xxx=3D> select * from pgstattuple('pg_toast.pg_toast_xxxxx'); table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent -----------+-------------+-----------+---------------+------------------+--= --------------+--------------------+------------+-------------- 905928704 | 117924 | 169760027 | 18.74 | 6330 | 9336459 | 1.03 | 722476480 | 79.75 (1 row) target v17 xxxx=3D> select * from pgstattuple('xxxxxx'); table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent -----------+-------------+-----------+---------------+------------------+--= --------------+--------------------+------------+-------------- 194191360 | 81905 | 106028087 | 54.6 | 4004 | 5801923 | 2.99 | 80468096 | 41.44 (1 row) xxxx=3D> select * from pgstattuple('pg_toast.pg_toast_xxxxx'); table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent ------------+-------------+-----------+---------------+------------------+-= ---------------+--------------------+------------+-------------- 1666334720 | 117921 | 169758344 | 10.19 | 9302 | 13732019 | 0.82 | 1475454612 | 88.54 (1 row) James Christophe Pettus =E6=96=BC 2026=E5=B9=B44=E6=9C=8819=E6= =97=A5=E9=80=B1=E6=97=A5 =E4=B8=8A=E5=8D=8811:56=E5=AF=AB=E9=81=93=EF=BC=9A > > > > On Apr 18, 2026, at 18:28, James Pang wrote: > > > > experts: > > source database v14 , pglogical extension 2.4.5 replication to ne= w > 17, source table very frequent UPDATEs /DELETES /INSERTS and has two text > and jsonb. in source database, application update/delete/insert through > SQL, table size did not increased quickly. but in target pg v17 , by > pglogical apply, we found table increased very quickly , table size got > doubled in days. > > Vacuum analyze did not help , only vacuum full can help. pgstattupl= e > show most of space are free space , that much more than source. it looks > like these replicate DML always asking new pages instead of reuse existin= g > freespace. > > Thanks, > > > > James > > Hello, > > 1. First, are you *sure* that the free space is the source of the bloat, > and not dead tuples? Could you share the queries you ran to detrmine thi= s? > > 2. Have you set fillfactor to anything besides 100 on either the source o= r > the destination? > > 3. You might consider using in-core logical replication rather than > pglogical for this. By PostgreSQL v14, in-core logical replication is > likely a better choice. > > Best, > -- Christophe --000000000000620893064fcb0d0f Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
1. we use default fill factor in both sou= rce and target, sorry, we have two environment, v14-->v17,=C2=A0 v16--&g= t;v17. both see similar issue.
2. any key difference between in-core an= d pglogical extension to apply UPDATEs? we want to use pglogical extension = conflict resolution, it's a bi-directional replication(when workload on= source v16 it replicate data to v17, when it running on v17, so it can rep= lication back to v16)
3. free space is high in source and target,= but the size of freespace show big difference

we = found this issue , and try to vacuum full several time on v17, but after va= cuum full , it bloating very quickly.you see total toast size
much more= than source (workload is still running), =C2=A0target v17(by pglogical)
xxx=3D> select * from pgstattuple('xxxx');
=C2=A0table_l= en | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tupl= e_len | dead_tuple_percent | free_space | free_percent
-----------+-----= --------+-----------+---------------+------------------+----------------+--= ------------------+------------+--------------
=C2=A0191160320 | =C2=A0 = =C2=A0 =C2=A0 81911 | 107823097 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A056.4 | = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 1439 | =C2=A0 =C2=A0 =C2=A0 =C2= =A02020471 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 1.06 | =C2=A0= 79614944 | =C2=A0 =C2=A0 =C2=A0 =C2=A041.65
(1 row)

xxx=3D> = =C2=A0select * from pgstattuple('pg_toast.pg_toast_xxxxx');
=C2= =A0table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count |= dead_tuple_len | dead_tuple_percent | free_space | free_percent
-------= ----+-------------+-----------+---------------+------------------+---------= -------+--------------------+------------+--------------
=C2=A0905928704= | =C2=A0 =C2=A0 =C2=A0117924 | 169760027 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 18.= 74 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 6330 | =C2=A0 =C2=A0 =C2=A0 = =C2=A09336459 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 1.03 | =C2= =A0722476480 | =C2=A0 =C2=A0 =C2=A0 =C2=A079.75
(1 row)


targe= t v17
xxxx=3D> =C2=A0select * from pgstattuple('xxxxxx');
= =C2=A0table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_coun= t | dead_tuple_len | dead_tuple_percent | free_space | free_percent
----= -------+-------------+-----------+---------------+------------------+------= ----------+--------------------+------------+--------------
=C2=A0194191= 360 | =C2=A0 =C2=A0 =C2=A0 81905 | 106028087 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A054.6 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 4004 | =C2=A0 =C2=A0= =C2=A0 =C2=A05801923 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 2.= 99 | =C2=A0 80468096 | =C2=A0 =C2=A0 =C2=A0 =C2=A041.44
(1 row)

x= xxx=3D> =C2=A0select * from pgstattuple('pg_toast.pg_toast_xxxxx'= ;);
=C2=A0table_len =C2=A0| tuple_count | tuple_len | tuple_percent | de= ad_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_pe= rcent
------------+-------------+-----------+---------------+-----------= -------+----------------+--------------------+------------+--------------=C2=A01666334720 | =C2=A0 =C2=A0 =C2=A0117921 | 169758344 | =C2=A0 =C2=A0= =C2=A0 =C2=A0 10.19 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 9302 | =C2= =A0 =C2=A0 =C2=A0 13732019 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 0.82 | 1475454612 | =C2=A0 =C2=A0 =C2=A0 =C2=A088.54
(1 row)

James

Christophe Pettus <xof@thebuild.com> =E6=96=BC 2026= =E5=B9=B44=E6=9C=8819=E6=97=A5=E9=80=B1=E6=97=A5 =E4=B8=8A=E5=8D=8811:56=E5= =AF=AB=E9=81=93=EF=BC=9A


> On Apr 18, 2026, at 18:28, James Pang <jamespang886@gmail.com> wrote:
>
> experts:
>=C2=A0 =C2=A0 =C2=A0 source database v14 ,=C2=A0 pglogical extension 2.= 4.5 replication to new 17, source table very frequent UPDATEs /DELETES /INS= ERTS and has two text and jsonb. in source database, application update/del= ete/insert through SQL, table size did not increased quickly. but in target= pg v17 , by pglogical apply, we found table increased very quickly , table= size got doubled in days.=C2=A0
>=C2=A0 =C2=A0 =C2=A0Vacuum analyze did not help , only vacuum full can = help. pgstattuple show most of space are free space , that much more than s= ource.=C2=A0 it looks like these replicate DML always asking new pages inst= ead of reuse existing freespace.
>=C2=A0 =C2=A0 =C2=A0Thanks,
>
> James

Hello,

1. First, are you *sure* that the free space is the source of the bloat, an= d not dead tuples?=C2=A0 Could you share the queries you ran to detrmine th= is?

2. Have you set fillfactor to anything besides 100 on either the source or = the destination?

3. You might consider using in-core logical replication rather than pglogic= al for this.=C2=A0 By PostgreSQL v14, in-core logical replication is likely= a better choice.

Best,
-- Christophe
--000000000000620893064fcb0d0f--