Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pkJIJ-0004Tv-8E for pgsql-hackers@arkaria.postgresql.org; Thu, 06 Apr 2023 06:40:27 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1pkJII-00015l-0k for pgsql-hackers@arkaria.postgresql.org; Thu, 06 Apr 2023 06:40:26 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pkJIH-00015b-MN for pgsql-hackers@lists.postgresql.org; Thu, 06 Apr 2023 06:40:25 +0000 Received: from mail-oa1-x35.google.com ([2001:4860:4864:20::35]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1pkJIE-001CH9-Li for pgsql-hackers@postgresql.org; Thu, 06 Apr 2023 06:40:25 +0000 Received: by mail-oa1-x35.google.com with SMTP id 586e51a60fabf-17aa62d0a4aso41292072fac.4 for ; Wed, 05 Apr 2023 23:40:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680763221; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=ax+UvdhxH66EOc67noHAjbnnwnb+Fk6D+KrYbetC2sI=; b=NcLnvQkH5/4y/gtyrV/KqkTTLUHTq8roXW2f5CaAheB4sgMPmon5y6EXeruTmfQZhL JMfEJ4y7VstBdelgYC/XX3E1wQs7tgF4kZ6khEfYZ5nDC+N7yrXVM5fH2Hgvfch7uQkz Q8tGeRcEUK2HdeE2PMuQ8zHsJErBQDDr+IM6buSf20mh5gXJPshQoppMERxtjDYnMbmJ afDjKf2z2FQmbunQa+H9xaYk1180i964lMl8ZoPjaNy40p5yRpHuYRHHC4u/vTflB08H Hrrc8vUMmHKD2H29MRVAKksc8tYCHmsaBhWfPWXcX9AxfcOI8xEDIKkDgvBlOefDcBDK m0OA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680763221; h=content-transfer-encoding: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=ax+UvdhxH66EOc67noHAjbnnwnb+Fk6D+KrYbetC2sI=; b=0OVXUMqtWs3aLJwucC3eszM4vPm6fmSJ3Pb+ofELXtDR54IGeBDfE3yhtkwI7vuGPZ QnJCLRDqDHNPHfSrSiVhgPIyW2gxTUV9kcV8B40R/bpbVrqJxNH4yJxWd/XJbE717E2N m7EU9Dz2L8H97SC7CltuyBdlGuTVaMPb0s5mYs801rlVirUy0pEW0zG426K1rxm1VoGf oT/ESKf6/f02ht3mR7v+FZjcqCPBMLwZBNebiddROzf5ioigmFZO+lNk+LIcUJNQYPEH IyvU5glyMz5B1c0WJSnlfQgftWx7imWz8/9J3TJnGCjAiNEwhCLfCXmT8a3qph7EyGoU yD2Q== X-Gm-Message-State: AAQBX9cnb3pUqNpsP2aeq5nZ67MiIXQzfjljTjfcjjFGjn3Rokwkg1uo Pw//lIPhywy0C+To62wnT1FYXbYaLO6tq+ylUoQ= X-Google-Smtp-Source: AKy350ZcLq3q8dkVp4w6J0bH5uLBSFBlZJrOdaTCahTE0zjBRbOsYqmlWKlMUTvDGB128t+ckgvLnQn9bROIIvGP2sU= X-Received: by 2002:a05:6870:1318:b0:17e:e89f:ab77 with SMTP id 24-20020a056870131800b0017ee89fab77mr4172284oab.1.1680763220791; Wed, 05 Apr 2023 23:40:20 -0700 (PDT) MIME-Version: 1.0 References: <20230329.132155.629765142788133576.horikyota.ntt@gmail.com> <20230329.173456.1185961934810139447.horikyota.ntt@gmail.com> <935191FB-083B-4060-89FC-466F61FAA391@yesql.se> <1252075.1680547394@sss.pgh.pa.us> <20230403190837.qubpnwugfe2k2g46@awork3.anarazel.de> <7E06F879-7E20-4A6A-862F-CA72CDC9A323@yesql.se> In-Reply-To: From: Masahiko Sawada Date: Thu, 6 Apr 2023 15:39:43 +0900 Message-ID: Subject: Re: Should vacuum process config file reload more often To: Melanie Plageman Cc: Daniel Gustafsson , Andres Freund , Tom Lane , Kyotaro Horiguchi , PostgreSQL Hackers , Amit Kapila Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Thu, Apr 6, 2023 at 12:29=E2=80=AFAM Melanie Plageman wrote: > > Thanks all for the reviews. > > v16 attached. I put it together rather quickly, so there might be a few > spurious whitespaces or similar. There is one rather annoying pgindent > outlier that I have to figure out what to do about as well. > > The remaining functional TODOs that I know of are: > > - Resolve what to do about names of GUC and vacuum variables for cost > limit and cost delay (since it may affect extensions) > > - Figure out what to do about the logging message which accesses dboid > and tableoid (lock/no lock, where to put it, etc) > > - I see several places in docs which reference the balancing algorithm > for autovac workers. I did not read them in great detail, but we may > want to review them to see if any require updates. > > - Consider whether or not the initial two commits should just be > squashed with the third commit > > - Anything else reviewers are still unhappy with > > > On Wed, Apr 5, 2023 at 1:56=E2=80=AFAM Masahiko Sawada wrote: > > > > On Wed, Apr 5, 2023 at 5:05=E2=80=AFAM Melanie Plageman > > wrote: > > > > > > On Tue, Apr 4, 2023 at 4:27=E2=80=AFAM Masahiko Sawada wrote: > > > > --- > > > > - if (worker->wi_proc !=3D NULL) > > > > - elog(DEBUG2, "autovac_balance_cost(pid=3D%= d > > > > db=3D%u, rel=3D%u, dobalance=3D%s cost_limit=3D%d, cost_limit_base= =3D%d, > > > > cost_delay=3D%g)", > > > > - worker->wi_proc->pid, > > > > worker->wi_dboid, worker->wi_tableoid, > > > > - worker->wi_dobalance ? "yes" : "n= o", > > > > - worker->wi_cost_limit, > > > > worker->wi_cost_limit_base, > > > > - worker->wi_cost_delay); > > > > > > > > I think it's better to keep this kind of log in some form for > > > > debugging. For example, we can show these values of autovacuum work= ers > > > > in VacuumUpdateCosts(). > > > > > > I added a message to do_autovacuum() after calling VacuumUpdateCosts(= ) > > > in the loop vacuuming each table. That means it will happen once per > > > table. It's not ideal that I had to move the call to VacuumUpdateCost= s() > > > behind the shared lock in that loop so that we could access the pid a= nd > > > such in the logging message after updating the cost and delay, but it= is > > > probably okay. Though noone is going to be changing those at this > > > point, it still seemed better to access them under the lock. > > > > > > This does mean we won't log anything when we do change the values of > > > VacuumCostDelay and VacuumCostLimit while vacuuming a table. Is it wo= rth > > > adding some code to do that in VacuumUpdateCosts() (only when the val= ue > > > has changed not on every call to VacuumUpdateCosts())? Or perhaps we > > > could add it in the config reload branch that is already in > > > vacuum_delay_point()? > > > > Previously, we used to show the pid in the log since a worker/launcher > > set other workers' delay costs. But now that the worker sets its delay > > costs, we don't need to show the pid in the log. Also, I think it's > > useful for debugging and investigating the system if we log it when > > changing the values. The log I imagined to add was like: > > > > @@ -1801,6 +1801,13 @@ VacuumUpdateCosts(void) > > VacuumCostDelay =3D vacuum_cost_delay; > > > > AutoVacuumUpdateLimit(); > > + > > + elog(DEBUG2, "autovacuum update costs (db=3D%u, rel=3D%u, > > dobalance=3D%s, cost_limit=3D%d, cost_delay=3D%g active=3D%s failsafe= =3D%s)", > > + MyWorkerInfo->wi_dboid, MyWorkerInfo->wi_tableoid, > > + pg_atomic_unlocked_test_flag(&MyWorkerInfo->wi_dobalance) > > ? "no" : "yes", > > + VacuumCostLimit, VacuumCostDelay, > > + VacuumCostDelay > 0 ? "yes" : "no", > > + VacuumFailsafeActive ? "yes" : "no"); > > } > > else > > { > > Makes sense. I've updated the log message to roughly what you suggested. > I also realized I think it does make sense to call it in > VacuumUpdateCosts() -- only for autovacuum workers of course. I've done > this. I haven't taken the lock though and can't decide if I must since > they access dboid and tableoid -- those are not going to change at this > point, but I still don't know if I can access them lock-free... > Perhaps there is a way to condition it on the log level? > > If I have to take a lock, then I don't know if we should put these in > VacuumUpdateCosts()... I think we don't need to acquire a lock there as both values are updated only by workers reporting this message. Also I agree with where to put the log but I think the log message should start with lower cases: + elog(DEBUG2, + "Autovacuum VacuumUpdateCosts(db=3D%u, rel=3D%u, dobalance=3D%s, cost_limit=3D%d, cost_delay=3D%g active=3D%s failsafe=3D%s)= ", + MyWorkerInfo->wi_dboid, MyWorkerInfo->wi_tableoid= , + pg_atomic_unlocked_test_flag(&MyWorkerInfo->wi_dobalance) ? "no" : "yes", + VacuumCostLimit, VacuumCostDelay, + VacuumCostDelay > 0 ? "yes" : "no", + VacuumFailsafeActive ? "yes" : "no"); Some minor comments on 0003: +/* + * autovac_recalculate_workers_for_balance + * Recalculate the number of workers to consider, given cost-related + * storage parameters and the current number of active workers= . + * + * Caller must hold the AutovacuumLock in at least shared mode to access + * worker->wi_proc. + */ Does it make sense to add Assert(LWLockHeldByMe(AutovacuumLock)) at the beginning of this function? --- /* rebalance in case the default cost parameters changed *= / - LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE); - autovac_balance_cost(); + LWLockAcquire(AutovacuumLock, LW_SHARED); + autovac_recalculate_workers_for_balance(); LWLockRelease(AutovacuumLock); Do we really need to have the autovacuum launcher recalculate av_nworkersForBalance after reloading the config file? Since the cost parameters are not used inautovac_recalculate_workers_for_balance() the comment also needs to be updated. --- + /* + * Balance and update limit values for autovacuum workers. We must + * always do this in case the autovacuum launcher or anoth= er + * autovacuum worker has recalculated the number of workers across + * which we must balance the limit. This is done by the launcher when + * launching a new worker and by workers before vacuuming each table. + */ + AutoVacuumUpdateCostLimit(); I think the last sentence is not correct. IIUC recalculation of av_nworkersForBalance is done by the launcher after a worker finished and by workers before vacuuming each table. --- It's not a problem of this patch, but IIUC since we don't reset wi_dobalance after vacuuming each table we use the last value of wi_dobalance for performing autovacuum items. At end of the loop for tables in do_autovacuum() we have the following code that explains why we don't reset wi_dobalance: /* * Remove my info from shared memory. We could, but intentionally * don't, unset wi_dobalance on the assumption that we are more lik= ely * than not to vacuum a table with no cost-related storage paramete= rs * next, so we don't want to give up our share of I/O for a very sh= ort * interval and thereby thrash the global balance. */ LWLockAcquire(AutovacuumScheduleLock, LW_EXCLUSIVE); MyWorkerInfo->wi_tableoid =3D InvalidOid; MyWorkerInfo->wi_sharedrel =3D false; LWLockRelease(AutovacuumScheduleLock); Assuming we agree with that, probably we need to reset it to true after vacuuming all tables? 0001 and 0002 patches look good to me except for the renaming GUCs stuff as the discussion is ongoing. Regards, -- Masahiko Sawada Amazon Web Services: https://aws.amazon.com