Re: Option to not use ringbuffer in VACUUM, using it in failsafe mode
Melanie Plageman <melanieplageman@gmail.com>
From: Melanie Plageman <melanieplageman@gmail.com>
To: Andres Freund <andres@anarazel.de>
Cc: David Rowley <dgrowleyml@gmail.com>, Justin Pryzby <pryzby@telsasoft.com>, Masahiko Sawada <sawada.mshk@gmail.com>, Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>,
Tom Lane <tgl@sss.pgh.pa.us>, Peter Geoghegan <pg@bowt.ie>, pgsql-hackers@postgresql.org, Robert Haas <robertmhaas@gmail.com>
Date: 2023-04-06T00:41:48Z
Lists: pgsql-hackers
Attachments
- v12-0002-Push-vacuum-setup-code-up-into-ExecVacuum.patch (text/x-patch) patch v12-0002
- v12-0004-Add-buffer-usage-limit-option-to-vacuumdb.patch (text/x-patch) patch v12-0004
- v12-0001-VACUUM-FULL-ANALYZE-needs-BufferAccessStrategy.patch (text/x-patch) patch v12-0001
- v12-0003-Add-VACUUM-BUFFER_USAGE_LIMIT-option-and-GUC.patch (text/x-patch) patch v12-0003
On Wed, Apr 5, 2023 at 6:55 PM Melanie Plageman <melanieplageman@gmail.com> wrote: > > On Wed, Apr 5, 2023 at 5:15 PM Andres Freund <andres@anarazel.de> wrote: > > > > Hi, > > > > On 2023-04-05 16:17:20 -0400, Melanie Plageman wrote: > > > On Wed, Apr 5, 2023 at 1:05 PM Andres Freund <andres@anarazel.de> wrote: > > > > Perhaps the best solution for autovac vs interactive vacuum issue would be to > > > > move the allocation of the bstrategy to ExecVacuum()? > > > > > > So, I started looking into allocating the bstrategy in ExecVacuum(). > > > > > > While doing so, I was trying to understand if the "sanity checking" in > > > vacuum() could possibly apply to autovacuum, and I don't really see how. > > > > > > AFAICT, autovacuum does not ever set VACOPT_DISABLE_PAGE_SKIPPING or > > > VACOPT_FULL or VACOPT_ONLY_DATABASE_STATS. > > > > > > We could move those sanity checks up into ExecVacuum(). > > > > Would make sense. > > > > ISTM that eventually most of what currently happens in vacuum() should be in > > ExecVacuum(). There's a lot of stuff that can't happen for autovacuum. So it > > just seems to make more sense to move those parts to ExecVacuum(). > > I've done that in the attached wip patch. It is perhaps too much of a > change, I dunno. > > > > I also noticed that we make the vac_context in vacuum() which says it is > > > for "cross-transaction storage". We use it for the buffer access > > > strategy and for the newrels relation list created in vacuum(). Then we > > > delete it at the end of vacuum(). > > > > > Autovacuum workers already make a similar kind of memory context called > > > AutovacMemCxt in do_autovacuum() which the comment says is for the list > > > of relations to vacuum/analyze across transactions. > > > > AutovacMemCxt seems to be a bit longer lived / cover more than the context > > created in vacuum(). It's where all the hash tables etc live that > > do_autovacuum() uses to determine what to vacuum. > > > > Note that do_autovacuum() also creates: > > > > /* > > * create a memory context to act as fake PortalContext, so that the > > * contexts created in the vacuum code are cleaned up for each table. > > */ > > PortalContext = AllocSetContextCreate(AutovacMemCxt, > > "Autovacuum Portal", > > ALLOCSET_DEFAULT_SIZES); > > > > which is then what vacuum() creates the "Vacuum" context in. > > Yea, I realized that when writing the patch. > > > > What if we made ExecVacuum() make its own memory context and both it and > > > do_autovacuum() pass that memory context (along with the buffer access > > > strategy they make) to vacuum(), which then uses the memory context in > > > the same way it does now? > > > > Maybe? It's not clear to me why it'd be a win. > > Less that it is a win and more that we need access to that memory > context when allocating the buffer access strategy, so we would have had > to make it in ExecVacuum(). And if we have already made it, we would > need to pass it in to vacuum() for it to use. > > > > It simplifies the buffer usage limit patchset and also seems a bit more > > > clear than what is there now? > > > > I don't really see what it'd make simpler? The context in vacuum() is used for > > just that vacuum - we couldn't just use AutovacMemCxt, as that'd live much > > longer (for all the tables a autovac worker processes). > > Autovacuum already made the BufferAccessStrategy in the AutovacMemCxt, > so this is the same behavior. I simply made autovacuum_do_vac_analyze() > make the per table vacuum memory context and pass that to vacuum(). So > we have the same amount of memory context granularity as before. > > Attached patchset has some kind of isolation test failure due to a hard > deadlock that I haven't figured out yet. I thought it was something with > the "in_vacuum" static variable and having VACUUM or ANALYZE called when > already in VACUUM or ANALYZE, but that variable is the same as in > master. > > I've mostly shared it because I want to know if this approach is worth > pursuing or not. Figured out how to fix the issue, though I'm not sure I understand how the issue can occur. use_own_xacts seems like it will always be true for autovacuum when it calls vacuum() and ExecVacuum() only calls vacuum() once, so I thought that I could make use_own_xacts a parameter to vacuum() and push up its calculation for VACUUM and ANALYZE into ExecVacuum(). This caused a deadlock, so there must be a way that in_vacuum is false but vacuum() is called in a nested context. Anyway, recalculating it every time in vacuum() fixes it. Attached is a v12 of the whole vacuum_buffer_usage_limit patch set which includes a commit to fix the bug in master and a commit to move relevant code from vacuum() up into ExecVacuum(). The logic I suggested earlier for fixing the bug was...not right. Attached fix should be right? - Melanie
Commits
-
Add unit to vacuum_buffer_usage_limit value in postgresql.conf.sample.
- b72f564d87d1 16.0 landed
-
Improve VACUUM/ANALYZE BUFFER_USAGE_LIMIT docs
- c0235013c13b 16.0 landed
-
Add --buffer-usage-limit option to vacuumdb
- ae78cae3be62 16.0 landed
-
Add VACUUM/ANALYZE BUFFER_USAGE_LIMIT option
- 1cbbee033857 16.0 landed
-
Move various prechecks from vacuum() into ExecVacuum()
- b9b125b9c143 16.0 landed
-
Always make a BufferAccessStrategy for ANALYZE
- bccd6908ca82 16.0 landed
-
Rename BufferAccessStrategyData.ring_size to nbuffers
- 8d928e3a9fe7 16.0 landed
-
Disable vacuum's use of a buffer access strategy during failsafe
- 4830f1024325 16.0 landed
-
Only make buffer strategy for vacuum when it's likely needed
- 32fbe0239b03 16.0 landed
-
Remove some global variables from vacuum.c
- 3f476c953495 16.0 landed
-
Doc: add Buffer Access Strategy to the glossary
- c8f8d0eb1868 16.0 landed