Re: We should stop telling users to "vacuum that database in single-user mode"

2021-03-05 Thread Alvaro Herrera
On 2021-Mar-02, David Rowley wrote:

> However, I wonder if it's worth going a few steps further to try and
> reduce the chances of that message being seen in the first place.
> Maybe it's worth considering ditching any (auto)vacuum cost limits for
> any table which is within X transaction from wrapping around.
> Likewise for "VACUUM;" when the database's datfrozenxid is getting
> dangerously high.

Yeah, I like this kind of approach, and I think one change we can do
that can have a very large effect is to disable index cleanup when in
emergency situations.  That way, the XID limit is advanced as much as
possible with as little effort as possible; once the system is back in
normal conditions, indexes can be cleaned up at a leisurely pace.

-- 
Álvaro Herrera   Valdivia, Chile
"El destino baraja y nosotros jugamos" (A. Schopenhauer)




Re: We should stop telling users to "vacuum that database in single-user mode"

2021-03-03 Thread Robert Treat
On Wed, Mar 3, 2021 at 7:10 AM Hannu Krosing  wrote:
> On Wed, Mar 3, 2021 at 11:33 AM David Rowley  wrote:
> > On Wed, 3 Mar 2021 at 21:44, Magnus Hagander  wrote:
> >
> > I meant to ignore the cost limits if we're within a hundred million or
> > so of the stopLimit.  Per what Hannu mentioned, there does not seem to
> > be a great need with current versions of PostgreSQL to restart in the
> > instance in single-user mode. VACUUM still works once we're beyond the
> > stopLimit. It's just commands that need to generate a new XID that'll
> > fail with the error message mentioned by Hannu.
>
> I am investigating a possibility of introducing a special "Restricted
> Maintenance
> Mode" to let admin mitigate after xidStopLimit, maybe for another 0.5M txids,
> by doing things like
>
> * dropping an index - to make vacuum faster
> * dropping a table - sometimes it is better to drop a table in order to get 
> the
>   production database functional again instead of waiting hours for the vacuum
>   to finish.
>   And then later restore it from backup or maybe access it from a read-only
>   clone of the database via FDW.
> * drop a stale replication slot which is holding back vacuum
>

I've talked with a few people about modifying wraparound and xid
emergency vacuums to be more efficient, ie. run them without indexes,
and possibly some other options. That seems like low-hanging fruit if
not already a thing.

> To make sure that this will not accidentally just move xidStopLimit to 0.5M 
> for
> users who run main workloads as a superuser (they do exists!) this mode should
> be restricted to
> * only superuser
> * only a subset of commands /  functions
> * be heavily throttled to avoid running out of TXIDs, maybe 1-10 xids per 
> second
> * maybe require also setting a GUC to be very explicit
>
> > > I agree with your other idea, that of kicking in a more aggressive
> > > autovacuum if it's not dealing with things fast enough. Maybe even on
> > > an incremental way - that is run with the default, then at another
> > > threshold drop them to half, and at yet another threshold drop them to
> > > 0. I agree that pretty much anything is better than forcing the user
> > > into single user mode.
> >
> > OK cool. I wondered if it should be reduced incrementally or just
> > switch off the cost limit completely once we're beyond
> > ShmemVariableCache->xidStopLimit.
>
> Abrupt change is something that is more likely to make the user/DBA notice
> that something is going on. I have even been thinking about deliberate
> throttling to make the user notice / pay attention.
>

I worry that we're walking down the path of trying to find "clever"
solutions in a situation where the variety of production environments
(and therefore the right way to handle this issue) is nearly endless.
That said... I think at the point we're talking about, subtly is not
an absolute requirement... if people were paying attention they'd have
noticed autovacuum for wrap-around running or warnings in the logs; at
some point you do need to be a bit in your face that there is a real
possibility of disaster around the corner.

> > If we did want it to be incremental
> > then if we had say ShmemVariableCache->xidFastVacLimit, which was
> > about 100 million xids before xidStopLimit, then the code could adjust
> > the sleep delay down by the percentage through we are from
> > xidFastVacLimit to xidStopLimit.
> >
> > However, if we want to keep adjusting the sleep delay then we need to
> > make that work for vacuums that are running already. We don't want to
> > call ReadNextTransactionId() too often, but maybe if we did it once
> > per 10 seconds worth of vacuum_delay_point()s.  That way we'd never do
> > it for vacuums already going at full speed.
>
> There are already samples of this in code, for example the decision to
> force-start disabled autovacuum is considered after every 64k transactions.
>
> There is a related item in https://commitfest.postgresql.org/32/2983/ .
> When that gets done, we could drive the adjustments from autovacuum.c by
> adding the remaining XID range adjustment to existing worker delay adjust
> mechanisms in autovac_balance_cost() and signalling the autovacuum
> backend to run the adjustment every few seconds once we are in the danger
> zone.
>

That patch certainly looks interesting; many many times I've had to
have people kick off manual vacuums to use more i/o and kill the
wrap-around vacuum. Reading the discussion there, I wonder if we
should think about weighting the most urgent vacuum at the expense of
other potential autovacuums, although I feel like they often come in
bunches in these scenarios.


Robert Treat
https://xzilla.net




Re: We should stop telling users to "vacuum that database in single-user mode"

2021-03-03 Thread Hannu Krosing
On Wed, Mar 3, 2021 at 11:33 AM David Rowley  wrote:
>
> On Wed, 3 Mar 2021 at 21:44, Magnus Hagander  wrote:
...
> > I think we misunderstand each other. I meant this only as a comment
> > about the idea of ignoring the cost limit in single user mode -- that
> > is, it's a reason to *want* vacuum to not run as quickly as possible
> > in single user mode. I should've trimmed the email better.
>
> I meant to ignore the cost limits if we're within a hundred million or
> so of the stopLimit.  Per what Hannu mentioned, there does not seem to
> be a great need with current versions of PostgreSQL to restart in the
> instance in single-user mode. VACUUM still works once we're beyond the
> stopLimit. It's just commands that need to generate a new XID that'll
> fail with the error message mentioned by Hannu.

I am investigating a possibility of introducing a special "Restricted
Maintenance
Mode" to let admin mitigate after xidStopLimit, maybe for another 0.5M txids,
by doing things like

* dropping an index - to make vacuum faster
* dropping a table - sometimes it is better to drop a table in order to get the
  production database functional again instead of waiting hours for the vacuum
  to finish.
  And then later restore it from backup or maybe access it from a read-only
  clone of the database via FDW.
* drop a stale replication slot which is holding back vacuum

To make sure that this will not accidentally just move xidStopLimit to 0.5M for
users who run main workloads as a superuser (they do exists!) this mode should
be restricted to
* only superuser
* only a subset of commands /  functions
* be heavily throttled to avoid running out of TXIDs, maybe 1-10 xids per second
* maybe require also setting a GUC to be very explicit

> > I agree with your other idea, that of kicking in a more aggressive
> > autovacuum if it's not dealing with things fast enough. Maybe even on
> > an incremental way - that is run with the default, then at another
> > threshold drop them to half, and at yet another threshold drop them to
> > 0. I agree that pretty much anything is better than forcing the user
> > into single user mode.
>
> OK cool. I wondered if it should be reduced incrementally or just
> switch off the cost limit completely once we're beyond
> ShmemVariableCache->xidStopLimit.

Abrupt change is something that is more likely to make the user/DBA notice
that something is going on. I have even been thinking about deliberate
throttling to make the user notice / pay attention.

> If we did want it to be incremental
> then if we had say ShmemVariableCache->xidFastVacLimit, which was
> about 100 million xids before xidStopLimit, then the code could adjust
> the sleep delay down by the percentage through we are from
> xidFastVacLimit to xidStopLimit.
>
> However, if we want to keep adjusting the sleep delay then we need to
> make that work for vacuums that are running already. We don't want to
> call ReadNextTransactionId() too often, but maybe if we did it once
> per 10 seconds worth of vacuum_delay_point()s.  That way we'd never do
> it for vacuums already going at full speed.

There are already samples of this in code, for example the decision to
force-start disabled autovacuum is considered after every 64k transactions.

There is a related item in https://commitfest.postgresql.org/32/2983/ .
When that gets done, we could drive the adjustments from autovacuum.c by
adding the remaining XID range adjustment to existing worker delay adjust
mechanisms in autovac_balance_cost() and signalling the autovacuum
backend to run the adjustment every few seconds once we are in the danger
zone.

Cheers
Hannu




Re: We should stop telling users to "vacuum that database in single-user mode"

2021-03-03 Thread David Rowley
On Wed, 3 Mar 2021 at 21:44, Magnus Hagander  wrote:
>
> On Tue, Mar 2, 2021 at 10:07 PM David Rowley  wrote:
> >
> > On Wed, 3 Mar 2021 at 01:12, Magnus Hagander  wrote:
> > >
> > > On Tue, Mar 2, 2021 at 7:52 AM David Rowley  wrote:
> > > > I have seen it happen that an instance has a vacuum_cost_limit set and
> > > > someone did start the database in single-user mode, per the advice of
> > > > the error message only to find that the VACUUM took a very long time
> > > > due to the restrictive cost limit. I struggle to imagine why anyone
> > > > wouldn't want the vacuum to run as quickly as possible in that
> > > > situation.
> > >
> > > Multiple instances running on the same hardware and only one of them
> > > being in trouble?
> >
> > You might be right. I'm not saying it's a great idea but thought it
> > was worth considering.
> >
> > We could turn to POLA and ask; what would you be more surprised at; 1)
> > Your database suddenly using more I/O than it had been previously, or;
> > 2) Your database no longer accepting DML.
>
> I think we misunderstand each other. I meant this only as a comment
> about the idea of ignoring the cost limit in single user mode -- that
> is, it's a reason to *want* vacuum to not run as quickly as possible
> in single user mode. I should've trimmed the email better.

I meant to ignore the cost limits if we're within a hundred million or
so of the stopLimit.  Per what Hannu mentioned, there does not seem to
be a great need with current versions of PostgreSQL to restart in the
instance in single-user mode. VACUUM still works once we're beyond the
stopLimit. It's just commands that need to generate a new XID that'll
fail with the error message mentioned by Hannu.

> I agree with your other idea, that of kicking in a more aggressive
> autovacuum if it's not dealing with things fast enough. Maybe even on
> an incremental way - that is run with the default, then at another
> threshold drop them to half, and at yet another threshold drop them to
> 0. I agree that pretty much anything is better than forcing the user
> into single user mode.

OK cool. I wondered if it should be reduced incrementally or just
switch off the cost limit completely once we're beyond
ShmemVariableCache->xidStopLimit.  If we did want it to be incremental
then if we had say ShmemVariableCache->xidFastVacLimit, which was
about 100 million xids before xidStopLimit, then the code could adjust
the sleep delay down by the percentage through we are from
xidFastVacLimit to xidStopLimit.

However, if we want to keep adjusting the sleep delay then we need to
make that work for vacuums that are running already. We don't want to
call ReadNextTransactionId() too often, but maybe if we did it once
per 10 seconds worth of vacuum_delay_point()s.  That way we'd never do
it for vacuums already going at full speed.

David




Re: We should stop telling users to "vacuum that database in single-user mode"

2021-03-03 Thread Magnus Hagander
On Tue, Mar 2, 2021 at 10:07 PM David Rowley  wrote:
>
> On Wed, 3 Mar 2021 at 01:12, Magnus Hagander  wrote:
> >
> > On Tue, Mar 2, 2021 at 7:52 AM David Rowley  wrote:
> > > I have seen it happen that an instance has a vacuum_cost_limit set and
> > > someone did start the database in single-user mode, per the advice of
> > > the error message only to find that the VACUUM took a very long time
> > > due to the restrictive cost limit. I struggle to imagine why anyone
> > > wouldn't want the vacuum to run as quickly as possible in that
> > > situation.
> >
> > Multiple instances running on the same hardware and only one of them
> > being in trouble?
>
> You might be right. I'm not saying it's a great idea but thought it
> was worth considering.
>
> We could turn to POLA and ask; what would you be more surprised at; 1)
> Your database suddenly using more I/O than it had been previously, or;
> 2) Your database no longer accepting DML.

I think we misunderstand each other. I meant this only as a comment
about the idea of ignoring the cost limit in single user mode -- that
is, it's a reason to *want* vacuum to not run as quickly as possible
in single user mode. I should've trimmed the email better.

I agree with your other idea, that of kicking in a more aggressive
autovacuum if it's not dealing with things fast enough. Maybe even on
an incremental way - that is run with the default, then at another
threshold drop them to half, and at yet another threshold drop them to
0. I agree that pretty much anything is better than forcing the user
into single user mode.

-- 
 Magnus Hagander
 Me: https://www.hagander.net/
 Work: https://www.redpill-linpro.com/




Re: We should stop telling users to "vacuum that database in single-user mode"

2021-03-02 Thread David Rowley
On Wed, 3 Mar 2021 at 01:12, Magnus Hagander  wrote:
>
> On Tue, Mar 2, 2021 at 7:52 AM David Rowley  wrote:
> > I have seen it happen that an instance has a vacuum_cost_limit set and
> > someone did start the database in single-user mode, per the advice of
> > the error message only to find that the VACUUM took a very long time
> > due to the restrictive cost limit. I struggle to imagine why anyone
> > wouldn't want the vacuum to run as quickly as possible in that
> > situation.
>
> Multiple instances running on the same hardware and only one of them
> being in trouble?

You might be right. I'm not saying it's a great idea but thought it
was worth considering.

We could turn to POLA and ask; what would you be more surprised at; 1)
Your database suddenly using more I/O than it had been previously, or;
2) Your database no longer accepting DML.

David




Re: We should stop telling users to "vacuum that database in single-user mode"

2021-03-02 Thread Magnus Hagander
On Tue, Mar 2, 2021 at 7:52 AM David Rowley  wrote:
>
> On Tue, 2 Mar 2021 at 04:32, Hannu Krosing  wrote:
> >
> > It looks like we are unnecessarily instructing our usiers to vacuum their
> > databases in single-user mode when just vacuuming would be enough.
> >
> > We should fix the error message to be less misleading.
>
> It would be good to change the message as it's pretty outdated. Back
> in 8ad3965a1 (2005) when the message was added, SELECT and VACUUM
> would have called GetNewTransactionId().  That's no longer the case.
> We only do that when we actually need an XID.
>
> However, I wonder if it's worth going a few steps further to try and
> reduce the chances of that message being seen in the first place.
> Maybe it's worth considering ditching any (auto)vacuum cost limits for
> any table which is within X transaction from wrapping around.
> Likewise for "VACUUM;" when the database's datfrozenxid is getting
> dangerously high.
>
> Such "emergency" vacuums could be noted in the auto-vacuum log and
> NOTICEd or WARNING sent to the user during manual VACUUMs. Maybe the
> value of X could be xidStopLimit minus a hundred million or so.
>
> I have seen it happen that an instance has a vacuum_cost_limit set and
> someone did start the database in single-user mode, per the advice of
> the error message only to find that the VACUUM took a very long time
> due to the restrictive cost limit. I struggle to imagine why anyone
> wouldn't want the vacuum to run as quickly as possible in that
> situation.

Multiple instances running on the same hardware and only one of them
being in trouble?

But it would probably be worthwhile throwing a WARNING if vacuum is
run with cost delay enabled in single user mode -- so that the user is
at least aware of the choice (and can cancel and try again). Maybe
even a warning directly when starting up a single user session, to let
them know?


-- 
 Magnus Hagander
 Me: https://www.hagander.net/
 Work: https://www.redpill-linpro.com/




Re: We should stop telling users to "vacuum that database in single-user mode"

2021-03-01 Thread David Rowley
On Tue, 2 Mar 2021 at 04:32, Hannu Krosing  wrote:
>
> It looks like we are unnecessarily instructing our usiers to vacuum their
> databases in single-user mode when just vacuuming would be enough.
>
> We should fix the error message to be less misleading.

It would be good to change the message as it's pretty outdated. Back
in 8ad3965a1 (2005) when the message was added, SELECT and VACUUM
would have called GetNewTransactionId().  That's no longer the case.
We only do that when we actually need an XID.

However, I wonder if it's worth going a few steps further to try and
reduce the chances of that message being seen in the first place.
Maybe it's worth considering ditching any (auto)vacuum cost limits for
any table which is within X transaction from wrapping around.
Likewise for "VACUUM;" when the database's datfrozenxid is getting
dangerously high.

Such "emergency" vacuums could be noted in the auto-vacuum log and
NOTICEd or WARNING sent to the user during manual VACUUMs. Maybe the
value of X could be xidStopLimit minus a hundred million or so.

I have seen it happen that an instance has a vacuum_cost_limit set and
someone did start the database in single-user mode, per the advice of
the error message only to find that the VACUUM took a very long time
due to the restrictive cost limit. I struggle to imagine why anyone
wouldn't want the vacuum to run as quickly as possible in that
situation.

(Ideally, the speed of auto-vacuum would be expressed as a percentage
of time spent working vs sleeping rather than an absolute speed
limit... that way, faster servers would get faster vacuums, assuming
the same settings.  Vacuums may also get more work done per unit of
time during offpeak, which seems like it might be a thing that people
might want.)

David




Re: We should stop telling users to "vacuum that database in single-user mode"

2021-03-01 Thread Noah Misch
On Mon, Mar 01, 2021 at 04:32:23PM +0100, Hannu Krosing wrote:
> It looks like we are unnecessarily instructing our usiers to vacuum their
> databases in single-user mode when just vacuuming would be enough.

> When I started looking at improving the situation I discovered, that there
> already is no need to run VACUUM in single user mode in any currently 
> supported
> PostgreSQL version as you can run VACUUM perfectly well when the wraparound
> protection is active.

A comment in SetTransactionIdLimit() says, "VACUUM requires an XID if it
truncates at wal_level!=minimal."  Hence, I think plain VACUUM will fail some
of the time; VACUUM (TRUNCATE false) should be reliable.  In general, I like
your goal of replacing painful error message advice with less-painful advice.
At the same time, it's valuable for the advice to reliably get the user out of
the bad situation.