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

Commite3a25ab

Browse files
committed
Refactor relation opening for VACUUM and ANALYZE
VACUUM and ANALYZE share similar logic when it comes to opening arelation to work on in terms of how the relation is opened, in whichorder locks are tried and how logs should be generated when somethingdoes not work as expected.This commit refactors things so as both use the same code path to handlethe way a relation is opened, so as the integration of new optionsbecomes easier.Author: Michael PaquierReviewed-by: Nathan BossartDiscussion:https://postgr.es/m/20180927075152.GT1659@paquier.xyz
1 parentcf3dfea commite3a25ab

File tree

3 files changed

+117
-109
lines changed

3 files changed

+117
-109
lines changed

‎src/backend/commands/analyze.c

Lines changed: 6 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
120120
intelevel;
121121
AcquireSampleRowsFuncacquirefunc=NULL;
122122
BlockNumberrelpages=0;
123-
boolrel_lock= true;
124123

125124
/* Select logging level */
126125
if (options&VACOPT_VERBOSE)
@@ -142,58 +141,16 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
142141
* concurrent VACUUM, which doesn't matter much at the moment but might
143142
* matter if we ever try to accumulate stats on dead tuples.) If the rel
144143
* has been dropped since we last saw it, we don't need to process it.
144+
*
145+
* Make sure to generate only logs for ANALYZE in this case.
145146
*/
146-
if (!(options&VACOPT_SKIP_LOCKED))
147-
onerel=try_relation_open(relid,ShareUpdateExclusiveLock);
148-
elseif (ConditionalLockRelationOid(relid,ShareUpdateExclusiveLock))
149-
onerel=try_relation_open(relid,NoLock);
150-
else
151-
{
152-
onerel=NULL;
153-
rel_lock= false;
154-
}
147+
onerel=vacuum_open_relation(relid,relation,params,
148+
options& ~(VACOPT_VACUUM),
149+
ShareUpdateExclusiveLock);
155150

156-
/*
157-
* If we failed to open or lock the relation, emit a log message before
158-
* exiting.
159-
*/
151+
/* leave if relation could not be opened or locked */
160152
if (!onerel)
161-
{
162-
/*
163-
* If the RangeVar is not defined, we do not have enough information
164-
* to provide a meaningful log statement. Chances are that
165-
* analyze_rel's caller has intentionally not provided this
166-
* information so that this logging is skipped, anyway.
167-
*/
168-
if (relation==NULL)
169-
return;
170-
171-
/*
172-
* Determine the log level. For autovacuum logs, we emit a LOG if
173-
* log_autovacuum_min_duration is not disabled. For manual ANALYZE,
174-
* we emit a WARNING to match the log statements in the permissions
175-
* checks.
176-
*/
177-
if (!IsAutoVacuumWorkerProcess())
178-
elevel=WARNING;
179-
elseif (params->log_min_duration >=0)
180-
elevel=LOG;
181-
else
182-
return;
183-
184-
if (!rel_lock)
185-
ereport(elevel,
186-
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
187-
errmsg("skipping analyze of \"%s\" --- lock not available",
188-
relation->relname)));
189-
else
190-
ereport(elevel,
191-
(errcode(ERRCODE_UNDEFINED_TABLE),
192-
errmsg("skipping analyze of \"%s\" --- relation no longer exists",
193-
relation->relname)));
194-
195153
return;
196-
}
197154

198155
/*
199156
* Check if relation needs to be skipped based on ownership. This check

‎src/backend/commands/vacuum.c

Lines changed: 109 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,112 @@ vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, int options)
482482
}
483483

484484

485+
/*
486+
* vacuum_open_relation
487+
*
488+
* This routine is used for attempting to open and lock a relation which
489+
* is going to be vacuumed or analyzed. If the relation cannot be opened
490+
* or locked, a log is emitted if possible.
491+
*/
492+
Relation
493+
vacuum_open_relation(Oidrelid,RangeVar*relation,VacuumParams*params,
494+
intoptions,LOCKMODElmode)
495+
{
496+
Relationonerel;
497+
boolrel_lock= true;
498+
intelevel;
499+
500+
Assert(params!=NULL);
501+
Assert((options& (VACOPT_VACUUM |VACOPT_ANALYZE))!=0);
502+
503+
/*
504+
* Open the relation and get the appropriate lock on it.
505+
*
506+
* There's a race condition here: the relation may have gone away since
507+
* the last time we saw it. If so, we don't need to vacuum or analyze it.
508+
*
509+
* If we've been asked not to wait for the relation lock, acquire it first
510+
* in non-blocking mode, before calling try_relation_open().
511+
*/
512+
if (!(options&VACOPT_SKIP_LOCKED))
513+
onerel=try_relation_open(relid,lmode);
514+
elseif (ConditionalLockRelationOid(relid,lmode))
515+
onerel=try_relation_open(relid,NoLock);
516+
else
517+
{
518+
onerel=NULL;
519+
rel_lock= false;
520+
}
521+
522+
/* if relation is opened, leave */
523+
if (onerel)
524+
returnonerel;
525+
526+
/*
527+
* Relation could not be opened, hence generate if possible a log
528+
* informing on the situation.
529+
*
530+
* If the RangeVar is not defined, we do not have enough information to
531+
* provide a meaningful log statement. Chances are that the caller has
532+
* intentionally not provided this information so that this logging is
533+
* skipped, anyway.
534+
*/
535+
if (relation==NULL)
536+
returnNULL;
537+
538+
/*
539+
* Determine the log level.
540+
*
541+
* For autovacuum logs, we emit a LOG if log_autovacuum_min_duration is
542+
* not disabled. For manual VACUUM or ANALYZE, we emit a WARNING to match
543+
* the log statements in the permission checks.
544+
*/
545+
if (!IsAutoVacuumWorkerProcess())
546+
elevel=WARNING;
547+
elseif (params->log_min_duration >=0)
548+
elevel=LOG;
549+
else
550+
returnNULL;
551+
552+
if ((options&VACOPT_VACUUM)!=0)
553+
{
554+
if (!rel_lock)
555+
ereport(elevel,
556+
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
557+
errmsg("skipping vacuum of \"%s\" --- lock not available",
558+
relation->relname)));
559+
else
560+
ereport(elevel,
561+
(errcode(ERRCODE_UNDEFINED_TABLE),
562+
errmsg("skipping vacuum of \"%s\" --- relation no longer exists",
563+
relation->relname)));
564+
565+
/*
566+
* For VACUUM ANALYZE, both logs could show up, but just generate
567+
* information for VACUUM as that would be the first one to be
568+
* processed.
569+
*/
570+
returnNULL;
571+
}
572+
573+
if ((options&VACOPT_ANALYZE)!=0)
574+
{
575+
if (!rel_lock)
576+
ereport(elevel,
577+
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
578+
errmsg("skipping analyze of \"%s\" --- lock not available",
579+
relation->relname)));
580+
else
581+
ereport(elevel,
582+
(errcode(ERRCODE_UNDEFINED_TABLE),
583+
errmsg("skipping analyze of \"%s\" --- relation no longer exists",
584+
relation->relname)));
585+
}
586+
587+
returnNULL;
588+
}
589+
590+
485591
/*
486592
* Given a VacuumRelation, fill in the table OID if it wasn't specified,
487593
* and optionally add VacuumRelations for partitions of the table.
@@ -1400,7 +1506,6 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
14001506
Oidsave_userid;
14011507
intsave_sec_context;
14021508
intsave_nestlevel;
1403-
boolrel_lock= true;
14041509

14051510
Assert(params!=NULL);
14061511

@@ -1455,68 +1560,12 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
14551560
*/
14561561
lmode= (options&VACOPT_FULL) ?AccessExclusiveLock :ShareUpdateExclusiveLock;
14571562

1458-
/*
1459-
* Open the relation and get the appropriate lock on it.
1460-
*
1461-
* There's a race condition here: the rel may have gone away since the
1462-
* last time we saw it. If so, we don't need to vacuum it.
1463-
*
1464-
* If we've been asked not to wait for the relation lock, acquire it first
1465-
* in non-blocking mode, before calling try_relation_open().
1466-
*/
1467-
if (!(options&VACOPT_SKIP_LOCKED))
1468-
onerel=try_relation_open(relid,lmode);
1469-
elseif (ConditionalLockRelationOid(relid,lmode))
1470-
onerel=try_relation_open(relid,NoLock);
1471-
else
1472-
{
1473-
onerel=NULL;
1474-
rel_lock= false;
1475-
}
1563+
/* open the relation and get the appropriate lock on it */
1564+
onerel=vacuum_open_relation(relid,relation,params,options,lmode);
14761565

1477-
/*
1478-
* If we failed to open or lock the relation, emit a log message before
1479-
* exiting.
1480-
*/
1566+
/* leave if relation could not be opened or locked */
14811567
if (!onerel)
14821568
{
1483-
intelevel=0;
1484-
1485-
/*
1486-
* Determine the log level.
1487-
*
1488-
* If the RangeVar is not defined, we do not have enough information
1489-
* to provide a meaningful log statement. Chances are that
1490-
* vacuum_rel's caller has intentionally not provided this information
1491-
* so that this logging is skipped, anyway.
1492-
*
1493-
* Otherwise, for autovacuum logs, we emit a LOG if
1494-
* log_autovacuum_min_duration is not disabled. For manual VACUUM, we
1495-
* emit a WARNING to match the log statements in the permission
1496-
* checks.
1497-
*/
1498-
if (relation!=NULL)
1499-
{
1500-
if (!IsAutoVacuumWorkerProcess())
1501-
elevel=WARNING;
1502-
elseif (params->log_min_duration >=0)
1503-
elevel=LOG;
1504-
}
1505-
1506-
if (elevel!=0)
1507-
{
1508-
if (!rel_lock)
1509-
ereport(elevel,
1510-
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
1511-
errmsg("skipping vacuum of \"%s\" --- lock not available",
1512-
relation->relname)));
1513-
else
1514-
ereport(elevel,
1515-
(errcode(ERRCODE_UNDEFINED_TABLE),
1516-
errmsg("skipping vacuum of \"%s\" --- relation no longer exists",
1517-
relation->relname)));
1518-
}
1519-
15201569
PopActiveSnapshot();
15211570
CommitTransactionCommand();
15221571
return false;

‎src/include/commands/vacuum.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ extern void vac_update_datfrozenxid(void);
188188
externvoidvacuum_delay_point(void);
189189
externboolvacuum_is_relation_owner(Oidrelid,Form_pg_classreltuple,
190190
intoptions);
191+
externRelationvacuum_open_relation(Oidrelid,RangeVar*relation,
192+
VacuumParams*params,intoptions,LOCKMODElmode);
191193

192194
/* in commands/vacuumlazy.c */
193195
externvoidlazy_vacuum_rel(Relationonerel,intoptions,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp