8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
14
14
*-------------------------------------------------------------------------
@@ -397,12 +397,6 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
397
397
*/
398
398
onerel = heap_open (relid ,AccessExclusiveLock );
399
399
400
- /*
401
- * Remember the relations TOAST relation for later
402
- *
403
- */
404
- toast_relid = onerel -> rd_rel -> reltoastrelid ;
405
-
406
400
#ifndef NO_SECURITY
407
401
if (!pg_ownercheck (GetUserId (),RelationGetRelationName (onerel ),
408
402
RELNAME ))
@@ -416,6 +410,11 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
416
410
}
417
411
#endif
418
412
413
+ /*
414
+ * Remember the relation'ss TOAST relation for later
415
+ */
416
+ toast_relid = onerel -> rd_rel -> reltoastrelid ;
417
+
419
418
/*
420
419
* Set up statistics-gathering machinery.
421
420
*/
@@ -430,7 +429,8 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
430
429
reindex = false;
431
430
vacuum_pages .num_pages = fraged_pages .num_pages = 0 ;
432
431
scan_heap (vacrelstats ,onerel ,& vacuum_pages ,& fraged_pages );
433
- if (IsIgnoringSystemIndexes ()&& IsSystemRelationName (RelationGetRelationName (onerel )))
432
+ if (IsIgnoringSystemIndexes ()&&
433
+ IsSystemRelationName (RelationGetRelationName (onerel )))
434
434
reindex = true;
435
435
436
436
/* Now open indices */
@@ -459,30 +459,54 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
459
459
if (vacuum_pages .num_pages > 0 )
460
460
{
461
461
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 );
463
464
}
464
465
else
465
- /* just scan indices to update statistic */
466
466
{
467
+ /* just scan indices to update statistic */
467
468
for (i = 0 ;i < nindices ;i ++ )
468
469
scan_index (Irel [i ],vacrelstats -> num_tuples );
469
470
}
470
471
}
471
472
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
+ }
474
479
else
475
480
{
476
481
if (Irel != (Relation * )NULL )
477
482
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 */
480
486
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
+ }
481
501
}
482
502
if (reindex )
483
503
activate_indexes_of_a_table (relid , true);
484
504
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
+ */
486
510
if (vacuum_pages .num_pages > 0 )
487
511
{
488
512
vacpage = vacuum_pages .pagedesc ;
@@ -498,12 +522,14 @@ vacuum_rel(Oid relid, bool analyze, bool is_toastrel)
498
522
499
523
/* update statistics in pg_class */
500
524
update_relstats (vacrelstats -> relid ,vacrelstats -> num_pages ,
501
- vacrelstats -> num_tuples ,vacrelstats -> hasindex ,vacrelstats );
525
+ vacrelstats -> num_tuples ,vacrelstats -> hasindex ,
526
+ vacrelstats );
502
527
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
504
530
* while we still hold the lock on the master table. We don't
505
531
* 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
507
533
* totally unimportant for toast relations
508
534
*/
509
535
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)",
1820
1846
pfree (Nvacpagelist .pagedesc );
1821
1847
}
1822
1848
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 */
1824
1861
if (blkno < nblocks )
1825
1862
{
1826
- i = FlushRelationBuffers (onerel ,blkno );
1827
- if (i < 0 )
1828
- elog (FATAL ,"VACUUM (repair_frag): FlushRelationBuffers returned %d" ,i );
1829
1863
blkno = smgrtruncate (DEFAULT_SMGR ,onerel ,blkno );
1830
1864
Assert (blkno >=0 );
1831
1865
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)",
1840
1874
pfree (vacpage );
1841
1875
if (vacrelstats -> vtlinks != NULL )
1842
1876
pfree (vacrelstats -> vtlinks );
1843
-
1844
1877
}
1845
1878
1846
1879
/*
@@ -1860,7 +1893,7 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
1860
1893
1861
1894
nblocks = vacuum_pages -> num_pages ;
1862
1895
nblocks -= vacuum_pages -> empty_end_pages ;/* nothing to do with
1863
- * them */
1896
+ * them */
1864
1897
1865
1898
for (i = 0 ,vacpage = vacuum_pages -> pagedesc ;i < nblocks ;i ++ ,vacpage ++ )
1866
1899
{
@@ -1873,33 +1906,30 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
1873
1906
}
1874
1907
}
1875
1908
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
+
1876
1923
/* truncate relation if there are some empty end-pages */
1877
1924
if (vacuum_pages -> empty_end_pages > 0 )
1878
1925
{
1879
- Assert (vacrelstats -> num_pages >=vacuum_pages -> empty_end_pages );
1880
- nblocks = vacrelstats -> num_pages - vacuum_pages -> empty_end_pages ;
1881
1926
elog (MESSAGE_LEVEL ,"Rel %s: Pages: %u --> %u." ,
1882
1927
RelationGetRelationName (onerel ),
1883
1928
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
-
1897
1929
nblocks = smgrtruncate (DEFAULT_SMGR ,onerel ,nblocks );
1898
1930
Assert (nblocks >=0 );
1899
- vacrelstats -> num_pages = nblocks ;/* set new number of
1900
- * blocks */
1931
+ vacrelstats -> num_pages = nblocks ;/* set new number of blocks */
1901
1932
}
1902
-
1903
1933
}
1904
1934
1905
1935
/*