Re: BUG #13750: Autovacuum slows down with large numbers of tables. More workers makes it slower.

From: David Gould <daveg(at)sonic(dot)net>
To: Alvaro Herrera <alvherre(at)2ndquadrant(dot)com>
Cc: Jeff Janes <jeff(dot)janes(at)gmail(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Pg Bugs <pgsql-bugs(at)postgresql(dot)org>, Josh Berkus <josh(at)agliodbs(dot)com>
Subject: Re: BUG #13750: Autovacuum slows down with large numbers of tables. More workers makes it slower.
Date: 2016-03-16 21:00:38
Message-ID: 20160316140038.06a1934d@engels
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

On Tue, 15 Mar 2016 14:28:16 -0700
David Gould <daveg(at)sonic(dot)net> wrote:

> On Tue, 15 Mar 2016 17:40:26 -0300
> Alvaro Herrera <alvherre(at)2ndquadrant(dot)com> wrote:
>
> > David Gould wrote:
> > > On Mon, 29 Feb 2016 18:33:50 -0300
> > > Alvaro Herrera <alvherre(at)2ndquadrant(dot)com> wrote:
> > >
> > > > Hi David, did you ever post an updated version of this patch?
> > >
> > > No. Let me fix that now. I've attached my current revision of the patch
> > > based on master. This version is significantly better than the original
> > > version and resolves multiple issues:
> >
> > Thanks for the patch. I spent some time studying it and testing it. I
> > think there's a minor bug in this latest version: the "continue" when
> > the "for" loop exits because of all relids being less than
> > highest_oid_claimed should be a "break" instead. Otherwise the worker
> > will uselessly loop over the whole list of OIDs only to find each time
> > that it has nothing to do.
>
> Good catch. Thanks!

Actually, looking at this more closely, I don't see the problem.
I'm assuming you meant the continue after "if (relid ==InvalidOid)":

/*
* 2. While there are items that have not been visited...
*/
for(oid_idx = 0; oid_idx < numoids; )
{
...
/*
* 4a. Skip past the highest_oid_claimed to find the next oid to work on.
*/
relid = InvalidOid;
while (relid <= highest_oid_claimed && oid_idx < numoids)
relid = table_oids[oid_idx++];
if (relid <= highest_oid_claimed)
relid = InvalidOid;
/* 4b. Claim the chosen table by storing its oid in shared memory. */
MyWorkerInfo->wi_tableoid = relid;

LWLockRelease(AutovacuumLock);

/* If we reached the end of the list there is nothing to do. */
if (relid == InvalidOid)
continue;
...
}

At the continue oid_idx will have been incremented by:

while (relid <= highest_oid_claimed && oid_idx < numoids)
relid = table_oids[oid_idx++];

to be equal to numoids so the for loop will exit immediately as the loop
condition is "oid_idx < numoids".

"break" would work as well, but basically there is only one reason to exit
the for loop, exhausting the list of oids, so continue seemed preferable.

Or am I missing something?

-dg

--
David Gould 510 282 0869 daveg(at)sonic(dot)net
If simplicity worked, the world would be overrun with insects.

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message matvejchikov 2016-03-16 21:59:10 BUG #14027: n_tup_ins increments regardless of insertion success
Previous Message Philip White 2016-03-16 20:53:57 postmaster became multithreaded during startup