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

Commitb9b125b

Browse files
committed
Move various prechecks from vacuum() into ExecVacuum()
vacuum() is used for both the VACUUM command and for autovacuum. Therewere many prechecks being done inside vacuum() that were just not relevantto autovacuum. Let's move the bulk of these into ExecVacuum() so thatthey're only executed when running the VACUUM command. This removes asmall amount of overhead when autovacuum vacuums a table.While we are at it, allocate VACUUM's BufferAccessStrategy in ExecVacuum()and pass it into vacuum() instead of expecting vacuum() to make it if it'snot already made by the calling function. To make this work, we need tocreate the vacuum memory context slightly earlier, so we now need to passthat down to vacuum() so that it's available for use in other memoryallocations.Author: Melanie PlagemanReviewed-by: David RowleyDiscussion:https://postgr.es/m/20230405211534.4skgskbilnxqrmxg@awork3.anarazel.de
1 parentacab1b0 commitb9b125b

File tree

3 files changed

+91
-78
lines changed

3 files changed

+91
-78
lines changed

‎src/backend/commands/vacuum.c

Lines changed: 78 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ void
105105
ExecVacuum(ParseState*pstate,VacuumStmt*vacstmt,boolisTopLevel)
106106
{
107107
VacuumParamsparams;
108+
BufferAccessStrategybstrategy=NULL;
108109
boolverbose= false;
109110
boolskip_locked= false;
110111
boolanalyze= false;
@@ -115,6 +116,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
115116
boolprocess_toast= true;
116117
boolskip_database_stats= false;
117118
boolonly_database_stats= false;
119+
MemoryContextvac_context;
118120
ListCell*lc;
119121

120122
/* index_cleanup and truncate values unspecified for now */
@@ -254,6 +256,42 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
254256
}
255257
}
256258

259+
260+
/*
261+
* Sanity check DISABLE_PAGE_SKIPPING option.
262+
*/
263+
if ((params.options&VACOPT_FULL)!=0&&
264+
(params.options&VACOPT_DISABLE_PAGE_SKIPPING)!=0)
265+
ereport(ERROR,
266+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
267+
errmsg("VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL")));
268+
269+
/* sanity check for PROCESS_TOAST */
270+
if ((params.options&VACOPT_FULL)!=0&&
271+
(params.options&VACOPT_PROCESS_TOAST)==0)
272+
ereport(ERROR,
273+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
274+
errmsg("PROCESS_TOAST required with VACUUM FULL")));
275+
276+
/* sanity check for ONLY_DATABASE_STATS */
277+
if (params.options&VACOPT_ONLY_DATABASE_STATS)
278+
{
279+
Assert(params.options&VACOPT_VACUUM);
280+
if (vacstmt->rels!=NIL)
281+
ereport(ERROR,
282+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
283+
errmsg("ONLY_DATABASE_STATS cannot be specified with a list of tables")));
284+
/* don't require people to turn off PROCESS_TOAST/MAIN explicitly */
285+
if (params.options& ~(VACOPT_VACUUM |
286+
VACOPT_VERBOSE |
287+
VACOPT_PROCESS_MAIN |
288+
VACOPT_PROCESS_TOAST |
289+
VACOPT_ONLY_DATABASE_STATS))
290+
ereport(ERROR,
291+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
292+
errmsg("ONLY_DATABASE_STATS cannot be specified with other VACUUM options")));
293+
}
294+
257295
/*
258296
* All freeze ages are zero if the FREEZE option is given; otherwise pass
259297
* them as -1 which means to use the default values.
@@ -279,12 +317,43 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
279317
/* user-invoked vacuum uses VACOPT_VERBOSE instead of log_min_duration */
280318
params.log_min_duration=-1;
281319

320+
/*
321+
* Create special memory context for cross-transaction storage.
322+
*
323+
* Since it is a child of PortalContext, it will go away eventually even
324+
* if we suffer an error; there's no need for special abort cleanup logic.
325+
*/
326+
vac_context=AllocSetContextCreate(PortalContext,
327+
"Vacuum",
328+
ALLOCSET_DEFAULT_SIZES);
329+
330+
/*
331+
* Make a buffer strategy object in the cross-transaction memory context.
332+
* We needn't bother making this for VACUUM (FULL) or VACUUM
333+
* (ONLY_DATABASE_STATS) as they'll not make use of it. VACUUM (FULL,
334+
* ANALYZE) is possible, so we'd better ensure that we make a strategy
335+
* when we see ANALYZE.
336+
*/
337+
if ((params.options& (VACOPT_ONLY_DATABASE_STATS |
338+
VACOPT_FULL))==0||
339+
(params.options&VACOPT_ANALYZE)!=0)
340+
{
341+
342+
MemoryContextold_context=MemoryContextSwitchTo(vac_context);
343+
344+
bstrategy=GetAccessStrategy(BAS_VACUUM);
345+
MemoryContextSwitchTo(old_context);
346+
}
347+
282348
/* Now go through the common routine */
283-
vacuum(vacstmt->rels,&params,NULL,isTopLevel);
349+
vacuum(vacstmt->rels,&params,bstrategy,vac_context,isTopLevel);
350+
351+
/* Finally, clean up the vacuum memory context */
352+
MemoryContextDelete(vac_context);
284353
}
285354

286355
/*
287-
* Internal entry point forVACUUM and ANALYZE commands.
356+
* Internal entry point forautovacuum and the VACUUM / ANALYZE commands.
288357
*
289358
* relations, if not NIL, is a list of VacuumRelation to process; otherwise,
290359
* we process all relevant tables in the database. For each VacuumRelation,
@@ -294,21 +363,23 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
294363
* params contains a set of parameters that can be used to customize the
295364
* behavior.
296365
*
297-
* bstrategy is normally given as NULL, but in autovacuum it can be passed
298-
* in to use the same buffer strategy object across multiple vacuum() calls.
366+
* bstrategy may be passed in as NULL when the caller does not want to
367+
* restrict the number of shared_buffers that VACUUM / ANALYZE can use,
368+
* otherwise, the caller must build a BufferAccessStrategy with the number of
369+
* shared_buffers that VACUUM / ANALYZE should try to limit themselves to
370+
* using.
299371
*
300372
* isTopLevel should be passed down from ProcessUtility.
301373
*
302374
* It is the caller's responsibility that all parameters are allocated in a
303375
* memory context that will not disappear at transaction commit.
304376
*/
305377
void
306-
vacuum(List*relations,VacuumParams*params,
307-
BufferAccessStrategybstrategy,boolisTopLevel)
378+
vacuum(List*relations,VacuumParams*params,BufferAccessStrategybstrategy,
379+
MemoryContextvac_context,boolisTopLevel)
308380
{
309381
staticboolin_vacuum= false;
310382

311-
MemoryContextvac_context;
312383
constchar*stmttype;
313384
volatileboolin_outer_xact,
314385
use_own_xacts;
@@ -344,69 +415,6 @@ vacuum(List *relations, VacuumParams *params,
344415
errmsg("%s cannot be executed from VACUUM or ANALYZE",
345416
stmttype)));
346417

347-
/*
348-
* Sanity check DISABLE_PAGE_SKIPPING option.
349-
*/
350-
if ((params->options&VACOPT_FULL)!=0&&
351-
(params->options&VACOPT_DISABLE_PAGE_SKIPPING)!=0)
352-
ereport(ERROR,
353-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
354-
errmsg("VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL")));
355-
356-
/* sanity check for PROCESS_TOAST */
357-
if ((params->options&VACOPT_FULL)!=0&&
358-
(params->options&VACOPT_PROCESS_TOAST)==0)
359-
ereport(ERROR,
360-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
361-
errmsg("PROCESS_TOAST required with VACUUM FULL")));
362-
363-
/* sanity check for ONLY_DATABASE_STATS */
364-
if (params->options&VACOPT_ONLY_DATABASE_STATS)
365-
{
366-
Assert(params->options&VACOPT_VACUUM);
367-
if (relations!=NIL)
368-
ereport(ERROR,
369-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
370-
errmsg("ONLY_DATABASE_STATS cannot be specified with a list of tables")));
371-
/* don't require people to turn off PROCESS_TOAST/MAIN explicitly */
372-
if (params->options& ~(VACOPT_VACUUM |
373-
VACOPT_VERBOSE |
374-
VACOPT_PROCESS_MAIN |
375-
VACOPT_PROCESS_TOAST |
376-
VACOPT_ONLY_DATABASE_STATS))
377-
ereport(ERROR,
378-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
379-
errmsg("ONLY_DATABASE_STATS cannot be specified with other VACUUM options")));
380-
}
381-
382-
/*
383-
* Create special memory context for cross-transaction storage.
384-
*
385-
* Since it is a child of PortalContext, it will go away eventually even
386-
* if we suffer an error; there's no need for special abort cleanup logic.
387-
*/
388-
vac_context=AllocSetContextCreate(PortalContext,
389-
"Vacuum",
390-
ALLOCSET_DEFAULT_SIZES);
391-
392-
/*
393-
* If caller didn't give us a buffer strategy object, make one in the
394-
* cross-transaction memory context. We needn't bother making this for
395-
* VACUUM (FULL) or VACUUM (ONLY_DATABASE_STATS) as they'll not make use
396-
* of it. VACUUM (FULL, ANALYZE) is possible, so we'd better ensure that
397-
* we make a strategy when we see ANALYZE.
398-
*/
399-
if (bstrategy==NULL&&
400-
((params->options& (VACOPT_ONLY_DATABASE_STATS |
401-
VACOPT_FULL))==0||
402-
(params->options&VACOPT_ANALYZE)!=0))
403-
{
404-
MemoryContextold_context=MemoryContextSwitchTo(vac_context);
405-
406-
bstrategy=GetAccessStrategy(BAS_VACUUM);
407-
MemoryContextSwitchTo(old_context);
408-
}
409-
410418
/*
411419
* Build list of relation(s) to process, putting any new data in
412420
* vac_context for safekeeping.
@@ -578,12 +586,6 @@ vacuum(List *relations, VacuumParams *params,
578586
vac_update_datfrozenxid();
579587
}
580588

581-
/*
582-
* Clean up working storage --- note we must do this after
583-
* StartTransactionCommand, else we might be trying to delete the active
584-
* context!
585-
*/
586-
MemoryContextDelete(vac_context);
587589
}
588590

589591
/*

‎src/backend/postmaster/autovacuum.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3140,13 +3140,17 @@ relation_needs_vacanalyze(Oid relid,
31403140
/*
31413141
* autovacuum_do_vac_analyze
31423142
*Vacuum and/or analyze the specified table
3143+
*
3144+
* We expect the caller to have switched into a memory context that won't
3145+
* disappear at transaction commit.
31433146
*/
31443147
staticvoid
31453148
autovacuum_do_vac_analyze(autovac_table*tab,BufferAccessStrategybstrategy)
31463149
{
31473150
RangeVar*rangevar;
31483151
VacuumRelation*rel;
31493152
List*rel_list;
3153+
MemoryContextvac_context;
31503154

31513155
/* Let pgstat know what we're doing */
31523156
autovac_report_activity(tab);
@@ -3156,7 +3160,13 @@ autovacuum_do_vac_analyze(autovac_table *tab, BufferAccessStrategy bstrategy)
31563160
rel=makeVacuumRelation(rangevar,tab->at_relid,NIL);
31573161
rel_list=list_make1(rel);
31583162

3159-
vacuum(rel_list,&tab->at_params,bstrategy, true);
3163+
vac_context=AllocSetContextCreate(CurrentMemoryContext,
3164+
"Vacuum",
3165+
ALLOCSET_DEFAULT_SIZES);
3166+
3167+
vacuum(rel_list,&tab->at_params,bstrategy,vac_context, true);
3168+
3169+
MemoryContextDelete(vac_context);
31603170
}
31613171

31623172
/*

‎src/include/commands/vacuum.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,8 @@ extern PGDLLIMPORT int VacuumCostBalanceLocal;
310310
/* in commands/vacuum.c */
311311
externvoidExecVacuum(ParseState*pstate,VacuumStmt*vacstmt,boolisTopLevel);
312312
externvoidvacuum(List*relations,VacuumParams*params,
313-
BufferAccessStrategybstrategy,boolisTopLevel);
313+
BufferAccessStrategybstrategy,MemoryContextvac_context,
314+
boolisTopLevel);
314315
externvoidvac_open_indexes(Relationrelation,LOCKMODElockmode,
315316
int*nindexes,Relation**Irel);
316317
externvoidvac_close_indexes(intnindexes,Relation*Irel,LOCKMODElockmode);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp