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 */
398398onerel = 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
407401if (!pg_ownercheck (GetUserId (),RelationGetRelationName (onerel ),
408402RELNAME ))
@@ -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)
430429reindex = false;
431430vacuum_pages .num_pages = fraged_pages .num_pages = 0 ;
432431scan_heap (vacrelstats ,onerel ,& vacuum_pages ,& fraged_pages );
433- if (IsIgnoringSystemIndexes ()&& IsSystemRelationName (RelationGetRelationName (onerel )))
432+ if (IsIgnoringSystemIndexes ()&&
433+ IsSystemRelationName (RelationGetRelationName (onerel )))
434434reindex = true;
435435
436436/* Now open indices */
@@ -459,30 +459,54 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
459459if (vacuum_pages .num_pages > 0 )
460460{
461461for (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}
464465else
465- /* just scan indices to update statistic */
466466{
467+ /* just scan indices to update statistic */
467468for (i = 0 ;i < nindices ;i ++ )
468469scan_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+ }
474479else
475480{
476481if (Irel != (Relation * )NULL )
477482close_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 */
480486vacuum_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}
482502if (reindex )
483503activate_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+ */
486510if (vacuum_pages .num_pages > 0 )
487511{
488512vacpage = vacuum_pages .pagedesc ;
@@ -498,12 +522,14 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
498522
499523/* update statistics in pg_class */
500524update_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 */
509535if (toast_relid != InvalidOid )
@@ -1820,12 +1846,20 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
18201846pfree (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 */
18241861if (blkno < nblocks )
18251862{
1826- i = FlushRelationBuffers (onerel ,blkno );
1827- if (i < 0 )
1828- elog (FATAL ,"VACUUM (repair_frag): FlushRelationBuffers returned %d" ,i );
18291863blkno = smgrtruncate (DEFAULT_SMGR ,onerel ,blkno );
18301864Assert (blkno >=0 );
18311865vacrelstats -> 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)",
18401874pfree (vacpage );
18411875if (vacrelstats -> vtlinks != NULL )
18421876pfree (vacrelstats -> vtlinks );
1843-
18441877}
18451878
18461879/*
@@ -1860,7 +1893,7 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
18601893
18611894nblocks = vacuum_pages -> num_pages ;
18621895nblocks -= vacuum_pages -> empty_end_pages ;/* nothing to do with
1863- * them */
1896+ * them */
18641897
18651898for (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 */
18771924if (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 ;
18811926elog (MESSAGE_LEVEL ,"Rel %s: Pages: %u --> %u." ,
18821927RelationGetRelationName (onerel ),
18831928vacrelstats -> 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-
18971929nblocks = smgrtruncate (DEFAULT_SMGR ,onerel ,nblocks );
18981930Assert (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/*