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

Commitede62e5

Browse files
committed
Add VACUUM (DISABLE_PAGE_SKIPPING) for emergencies.
If you really want to vacuum every single page in the relation,regardless of apparent visibility status or anything else, you can usethis option. In previous releases, this behavior could be achievedusing VACUUM (FREEZE), but because we can now recognize all-frozenpages as not needing to be frozen again, that no longer works. Thereshould be no need for routine use of this option, but maybe bugs ordisaster recovery will necessitate its use.Patch by me, reviewed by Andres Freund.
1 parent20eb273 commitede62e5

File tree

7 files changed

+97
-46
lines changed

7 files changed

+97
-46
lines changed

‎doc/src/sgml/ref/vacuum.sgml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ PostgreSQL documentation
2121

2222
<refsynopsisdiv>
2323
<synopsis>
24-
VACUUM [ ( { FULL | FREEZE | VERBOSE | ANALYZE } [, ...] ) ] [ <replaceable class="PARAMETER">table_name</replaceable> [ (<replaceable class="PARAMETER">column_name</replaceable> [, ...] ) ] ]
24+
VACUUM [ ( { FULL | FREEZE | VERBOSE | ANALYZE| DISABLE_PAGE_SKIPPING} [, ...] ) ] [ <replaceable class="PARAMETER">table_name</replaceable> [ (<replaceable class="PARAMETER">column_name</replaceable> [, ...] ) ] ]
2525
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ <replaceable class="PARAMETER">table_name</replaceable> ]
2626
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table_name</replaceable> [ (<replaceable class="PARAMETER">column_name</replaceable> [, ...] ) ] ]
2727
</synopsis>
@@ -129,6 +129,25 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">
129129
</listitem>
130130
</varlistentry>
131131

132+
<varlistentry>
133+
<term><literal>DISABLE_PAGE_SKIPPING</literal></term>
134+
<listitem>
135+
<para>
136+
Normally, <command>VACUUM</> will skip pages based on the <link
137+
linkend="vacuum-for-visibility-map">visibility map</>. Pages where
138+
all tuples are known to be frozen can always be skipped, and those
139+
where all tuples are known to be visible to all transactions may be
140+
skipped except when performing an aggressive vacuum. Furthermore,
141+
except when performing an aggressive vacuum, some pages may be skipped
142+
in order to avoid waiting for other sessions to finish using them.
143+
This option disables all page-skipping behavior, and is intended to
144+
be used only the contents of the visibility map are thought to
145+
be suspect, which should happen only if there is a hardware or software
146+
issue causing database corruption.
147+
</para>
148+
</listitem>
149+
</varlistentry>
150+
132151
<varlistentry>
133152
<term><replaceable class="PARAMETER">table_name</replaceable></term>
134153
<listitem>

‎src/backend/commands/vacuum.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,15 @@ vacuum(int options, RangeVar *relation, Oid relid, VacuumParams *params,
185185
errmsg("%s cannot be executed from VACUUM or ANALYZE",
186186
stmttype)));
187187

188+
/*
189+
* Sanity check DISABLE_PAGE_SKIPPING option.
190+
*/
191+
if ((options&VACOPT_FULL)!=0&&
192+
(options&VACOPT_DISABLE_PAGE_SKIPPING)!=0)
193+
ereport(ERROR,
194+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
195+
errmsg("VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL")));
196+
188197
/*
189198
* Send info about dead objects to the statistics collector, unless we are
190199
* in autovacuum --- autovacuum.c does this for itself.

‎src/backend/commands/vacuumlazy.c

Lines changed: 53 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,9 @@ static BufferAccessStrategy vac_strategy;
137137

138138

139139
/* non-export function prototypes */
140-
staticvoidlazy_scan_heap(Relationonerel,LVRelStats*vacrelstats,
141-
Relation*Irel,intnindexes,boolaggressive);
140+
staticvoidlazy_scan_heap(Relationonerel,intoptions,
141+
LVRelStats*vacrelstats,Relation*Irel,intnindexes,
142+
boolaggressive);
142143
staticvoidlazy_vacuum_heap(Relationonerel,LVRelStats*vacrelstats);
143144
staticboollazy_check_needs_freeze(Bufferbuf,bool*hastup);
144145
staticvoidlazy_vacuum_index(Relationindrel,
@@ -223,15 +224,17 @@ lazy_vacuum_rel(Relation onerel, int options, VacuumParams *params,
223224
&MultiXactCutoff,&mxactFullScanLimit);
224225

225226
/*
226-
* We request an aggressive scan ifeitherthe table's frozen Xid is now
227-
*olderthan or equal to the requested Xid full-table scan limit; or if
228-
*thetable's minimum MultiXactId is older than or equal to the requested
229-
* mxid full-table scan limit.
227+
* We request an aggressive scan if the table's frozen Xid is now older
228+
* than or equal to the requested Xid full-table scan limit; or if the
229+
* table's minimum MultiXactId is older than or equal to the requested
230+
* mxid full-table scan limit; or if DISABLE_PAGE_SKIPPING was specified.
230231
*/
231232
aggressive=TransactionIdPrecedesOrEquals(onerel->rd_rel->relfrozenxid,
232233
xidFullScanLimit);
233234
aggressive |=MultiXactIdPrecedesOrEquals(onerel->rd_rel->relminmxid,
234235
mxactFullScanLimit);
236+
if (options&VACOPT_DISABLE_PAGE_SKIPPING)
237+
aggressive= true;
235238

236239
vacrelstats= (LVRelStats*)palloc0(sizeof(LVRelStats));
237240

@@ -246,7 +249,7 @@ lazy_vacuum_rel(Relation onerel, int options, VacuumParams *params,
246249
vacrelstats->hasindex= (nindexes>0);
247250

248251
/* Do the vacuuming */
249-
lazy_scan_heap(onerel,vacrelstats,Irel,nindexes,aggressive);
252+
lazy_scan_heap(onerel,options,vacrelstats,Irel,nindexes,aggressive);
250253

251254
/* Done with indexes */
252255
vac_close_indexes(nindexes,Irel,NoLock);
@@ -441,7 +444,7 @@ vacuum_log_cleanup_info(Relation rel, LVRelStats *vacrelstats)
441444
*reference them have been killed.
442445
*/
443446
staticvoid
444-
lazy_scan_heap(Relationonerel,LVRelStats*vacrelstats,
447+
lazy_scan_heap(Relationonerel,intoptions,LVRelStats*vacrelstats,
445448
Relation*Irel,intnindexes,boolaggressive)
446449
{
447450
BlockNumbernblocks,
@@ -542,25 +545,28 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
542545
* the last page. This is worth avoiding mainly because such a lock must
543546
* be replayed on any hot standby, where it can be disruptive.
544547
*/
545-
for (next_unskippable_block=0;
546-
next_unskippable_block<nblocks;
547-
next_unskippable_block++)
548+
next_unskippable_block=0;
549+
if ((options&VACOPT_DISABLE_PAGE_SKIPPING)==0)
548550
{
549-
uint8vmstatus;
550-
551-
vmstatus=visibilitymap_get_status(onerel,next_unskippable_block,
552-
&vmbuffer);
553-
if (aggressive)
551+
while (next_unskippable_block<nblocks)
554552
{
555-
if ((vmstatus&VISIBILITYMAP_ALL_FROZEN)==0)
556-
break;
557-
}
558-
else
559-
{
560-
if ((vmstatus&VISIBILITYMAP_ALL_VISIBLE)==0)
561-
break;
553+
uint8vmstatus;
554+
555+
vmstatus=visibilitymap_get_status(onerel,next_unskippable_block,
556+
&vmbuffer);
557+
if (aggressive)
558+
{
559+
if ((vmstatus&VISIBILITYMAP_ALL_FROZEN)==0)
560+
break;
561+
}
562+
else
563+
{
564+
if ((vmstatus&VISIBILITYMAP_ALL_VISIBLE)==0)
565+
break;
566+
}
567+
vacuum_delay_point();
568+
next_unskippable_block++;
562569
}
563-
vacuum_delay_point();
564570
}
565571

566572
if (next_unskippable_block >=SKIP_PAGES_THRESHOLD)
@@ -594,26 +600,29 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
594600
if (blkno==next_unskippable_block)
595601
{
596602
/* Time to advance next_unskippable_block */
597-
for (next_unskippable_block++;
598-
next_unskippable_block<nblocks;
599-
next_unskippable_block++)
603+
next_unskippable_block++;
604+
if ((options&VACOPT_DISABLE_PAGE_SKIPPING)==0)
600605
{
601-
uint8vmskipflags;
602-
603-
vmskipflags=visibilitymap_get_status(onerel,
604-
next_unskippable_block,
605-
&vmbuffer);
606-
if (aggressive)
606+
while (next_unskippable_block<nblocks)
607607
{
608-
if ((vmskipflags&VISIBILITYMAP_ALL_FROZEN)==0)
609-
break;
610-
}
611-
else
612-
{
613-
if ((vmskipflags&VISIBILITYMAP_ALL_VISIBLE)==0)
614-
break;
608+
uint8vmskipflags;
609+
610+
vmskipflags=visibilitymap_get_status(onerel,
611+
next_unskippable_block,
612+
&vmbuffer);
613+
if (aggressive)
614+
{
615+
if ((vmskipflags&VISIBILITYMAP_ALL_FROZEN)==0)
616+
break;
617+
}
618+
else
619+
{
620+
if ((vmskipflags&VISIBILITYMAP_ALL_VISIBLE)==0)
621+
break;
622+
}
623+
vacuum_delay_point();
624+
next_unskippable_block++;
615625
}
616-
vacuum_delay_point();
617626
}
618627

619628
/*
@@ -1054,7 +1063,7 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
10541063
}
10551064
else
10561065
{
1057-
booltuple_totally_frozen;
1066+
booltuple_totally_frozen;
10581067

10591068
num_tuples+=1;
10601069
hastup= true;
@@ -1064,8 +1073,8 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
10641073
* freezing. Note we already have exclusive buffer lock.
10651074
*/
10661075
if (heap_prepare_freeze_tuple(tuple.t_data,FreezeLimit,
1067-
MultiXactCutoff,&frozen[nfrozen],
1068-
&tuple_totally_frozen))
1076+
MultiXactCutoff,&frozen[nfrozen],
1077+
&tuple_totally_frozen))
10691078
frozen[nfrozen++].offset=offnum;
10701079

10711080
if (!tuple_totally_frozen)

‎src/backend/parser/gram.y

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9370,6 +9370,16 @@ vacuum_option_elem:
93709370
|VERBOSE{$$ = VACOPT_VERBOSE; }
93719371
|FREEZE{$$ = VACOPT_FREEZE; }
93729372
|FULL{$$ = VACOPT_FULL; }
9373+
|IDENT
9374+
{
9375+
if (strcmp($1,"disable_page_skipping") ==0)
9376+
$$ = VACOPT_DISABLE_PAGE_SKIPPING;
9377+
else
9378+
ereport(ERROR,
9379+
(errcode(ERRCODE_SYNTAX_ERROR),
9380+
errmsg("unrecognized VACUUM option\"%s\"", $1),
9381+
parser_errposition(@1)));
9382+
}
93739383
;
93749384

93759385
AnalyzeStmt:

‎src/include/nodes/parsenodes.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2822,7 +2822,8 @@ typedef enum VacuumOption
28222822
VACOPT_FREEZE=1 <<3,/* FREEZE option */
28232823
VACOPT_FULL=1 <<4,/* FULL (non-concurrent) vacuum */
28242824
VACOPT_NOWAIT=1 <<5,/* don't wait to get lock (autovacuum only) */
2825-
VACOPT_SKIPTOAST=1 <<6/* don't process the TOAST table, if any */
2825+
VACOPT_SKIPTOAST=1 <<6,/* don't process the TOAST table, if any */
2826+
VACOPT_DISABLE_PAGE_SKIPPING=1 <<7/* don't skip any pages */
28262827
}VacuumOption;
28272828

28282829
typedefstructVacuumStmt

‎src/test/regress/expected/vacuum.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,6 @@ ERROR: ANALYZE cannot be executed from VACUUM or ANALYZE
7979
CONTEXT: SQL function "do_analyze" statement 1
8080
SQL function "wrap_do_analyze" statement 1
8181
VACUUM FULL vactst;
82+
VACUUM (DISABLE_PAGE_SKIPPING) vaccluster;
8283
DROP TABLE vaccluster;
8384
DROP TABLE vactst;

‎src/test/regress/sql/vacuum.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,7 @@ VACUUM FULL pg_database;
6060
VACUUM FULL vaccluster;
6161
VACUUM FULL vactst;
6262

63+
VACUUM (DISABLE_PAGE_SKIPPING) vaccluster;
64+
6365
DROPTABLE vaccluster;
6466
DROPTABLE vactst;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp