Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit32896c4

Browse files
committed
Avoid having autovacuum workers wait for relation locks.
Waiting for relation locks can lead to starvation - it pins down anautovacuum worker for as long as the lock is held. But if we're doingan anti-wraparound vacuum, then we still wait; maintenance can no longerbe put off.To assist with troubleshooting, if log_autovacuum_min_duration >= 0,we log whenever an autovacuum or autoanalyze is skipped for this reason.Per a gripe by Josh Berkus, and ensuing discussion.
1 parent47082fa commit32896c4

File tree

5 files changed

+61
-15
lines changed

5 files changed

+61
-15
lines changed

‎doc/src/sgml/config.sgml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4080,7 +4080,10 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
40804080
all autovacuum actions. Minus-one (the default) disables logging
40814081
autovacuum actions. For example, if you set this to
40824082
<literal>250ms</literal> then all automatic vacuums and analyzes that run
4083-
250ms or longer will be logged. Enabling this parameter can be helpful
4083+
250ms or longer will be logged. In addition, when this parameter is
4084+
set to any value other than <literal>-1</literal>, a message will be
4085+
logged if an autovacuum action is skipped due to the existence of a
4086+
conflicting lock. Enabling this parameter can be helpful
40844087
in tracking autovacuum activity. This setting can only be set in
40854088
the <filename>postgresql.conf</> file or on the server command line.
40864089
</para>

‎src/backend/commands/analyze.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include"pgstat.h"
3737
#include"postmaster/autovacuum.h"
3838
#include"storage/bufmgr.h"
39+
#include"storage/lmgr.h"
3940
#include"storage/proc.h"
4041
#include"storage/procarray.h"
4142
#include"utils/acl.h"
@@ -148,7 +149,19 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
148149
* matter if we ever try to accumulate stats on dead tuples.) If the rel
149150
* has been dropped since we last saw it, we don't need to process it.
150151
*/
151-
onerel=try_relation_open(relid,ShareUpdateExclusiveLock);
152+
if (!(vacstmt->options&VACOPT_NOWAIT))
153+
onerel=try_relation_open(relid,ShareUpdateExclusiveLock);
154+
elseif (ConditionalLockRelationOid(relid,ShareUpdateExclusiveLock))
155+
onerel=try_relation_open(relid,NoLock);
156+
else
157+
{
158+
onerel=NULL;
159+
if (IsAutoVacuumWorkerProcess()&&Log_autovacuum_min_duration >=0)
160+
ereport(LOG,
161+
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
162+
errmsg("skipping analyze of \"%s\" --- lock not available",
163+
vacstmt->relation->relname)));
164+
}
152165
if (!onerel)
153166
return;
154167

‎src/backend/commands/vacuum.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static BufferAccessStrategy vac_strategy;
6161
/* non-export function prototypes */
6262
staticList*get_rel_oids(Oidrelid,constRangeVar*vacrel);
6363
staticvoidvac_truncate_clog(TransactionIdfrozenXID);
64-
staticvoidvacuum_rel(Oidrelid,VacuumStmt*vacstmt,booldo_toast,
64+
staticboolvacuum_rel(Oidrelid,VacuumStmt*vacstmt,booldo_toast,
6565
boolfor_wraparound,bool*scanned_all);
6666

6767

@@ -226,8 +226,11 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
226226
boolscanned_all= false;
227227

228228
if (vacstmt->options&VACOPT_VACUUM)
229-
vacuum_rel(relid,vacstmt,do_toast,for_wraparound,
230-
&scanned_all);
229+
{
230+
if (!vacuum_rel(relid,vacstmt,do_toast,for_wraparound,
231+
&scanned_all))
232+
continue;
233+
}
231234

232235
if (vacstmt->options&VACOPT_ANALYZE)
233236
{
@@ -764,7 +767,7 @@ vac_truncate_clog(TransactionId frozenXID)
764767
*
765768
*At entry and exit, we are not inside a transaction.
766769
*/
767-
staticvoid
770+
staticbool
768771
vacuum_rel(Oidrelid,VacuumStmt*vacstmt,booldo_toast,boolfor_wraparound,
769772
bool*scanned_all)
770773
{
@@ -835,14 +838,29 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
835838
*
836839
* There's a race condition here: the rel may have gone away since the
837840
* last time we saw it. If so, we don't need to vacuum it.
841+
*
842+
* If we've been asked not to wait for the relation lock, acquire it
843+
* first in non-blocking mode, before calling try_relation_open().
838844
*/
839-
onerel=try_relation_open(relid,lmode);
845+
if (!(vacstmt->options&VACOPT_NOWAIT))
846+
onerel=try_relation_open(relid,lmode);
847+
elseif (ConditionalLockRelationOid(relid,lmode))
848+
onerel=try_relation_open(relid,NoLock);
849+
else
850+
{
851+
onerel=NULL;
852+
if (IsAutoVacuumWorkerProcess()&&Log_autovacuum_min_duration >=0)
853+
ereport(LOG,
854+
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
855+
errmsg("skipping vacuum of \"%s\" --- lock not available",
856+
vacstmt->relation->relname)));
857+
}
840858

841859
if (!onerel)
842860
{
843861
PopActiveSnapshot();
844862
CommitTransactionCommand();
845-
return;
863+
return false;
846864
}
847865

848866
/*
@@ -873,7 +891,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
873891
relation_close(onerel,lmode);
874892
PopActiveSnapshot();
875893
CommitTransactionCommand();
876-
return;
894+
return false;
877895
}
878896

879897
/*
@@ -890,7 +908,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
890908
relation_close(onerel,lmode);
891909
PopActiveSnapshot();
892910
CommitTransactionCommand();
893-
return;
911+
return false;
894912
}
895913

896914
/*
@@ -905,7 +923,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
905923
relation_close(onerel,lmode);
906924
PopActiveSnapshot();
907925
CommitTransactionCommand();
908-
return;
926+
return false;
909927
}
910928

911929
/*
@@ -989,6 +1007,9 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
9891007
* Now release the session-level lock on the master table.
9901008
*/
9911009
UnlockRelationIdForSession(&onerelid,lmode);
1010+
1011+
/* Report that we really did it. */
1012+
return true;
9921013
}
9931014

9941015

‎src/backend/postmaster/autovacuum.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2671,19 +2671,27 @@ autovacuum_do_vac_analyze(autovac_table *tab,
26712671
BufferAccessStrategybstrategy)
26722672
{
26732673
VacuumStmtvacstmt;
2674+
RangeVarrangevar;
26742675

2675-
/* Set up command parameters --- usealocalvariable instead of palloc */
2676+
/* Set up command parameters --- use localvariables instead of palloc */
26762677
MemSet(&vacstmt,0,sizeof(vacstmt));
2678+
MemSet(&rangevar,0,sizeof(rangevar));
2679+
2680+
rangevar.schemaname=tab->at_nspname;
2681+
rangevar.relname=tab->at_relname;
2682+
rangevar.location=-1;
26772683

26782684
vacstmt.type=T_VacuumStmt;
2679-
vacstmt.options=0;
2685+
if (!tab->at_wraparound)
2686+
vacstmt.options=VACOPT_NOWAIT;
26802687
if (tab->at_dovacuum)
26812688
vacstmt.options |=VACOPT_VACUUM;
26822689
if (tab->at_doanalyze)
26832690
vacstmt.options |=VACOPT_ANALYZE;
26842691
vacstmt.freeze_min_age=tab->at_freeze_min_age;
26852692
vacstmt.freeze_table_age=tab->at_freeze_table_age;
2686-
vacstmt.relation=NULL;/* not used since we pass a relid */
2693+
/* we pass the OID, but might need this anyway for an error message */
2694+
vacstmt.relation=&rangevar;
26872695
vacstmt.va_cols=NIL;
26882696

26892697
/* Let pgstat know what we're doing */

‎src/include/nodes/parsenodes.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2332,7 +2332,8 @@ typedef enum VacuumOption
23322332
VACOPT_ANALYZE=1 <<1,/* do ANALYZE */
23332333
VACOPT_VERBOSE=1 <<2,/* print progress info */
23342334
VACOPT_FREEZE=1 <<3,/* FREEZE option */
2335-
VACOPT_FULL=1 <<4/* FULL (non-concurrent) vacuum */
2335+
VACOPT_FULL=1 <<4,/* FULL (non-concurrent) vacuum */
2336+
VACOPT_NOWAIT=1 <<5
23362337
}VacuumOption;
23372338

23382339
typedefstructVacuumStmt

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp