Skip to content

Commit 95563e7

Browse files
committed
Make sure that FlushRelationBuffers() is invoked by all paths through
vacuum.c. This is needed to make the world safe for pg_upgrade.
1 parent ba2ea6e commit 95563e7

File tree

1 file changed

+72
-42
lines changed

1 file changed

+72
-42
lines changed

src/backend/commands/vacuum.c

Lines changed: 72 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.165 2000/09/12 04:49:07 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.166 2000/09/19 19:30:03 tgl Exp $
1212
*
1313
1414
*-------------------------------------------------------------------------
@@ -397,12 +397,6 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
397397
*/
398398
onerel = heap_open(relid, AccessExclusiveLock);
399399

400-
/*
401-
* Remember the relations TOAST relation for later
402-
*
403-
*/
404-
toast_relid = onerel->rd_rel->reltoastrelid;
405-
406400
#ifndef NO_SECURITY
407401
if (!pg_ownercheck(GetUserId(), RelationGetRelationName(onerel),
408402
RELNAME))
@@ -416,6 +410,11 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
416410
}
417411
#endif
418412

413+
/*
414+
* Remember the relation'ss TOAST relation for later
415+
*/
416+
toast_relid = onerel->rd_rel->reltoastrelid;
417+
419418
/*
420419
* Set up statistics-gathering machinery.
421420
*/
@@ -430,7 +429,8 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
430429
reindex = false;
431430
vacuum_pages.num_pages = fraged_pages.num_pages = 0;
432431
scan_heap(vacrelstats, onerel, &vacuum_pages, &fraged_pages);
433-
if (IsIgnoringSystemIndexes() && IsSystemRelationName(RelationGetRelationName(onerel)))
432+
if (IsIgnoringSystemIndexes() &&
433+
IsSystemRelationName(RelationGetRelationName(onerel)))
434434
reindex = true;
435435

436436
/* Now open indices */
@@ -459,30 +459,54 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
459459
if (vacuum_pages.num_pages > 0)
460460
{
461461
for (i = 0; i < nindices; i++)
462-
vacuum_index(&vacuum_pages, Irel[i], vacrelstats->num_tuples, 0);
462+
vacuum_index(&vacuum_pages, Irel[i],
463+
vacrelstats->num_tuples, 0);
463464
}
464465
else
465-
/* just scan indices to update statistic */
466466
{
467+
/* just scan indices to update statistic */
467468
for (i = 0; i < nindices; i++)
468469
scan_index(Irel[i], vacrelstats->num_tuples);
469470
}
470471
}
471472

472-
if (fraged_pages.num_pages > 0) /* Try to shrink heap */
473-
repair_frag(vacrelstats, onerel, &vacuum_pages, &fraged_pages, nindices, Irel);
473+
if (fraged_pages.num_pages > 0)
474+
{
475+
/* Try to shrink heap */
476+
repair_frag(vacrelstats, onerel, &vacuum_pages, &fraged_pages,
477+
nindices, Irel);
478+
}
474479
else
475480
{
476481
if (Irel != (Relation *) NULL)
477482
close_indices(nindices, Irel);
478-
if (vacuum_pages.num_pages > 0) /* Clean pages from
479-
* vacuum_pages list */
483+
if (vacuum_pages.num_pages > 0)
484+
{
485+
/* Clean pages from vacuum_pages list */
480486
vacuum_heap(vacrelstats, onerel, &vacuum_pages);
487+
}
488+
else
489+
{
490+
/*
491+
* Flush dirty pages out to disk. We must do this even if we
492+
* didn't do anything else, because we want to ensure that all
493+
* tuples have correct on-row commit status on disk (see
494+
* bufmgr.c's comments for FlushRelationBuffers()).
495+
*/
496+
i = FlushRelationBuffers(onerel, vacrelstats->num_pages);
497+
if (i < 0)
498+
elog(ERROR, "VACUUM (vacuum_rel): FlushRelationBuffers returned %d",
499+
i);
500+
}
481501
}
482502
if (reindex)
483503
activate_indexes_of_a_table(relid, true);
484504

485-
/* ok - free vacuum_pages list of reaped pages */
505+
/*
506+
* ok - free vacuum_pages list of reaped pages
507+
*
508+
* Isn't this a waste of code? Upcoming commit should free memory, no?
509+
*/
486510
if (vacuum_pages.num_pages > 0)
487511
{
488512
vacpage = vacuum_pages.pagedesc;
@@ -498,12 +522,14 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
498522

499523
/* update statistics in pg_class */
500524
update_relstats(vacrelstats->relid, vacrelstats->num_pages,
501-
vacrelstats->num_tuples, vacrelstats->hasindex, vacrelstats);
525+
vacrelstats->num_tuples, vacrelstats->hasindex,
526+
vacrelstats);
502527

503-
/* If the relation has a secondary toast one, vacuum that too
528+
/*
529+
* If the relation has a secondary toast one, vacuum that too
504530
* while we still hold the lock on the master table. We don't
505531
* need to propagate "analyze" to it, because the toaster
506-
* allways uses hardcoded index access and statistics are
532+
* always uses hardcoded index access and statistics are
507533
* totally unimportant for toast relations
508534
*/
509535
if (toast_relid != InvalidOid)
@@ -1820,12 +1846,20 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
18201846
pfree(Nvacpagelist.pagedesc);
18211847
}
18221848

1823-
/* truncate relation, after flushing any dirty pages out to disk */
1849+
/*
1850+
* Flush dirty pages out to disk. We do this unconditionally, even if
1851+
* we don't need to truncate, because we want to ensure that all tuples
1852+
* have correct on-row commit status on disk (see bufmgr.c's comments
1853+
* for FlushRelationBuffers()).
1854+
*/
1855+
i = FlushRelationBuffers(onerel, blkno);
1856+
if (i < 0)
1857+
elog(ERROR, "VACUUM (repair_frag): FlushRelationBuffers returned %d",
1858+
i);
1859+
1860+
/* truncate relation, if needed */
18241861
if (blkno < nblocks)
18251862
{
1826-
i = FlushRelationBuffers(onerel, blkno);
1827-
if (i < 0)
1828-
elog(FATAL, "VACUUM (repair_frag): FlushRelationBuffers returned %d", i);
18291863
blkno = smgrtruncate(DEFAULT_SMGR, onerel, blkno);
18301864
Assert(blkno >= 0);
18311865
vacrelstats->num_pages = blkno; /* set new number of blocks */
@@ -1840,7 +1874,6 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
18401874
pfree(vacpage);
18411875
if (vacrelstats->vtlinks != NULL)
18421876
pfree(vacrelstats->vtlinks);
1843-
18441877
}
18451878

18461879
/*
@@ -1860,7 +1893,7 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
18601893

18611894
nblocks = vacuum_pages->num_pages;
18621895
nblocks -= vacuum_pages->empty_end_pages; /* nothing to do with
1863-
* them */
1896+
* them */
18641897

18651898
for (i = 0, vacpage = vacuum_pages->pagedesc; i < nblocks; i++, vacpage++)
18661899
{
@@ -1873,33 +1906,30 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
18731906
}
18741907
}
18751908

1909+
/*
1910+
* Flush dirty pages out to disk. We do this unconditionally, even if
1911+
* we don't need to truncate, because we want to ensure that all tuples
1912+
* have correct on-row commit status on disk (see bufmgr.c's comments
1913+
* for FlushRelationBuffers()).
1914+
*/
1915+
Assert(vacrelstats->num_pages >= vacuum_pages->empty_end_pages);
1916+
nblocks = vacrelstats->num_pages - vacuum_pages->empty_end_pages;
1917+
1918+
i = FlushRelationBuffers(onerel, nblocks);
1919+
if (i < 0)
1920+
elog(ERROR, "VACUUM (vacuum_heap): FlushRelationBuffers returned %d",
1921+
i);
1922+
18761923
/* truncate relation if there are some empty end-pages */
18771924
if (vacuum_pages->empty_end_pages > 0)
18781925
{
1879-
Assert(vacrelstats->num_pages >= vacuum_pages->empty_end_pages);
1880-
nblocks = vacrelstats->num_pages - vacuum_pages->empty_end_pages;
18811926
elog(MESSAGE_LEVEL, "Rel %s: Pages: %u --> %u.",
18821927
RelationGetRelationName(onerel),
18831928
vacrelstats->num_pages, nblocks);
1884-
1885-
/*
1886-
* We have to flush "empty" end-pages (if changed, but who knows
1887-
* it) before truncation
1888-
*
1889-
* XXX is FlushBufferPool() still needed here?
1890-
*/
1891-
FlushBufferPool();
1892-
1893-
i = FlushRelationBuffers(onerel, nblocks);
1894-
if (i < 0)
1895-
elog(FATAL, "VACUUM (vacuum_heap): FlushRelationBuffers returned %d", i);
1896-
18971929
nblocks = smgrtruncate(DEFAULT_SMGR, onerel, nblocks);
18981930
Assert(nblocks >= 0);
1899-
vacrelstats->num_pages = nblocks; /* set new number of
1900-
* blocks */
1931+
vacrelstats->num_pages = nblocks; /* set new number of blocks */
19011932
}
1902-
19031933
}
19041934

19051935
/*

0 commit comments

Comments
 (0)