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 1tUwNw-0040hH-Ge for pgsql-performance@arkaria.postgresql.org; Mon, 06 Jan 2025 23:19:49 +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 1tUwMv-00EVpd-UC for pgsql-performance@arkaria.postgresql.org; Mon, 06 Jan 2025 23:18:45 +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 1tUwMv-00EVpS-Ef for pgsql-performance@lists.postgresql.org; Mon, 06 Jan 2025 23:18:45 +0000 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1tUwMr-000FF6-2L for pgsql-performance@lists.postgresql.org; Mon, 06 Jan 2025 23:18:44 +0000 Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-2ee786b3277so16033061a91.1 for ; Mon, 06 Jan 2025 15:18:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1736205520; x=1736810320; 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=Tz+sV0g1iSd9RqlXRD1fBvFjD0mbq2ljIKJCbOYHwr8=; b=WXQh/m65behkzGF6FuSqMJU+Pm7Sq/tANhwq1G/c5AhKhHg7CVfBcoFOCSCrXBcHh8 T5dVr4eZw5LyY9kGO9O2I09XMMQ5gNiNG1cI834y3mPa/F3PRXSZfvrFsXg8zFnVmXYM Ll0FRr8CVMNOsonAlAgp0rFUjd1n21clBY9AZEl1IKqvkcDLrqiOBD79LhFEQ0es8gc/ cOv1fLmkJ4Olq+49h/i9bqlfKKaBS8NE3Z2Ld8tqTTupdaLHgSJgcVP7ZmdHZs6A3tgk /977Gg8oCT/hQpcys3HScTWJI6LWb1i9kE8tu18ofTYa4534rqMpo7NaNLN48fJtOTxH /SpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736205520; x=1736810320; h=cc: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=Tz+sV0g1iSd9RqlXRD1fBvFjD0mbq2ljIKJCbOYHwr8=; b=KxZJWl+bqUKPJN0VGRBS+iyW9VCYB3kVoVf/4gVtlcMUIC3BGgJGZ3ybZiFtDV3GEX eXcX4CnQIwy0M3z8aYaVCNNgmbzhgCqH5n/aV5PCIrPB/TVcsFl1tatxwMebI3aZAJKx /pJw2hoQTmsNG8pG0jGAgbWq2aH/5JL1M6kLKZ3ZB4dvtD02N8qeyzLQudnTqOmO5Hsr JNP8Br6QbC0etylu5/7a9qsbbKKkltvlf2Qn+XgKFeNVFCbfhCCZU3somzuzWh/1sHyV 50Ox90MmX2CCXreapNKNg93saXyOBi+2U5odqM5C8prQSkpLFe0Vhj9XtwdGHKMXw3FK 5oyQ== X-Gm-Message-State: AOJu0YycnWcIcB/SBtnsCmsNhgzH1ahAlO5kTEqlnzEBJbFBRlg+qicP MITvNsrMIoCnxE9EAjmtlSFA4yhrLP7T8SEU33e5l+wnJk3PzGuZFIcn9ZZ37nTlEl+JibH3EC1 bU6mqLJTQITDWV+IPlV3c7372gUc= X-Gm-Gg: ASbGncvcLtibhklVeYP8guvOYiQOPPWqjMZWUnQltbbBXVCEwkLkABm6fNJyO+MiBcF sJaK92D3tjNlRqkv34w5QrAHuHFepyH8tb5oo X-Google-Smtp-Source: AGHT+IEeJScIwErjMwJXVqkk7KEHxm3/RWGEMgLnu625av/0aF2A+DHNmF2M9SLCc1XBOQTKZwrrM1AIjga5+pmmSzU= X-Received: by 2002:a17:90b:538b:b0:2ee:5bc9:75b5 with SMTP id 98e67ed59e1d1-2f452dfccf6mr86876849a91.4.1736205519820; Mon, 06 Jan 2025 15:18:39 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Slava Mudry Date: Mon, 6 Jan 2025 15:18:28 -0800 Message-ID: Subject: Re: Aggressive vacuum To: Graham Hay Cc: pgsql-performance@lists.postgresql.org Content-Type: multipart/alternative; boundary="000000000000442042062b11d93b" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000442042062b11d93b Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hello Graham, I had to deal with "vacuum to prevent wraparound" a few times and it's not fun :( Postgres doc explains it very well.. if you see that nasty thing running on your db, your best options are: 1. manually vacuum freeze the table 2. examine vacuum costs and lower them to make sure the autovacuum can do it's job. Allow more vacuum processes by tuning *autovacuum_max_workers* 3. tune and set autovacuum settings for your table to make sure autovacuum picks it up sooner than defaults allow it so. Depending on your usage, there are some other good optimizations you can try.. The best in my opinion is to partition the large table and isolate old rows from frequently updated rows and manually vacuum freeze rows that you know wan't change. Also newer postgres versions have improved the autovacuuming, if you're on ver 15 (based on your link to docs), you should consider upgrading to more recent version. Good luck, -Slava On Thu, Dec 19, 2024 at 5:37=E2=80=AFAM Graham Hay w= rote: > Can anyone enlighten me on exactly what triggers an "aggressive" > vacuum? I have read the docs multiple times (and watched several > videos!), but the changes I make do not have the expected outcomes; so > I'm clearly missing something. > > > https://www.postgresql.org/docs/15/routine-vacuuming.html#VACUUM-FOR-WRAP= AROUND > > I have a fairly large table, that has outgrown the vacuum defaults. We > started by setting: > > - autovacuum_vacuum_scale_factor=3D0 > - autovacuum_vacuum_threshold=3D100000 # 100K > > (10% was a lot of tuples). This was definitely an improvement, but > when the big vacuum (freeze) kicked off there was a noticeable > io/latency spike. We then tried setting: > > - autovacuum_freeze_table_age=3D100000000 # 100M > > which seemed to make it happen more frequently (and one would hope, > with less work to do). We reduced this to 50M, and again it was more > frequent (but not the 2x I expected). And when I dropped it to 10M, > nothing changed. > > After re-reading the docs, I got the impression I also needed to set: > > - autovacuum_freeze_min_age=3D10000000 # 10M > > As the system default was 50M. And again, this had an effect, but not > the 5x I was expecting. The docs say: > > > all-visible but not all-frozen pages are scanned if the number of > transactions that have passed since the last such scan is greater than > vacuum_freeze_table_age minus vacuum_freeze_min_age > > but wouldn't that have been 10M - 50M? i.e. -40M. Is there some other > setting I'm missing? > > All suggestions welcome! > > Thanks, > > Graham > > > --=20 -slava --000000000000442042062b11d93b Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hello Graham,
I had to deal with "vacu= um to prevent wraparound" a few times and it's not fun :(
Postgres doc explains it very well.. if you see that nasty thing runn= ing on your db, your best options are:
1. manually vacuum fre= eze the table
2. examine vacuum costs and lower them to make sure= the autovacuum can do it's job. Allow more vacuum processes by tuning= =20 autovacuum_max_workers
3. tune and set autovacuum settings for your table to make sure = autovacuum picks it up sooner than defaults allow it so.

Depending on your usage, there are some other good optimizations you= can try.. The best in my opinion is to partition the large table and isola= te old rows from frequently updated rows and manually vacuum freeze rows th= at you know wan't change. Also newer postgres versions have improved th= e autovacuuming, if you're on ver 15 (based on your link to docs), you = should consider upgrading to more recent version.
Good luck,
-Slava

On Thu, Dec 19, 2024 at 5:37=E2= =80=AFAM Graham Hay <grahamrhay@= gmail.com> wrote:
Can anyone enlighten me on exactly what triggers an "aggres= sive"
vacuum? I have read the docs multiple times (and watched several
videos!), but the changes I make do not have the expected outcomes; so
I'm clearly missing something.

https://www.postgresq= l.org/docs/15/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND

I have a fairly large table, that has outgrown the vacuum defaults. We
started by setting:

=C2=A0 =C2=A0 =C2=A0 =C2=A0 - autovacuum_vacuum_scale_factor=3D0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 - autovacuum_vacuum_threshold=3D100000 # 100K
(10% was a lot of tuples). This was definitely an improvement, but
when the big vacuum (freeze) kicked off there was a noticeable
io/latency spike. We then tried setting:

=C2=A0 =C2=A0 =C2=A0 - autovacuum_freeze_table_age=3D100000000 # 100M

which seemed to make it happen more frequently (and one would hope,
with less work to do). We reduced this to 50M, and again it was more
frequent (but not the 2x I expected). And when I dropped it to 10M,
nothing changed.

After re-reading the docs, I got the impression I also needed to set:

=C2=A0 =C2=A0 =C2=A0 =C2=A0 - autovacuum_freeze_min_age=3D10000000 # 10M
As the system default was 50M. And again, this had an effect, but not
the 5x I was expecting. The docs say:

> all-visible but not all-frozen pages are scanned if the number of tran= sactions that have passed since the last such scan is greater than vacuum_f= reeze_table_age minus vacuum_freeze_min_age

but wouldn't that have been 10M - 50M? i.e. -40M. Is there some other setting I'm missing?

All suggestions welcome!

Thanks,

Graham




--
-slava
--000000000000442042062b11d93b--