Commit a4d3695f authored by Bruce Momjian's avatar Bruce Momjian

Vacuum cleanup.

parent bd5aaca3
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.72 1998/08/19 19:59:43 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.73 1998/08/19 22:01:18 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -79,12 +79,12 @@ static void vc_shutdown(void); ...@@ -79,12 +79,12 @@ static void vc_shutdown(void);
static void vc_vacuum(NameData *VacRelP, bool analyze, List *va_cols); static void vc_vacuum(NameData *VacRelP, bool analyze, List *va_cols);
static VRelList vc_getrels(NameData *VacRelP); static VRelList vc_getrels(NameData *VacRelP);
static void vc_vacone(Oid relid, bool analyze, List *va_cols); static void vc_vacone(Oid relid, bool analyze, List *va_cols);
static void vc_scanheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl, VPageList Fvpl); static void vc_scanheap(VRelStats *vacrelstats, Relation onerel, VPageList vacuum_pages, VPageList fraged_pages);
static void vc_rpfheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl, VPageList Fvpl, int nindices, Relation *Irel); static void vc_rpfheap(VRelStats *vacrelstats, Relation onerel, VPageList vacuum_pages, VPageList fraged_pages, int nindices, Relation *Irel);
static void vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList vpl); static void vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList vpl);
static void vc_vacpage(Page page, VPageDescr vpd); static void vc_vacpage(Page page, VPageDescr vpd);
static void vc_vaconeind(VPageList vpl, Relation indrel, int nhtups); static void vc_vaconeind(VPageList vpl, Relation indrel, int num_tuples);
static void vc_scanoneind(Relation indrel, int nhtups); static void vc_scanoneind(Relation indrel, int num_tuples);
static void vc_attrstats(Relation onerel, VRelStats *vacrelstats, HeapTuple tuple); static void vc_attrstats(Relation onerel, VRelStats *vacrelstats, HeapTuple tuple);
static void vc_bucketcpy(AttributeTupleForm attr, Datum value, Datum *bucket, int16 *bucket_len); static void vc_bucketcpy(AttributeTupleForm attr, Datum value, Datum *bucket, int16 *bucket_len);
static void vc_updstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *vacrelstats); static void vc_updstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *vacrelstats);
...@@ -373,9 +373,9 @@ vc_vacone(Oid relid, bool analyze, List *va_cols) ...@@ -373,9 +373,9 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
HeapTuple tuple, HeapTuple tuple,
typetuple; typetuple;
Relation onerel; Relation onerel;
VPageListData Vvpl; /* List of pages to vacuum and/or clean VPageListData vacuum_pages; /* List of pages to vacuum and/or clean
* indices */ * indices */
VPageListData Fvpl; /* List of pages with space enough for VPageListData fraged_pages; /* List of pages with space enough for
* re-using */ * re-using */
VPageDescr *vpp; VPageDescr *vpp;
Relation *Irel; Relation *Irel;
...@@ -517,8 +517,8 @@ vc_vacone(Oid relid, bool analyze, List *va_cols) ...@@ -517,8 +517,8 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
RelationSetLockForWrite(onerel); RelationSetLockForWrite(onerel);
/* scan it */ /* scan it */
Vvpl.vpl_num_pages = Fvpl.vpl_num_pages = 0; vacuum_pages.vpl_num_pages = fraged_pages.vpl_num_pages = 0;
vc_scanheap(vacrelstats, onerel, &Vvpl, &Fvpl); vc_scanheap(vacrelstats, onerel, &vacuum_pages, &fraged_pages);
/* Now open indices */ /* Now open indices */
Irel = (Relation *) NULL; Irel = (Relation *) NULL;
...@@ -532,10 +532,10 @@ vc_vacone(Oid relid, bool analyze, List *va_cols) ...@@ -532,10 +532,10 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
/* Clean/scan index relation(s) */ /* Clean/scan index relation(s) */
if (Irel != (Relation *) NULL) if (Irel != (Relation *) NULL)
{ {
if (Vvpl.vpl_num_pages > 0) if (vacuum_pages.vpl_num_pages > 0)
{ {
for (i = 0; i < nindices; i++) for (i = 0; i < nindices; i++)
vc_vaconeind(&Vvpl, Irel[i], vacrelstats->num_tuples); vc_vaconeind(&vacuum_pages, Irel[i], vacrelstats->num_tuples);
} }
else else
/* just scan indices to update statistic */ /* just scan indices to update statistic */
...@@ -545,25 +545,25 @@ vc_vacone(Oid relid, bool analyze, List *va_cols) ...@@ -545,25 +545,25 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
} }
} }
if (Fvpl.vpl_num_pages > 0) /* Try to shrink heap */ if (fraged_pages.vpl_num_pages > 0) /* Try to shrink heap */
vc_rpfheap(vacrelstats, onerel, &Vvpl, &Fvpl, nindices, Irel); vc_rpfheap(vacrelstats, onerel, &vacuum_pages, &fraged_pages, nindices, Irel);
else else
{ {
if (Irel != (Relation *) NULL) if (Irel != (Relation *) NULL)
vc_clsindices(nindices, Irel); vc_clsindices(nindices, Irel);
if (Vvpl.vpl_num_pages > 0)/* Clean pages from Vvpl list */ if (vacuum_pages.vpl_num_pages > 0)/* Clean pages from vacuum_pages list */
vc_vacheap(vacrelstats, onerel, &Vvpl); vc_vacheap(vacrelstats, onerel, &vacuum_pages);
} }
/* ok - free Vvpl list of reapped pages */ /* ok - free vacuum_pages list of reapped pages */
if (Vvpl.vpl_num_pages > 0) if (vacuum_pages.vpl_num_pages > 0)
{ {
vpp = Vvpl.vpl_pagedesc; vpp = vacuum_pages.vpl_pagedesc;
for (i = 0; i < Vvpl.vpl_num_pages; i++, vpp++) for (i = 0; i < vacuum_pages.vpl_num_pages; i++, vpp++)
pfree(*vpp); pfree(*vpp);
pfree(Vvpl.vpl_pagedesc); pfree(vacuum_pages.vpl_pagedesc);
if (Fvpl.vpl_num_pages > 0) if (fraged_pages.vpl_num_pages > 0)
pfree(Fvpl.vpl_pagedesc); pfree(fraged_pages.vpl_pagedesc);
} }
/* all done with this class */ /* all done with this class */
...@@ -582,15 +582,15 @@ vc_vacone(Oid relid, bool analyze, List *va_cols) ...@@ -582,15 +582,15 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
/* /*
* vc_scanheap() -- scan an open heap relation * vc_scanheap() -- scan an open heap relation
* *
* This routine sets commit times, constructs Vvpl list of * This routine sets commit times, constructs vacuum_pages list of
* empty/uninitialized pages and pages with dead tuples and * empty/uninitialized pages and pages with dead tuples and
* ~LP_USED line pointers, constructs Fvpl list of pages * ~LP_USED line pointers, constructs fraged_pages list of pages
* appropriate for purposes of shrinking and maintains statistics * appropriate for purposes of shrinking and maintains statistics
* on the number of live tuples in a heap. * on the number of live tuples in a heap.
*/ */
static void static void
vc_scanheap(VRelStats *vacrelstats, Relation onerel, vc_scanheap(VRelStats *vacrelstats, Relation onerel,
VPageList Vvpl, VPageList Fvpl) VPageList vacuum_pages, VPageList fraged_pages)
{ {
int nblocks, int nblocks,
blkno; blkno;
...@@ -616,9 +616,9 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel, ...@@ -616,9 +616,9 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
empty_pages, empty_pages,
new_pages, new_pages,
changed_pages, changed_pages,
nemend; empty_end_pages;
Size frsize, Size free_size,
frsusf; usable_free_size;
Size min_tlen = MAXTUPLEN; Size min_tlen = MAXTUPLEN;
Size max_tlen = 0; Size max_tlen = 0;
int32 i; int32 i;
...@@ -628,8 +628,9 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel, ...@@ -628,8 +628,9 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
getrusage(RUSAGE_SELF, &ru0); getrusage(RUSAGE_SELF, &ru0);
tups_vacuumed = num_tuples = nunused = ncrash = empty_pages = new_pages = changed_pages = nemend = 0; tups_vacuumed = num_tuples = nunused = ncrash = empty_pages =
frsize = frsusf = 0; new_pages = changed_pages = empty_end_pages = 0;
free_size = usable_free_size = 0;
relname = (RelationGetRelationName(onerel))->data; relname = (RelationGetRelationName(onerel))->data;
...@@ -653,10 +654,10 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel, ...@@ -653,10 +654,10 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
relname, blkno); relname, blkno);
PageInit(page, BufferGetPageSize(buf), 0); PageInit(page, BufferGetPageSize(buf), 0);
vpc->vpd_free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower; vpc->vpd_free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower;
frsize += (vpc->vpd_free - sizeof(ItemIdData)); free_size += (vpc->vpd_free - sizeof(ItemIdData));
new_pages++; new_pages++;
nemend++; empty_end_pages++;
vc_reappage(Vvpl, vpc); vc_reappage(vacuum_pages, vpc);
WriteBuffer(buf); WriteBuffer(buf);
continue; continue;
} }
...@@ -664,10 +665,10 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel, ...@@ -664,10 +665,10 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
if (PageIsEmpty(page)) if (PageIsEmpty(page))
{ {
vpc->vpd_free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower; vpc->vpd_free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower;
frsize += (vpc->vpd_free - sizeof(ItemIdData)); free_size += (vpc->vpd_free - sizeof(ItemIdData));
empty_pages++; empty_pages++;
nemend++; empty_end_pages++;
vc_reappage(Vvpl, vpc); vc_reappage(vacuum_pages, vpc);
ReleaseBuffer(buf); ReleaseBuffer(buf);
continue; continue;
} }
...@@ -836,23 +837,23 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel, ...@@ -836,23 +837,23 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
{ /* Some tuples are gone */ { /* Some tuples are gone */
PageRepairFragmentation(tempPage); PageRepairFragmentation(tempPage);
vpc->vpd_free = ((PageHeader) tempPage)->pd_upper - ((PageHeader) tempPage)->pd_lower; vpc->vpd_free = ((PageHeader) tempPage)->pd_upper - ((PageHeader) tempPage)->pd_lower;
frsize += vpc->vpd_free; free_size += vpc->vpd_free;
vc_reappage(Vvpl, vpc); vc_reappage(vacuum_pages, vpc);
pfree(tempPage); pfree(tempPage);
tempPage = (Page) NULL; tempPage = (Page) NULL;
} }
else if (vpc->vpd_offsets_free > 0) else if (vpc->vpd_offsets_free > 0)
{ /* there are only ~LP_USED line pointers */ { /* there are only ~LP_USED line pointers */
vpc->vpd_free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower; vpc->vpd_free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower;
frsize += vpc->vpd_free; free_size += vpc->vpd_free;
vc_reappage(Vvpl, vpc); vc_reappage(vacuum_pages, vpc);
} }
if (dobufrel) if (dobufrel)
ReleaseBuffer(buf); ReleaseBuffer(buf);
if (notup) if (notup)
nemend++; empty_end_pages++;
else else
nemend = 0; empty_end_pages = 0;
} }
pfree(vpc); pfree(vpc);
...@@ -866,28 +867,28 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel, ...@@ -866,28 +867,28 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
vacrelstats->min_tlen = min_tlen; vacrelstats->min_tlen = min_tlen;
vacrelstats->max_tlen = max_tlen; vacrelstats->max_tlen = max_tlen;
Vvpl->vpl_empty_end_pages = nemend; vacuum_pages->vpl_empty_end_pages = empty_end_pages;
Fvpl->vpl_empty_end_pages = nemend; fraged_pages->vpl_empty_end_pages = empty_end_pages;
/* /*
* Try to make Fvpl keeping in mind that we can't use free space of * Try to make fraged_pages keeping in mind that we can't use free space of
* "empty" end-pages and last page if it reapped. * "empty" end-pages and last page if it reapped.
*/ */
if (do_shrinking && Vvpl->vpl_num_pages - nemend > 0) if (do_shrinking && vacuum_pages->vpl_num_pages - empty_end_pages > 0)
{ {
int nusf; /* blocks usefull for re-using */ int nusf; /* blocks usefull for re-using */
nusf = Vvpl->vpl_num_pages - nemend; nusf = vacuum_pages->vpl_num_pages - empty_end_pages;
if ((Vvpl->vpl_pagedesc[nusf - 1])->vpd_blkno == nblocks - nemend - 1) if ((vacuum_pages->vpl_pagedesc[nusf - 1])->vpd_blkno == nblocks - empty_end_pages - 1)
nusf--; nusf--;
for (i = 0; i < nusf; i++) for (i = 0; i < nusf; i++)
{ {
vp = Vvpl->vpl_pagedesc[i]; vp = vacuum_pages->vpl_pagedesc[i];
if (vc_enough_space(vp, min_tlen)) if (vc_enough_space(vp, min_tlen))
{ {
vc_vpinsert(Fvpl, vp); vc_vpinsert(fraged_pages, vp);
frsusf += vp->vpd_free; usable_free_size += vp->vpd_free;
} }
} }
} }
...@@ -896,9 +897,9 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel, ...@@ -896,9 +897,9 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
elog(MESSAGE_LEVEL, "Pages %u: Changed %u, Reapped %u, Empty %u, New %u; \ elog(MESSAGE_LEVEL, "Pages %u: Changed %u, Reapped %u, Empty %u, New %u; \
Tup %u: Vac %u, Crash %u, UnUsed %u, MinLen %u, MaxLen %u; Re-using: Free/Avail. Space %u/%u; EndEmpty/Avail. Pages %u/%u. Elapsed %u/%u sec.", Tup %u: Vac %u, Crash %u, UnUsed %u, MinLen %u, MaxLen %u; Re-using: Free/Avail. Space %u/%u; EndEmpty/Avail. Pages %u/%u. Elapsed %u/%u sec.",
nblocks, changed_pages, Vvpl->vpl_num_pages, empty_pages, new_pages, nblocks, changed_pages, vacuum_pages->vpl_num_pages, empty_pages, new_pages,
num_tuples, tups_vacuumed, ncrash, nunused, min_tlen, max_tlen, num_tuples, tups_vacuumed, ncrash, nunused, min_tlen, max_tlen,
frsize, frsusf, nemend, Fvpl->vpl_num_pages, free_size, usable_free_size, empty_end_pages, fraged_pages->vpl_num_pages,
ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec, ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec); ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
...@@ -917,12 +918,12 @@ Tup %u: Vac %u, Crash %u, UnUsed %u, MinLen %u, MaxLen %u; Re-using: Free/Avail. ...@@ -917,12 +918,12 @@ Tup %u: Vac %u, Crash %u, UnUsed %u, MinLen %u, MaxLen %u; Re-using: Free/Avail.
*/ */
static void static void
vc_rpfheap(VRelStats *vacrelstats, Relation onerel, vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
VPageList Vvpl, VPageList Fvpl, int nindices, Relation *Irel) VPageList vacuum_pages, VPageList fraged_pages, int nindices, Relation *Irel)
{ {
TransactionId myXID; TransactionId myXID;
CommandId myCID; CommandId myCID;
Buffer buf, Buffer buf,
ToBuf; cur_buffer;
int nblocks, int nblocks,
blkno; blkno;
Page page, Page page,
...@@ -940,21 +941,21 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel, ...@@ -940,21 +941,21 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
char *inulls = NULL; char *inulls = NULL;
InsertIndexResult iresult; InsertIndexResult iresult;
VPageListData Nvpl; VPageListData Nvpl;
VPageDescr ToVpd = NULL, VPageDescr cur_page = NULL,
Fvplast, last_fraged_page,
Vvplast, last_vacuum_page,
vpc, vpc,
*vpp; *vpp;
int ToVpI = 0; int cur_item = 0;
IndDesc *Idesc, IndDesc *Idesc,
*idcur; *idcur;
int Fblklast, int last_fraged_block,
Vblklast, last_vacuum_block,
i; i;
Size tlen; Size tuple_len;
int nmoved, int num_moved,
Fnum_pages, num_fraged_pages,
Vnum_pages; vacuumed_pages;
int checked_moved, int checked_moved,
num_tuples; num_tuples;
bool isempty, bool isempty,
...@@ -976,25 +977,25 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel, ...@@ -976,25 +977,25 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
} }
Nvpl.vpl_num_pages = 0; Nvpl.vpl_num_pages = 0;
Fnum_pages = Fvpl->vpl_num_pages; num_fraged_pages = fraged_pages->vpl_num_pages;
Fvplast = Fvpl->vpl_pagedesc[Fnum_pages - 1]; last_fraged_page = fraged_pages->vpl_pagedesc[num_fraged_pages - 1];
Fblklast = Fvplast->vpd_blkno; last_fraged_block = last_fraged_page->vpd_blkno;
Assert(Vvpl->vpl_num_pages > Vvpl->vpl_empty_end_pages); Assert(vacuum_pages->vpl_num_pages > vacuum_pages->vpl_empty_end_pages);
Vnum_pages = Vvpl->vpl_num_pages - Vvpl->vpl_empty_end_pages; vacuumed_pages = vacuum_pages->vpl_num_pages - vacuum_pages->vpl_empty_end_pages;
Vvplast = Vvpl->vpl_pagedesc[Vnum_pages - 1]; last_vacuum_page = vacuum_pages->vpl_pagedesc[vacuumed_pages - 1];
Vblklast = Vvplast->vpd_blkno; last_vacuum_block = last_vacuum_page->vpd_blkno;
Assert(Vblklast >= Fblklast); Assert(last_vacuum_block >= last_fraged_block);
ToBuf = InvalidBuffer; cur_buffer = InvalidBuffer;
nmoved = 0; num_moved = 0;
vpc = (VPageDescr) palloc(sizeof(VPageDescrData) + MaxOffsetNumber * sizeof(OffsetNumber)); vpc = (VPageDescr) palloc(sizeof(VPageDescrData) + MaxOffsetNumber * sizeof(OffsetNumber));
vpc->vpd_offsets_used = vpc->vpd_offsets_free = 0; vpc->vpd_offsets_used = vpc->vpd_offsets_free = 0;
nblocks = vacrelstats->num_pages; nblocks = vacrelstats->num_pages;
for (blkno = nblocks - Vvpl->vpl_empty_end_pages - 1;; blkno--) for (blkno = nblocks - vacuum_pages->vpl_empty_end_pages - 1;; blkno--)
{ {
/* if it's reapped page and it was used by me - quit */ /* if it's reapped page and it was used by me - quit */
if (blkno == Fblklast && Fvplast->vpd_offsets_used > 0) if (blkno == last_fraged_block && last_fraged_page->vpd_offsets_used > 0)
break; break;
buf = ReadBuffer(onerel, blkno); buf = ReadBuffer(onerel, blkno);
...@@ -1005,31 +1006,31 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel, ...@@ -1005,31 +1006,31 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
isempty = PageIsEmpty(page); isempty = PageIsEmpty(page);
dowrite = false; dowrite = false;
if (blkno == Vblklast) /* it's reapped page */ if (blkno == last_vacuum_block) /* it's reapped page */
{ {
if (Vvplast->vpd_offsets_free > 0) /* there are dead tuples */ if (last_vacuum_page->vpd_offsets_free > 0) /* there are dead tuples */
{ /* on this page - clean */ { /* on this page - clean */
Assert(!isempty); Assert(!isempty);
vc_vacpage(page, Vvplast); vc_vacpage(page, last_vacuum_page);
dowrite = true; dowrite = true;
} }
else else
Assert(isempty); Assert(isempty);
--Vnum_pages; --vacuumed_pages;
Assert(Vnum_pages > 0); Assert(vacuumed_pages > 0);
/* get prev reapped page from Vvpl */ /* get prev reapped page from vacuum_pages */
Vvplast = Vvpl->vpl_pagedesc[Vnum_pages - 1]; last_vacuum_page = vacuum_pages->vpl_pagedesc[vacuumed_pages - 1];
Vblklast = Vvplast->vpd_blkno; last_vacuum_block = last_vacuum_page->vpd_blkno;
if (blkno == Fblklast) /* this page in Fvpl too */ if (blkno == last_fraged_block) /* this page in fraged_pages too */
{ {
--Fnum_pages; --num_fraged_pages;
Assert(Fnum_pages > 0); Assert(num_fraged_pages > 0);
Assert(Fvplast->vpd_offsets_used == 0); Assert(last_fraged_page->vpd_offsets_used == 0);
/* get prev reapped page from Fvpl */ /* get prev reapped page from fraged_pages */
Fvplast = Fvpl->vpl_pagedesc[Fnum_pages - 1]; last_fraged_page = fraged_pages->vpl_pagedesc[num_fraged_pages - 1];
Fblklast = Fvplast->vpd_blkno; last_fraged_block = last_fraged_page->vpd_blkno;
} }
Assert(Fblklast <= Vblklast); Assert(last_fraged_block <= last_vacuum_block);
if (isempty) if (isempty)
{ {
ReleaseBuffer(buf); ReleaseBuffer(buf);
...@@ -1051,54 +1052,54 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel, ...@@ -1051,54 +1052,54 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
continue; continue;
tuple = (HeapTuple) PageGetItem(page, itemid); tuple = (HeapTuple) PageGetItem(page, itemid);
tlen = tuple->t_len; tuple_len = tuple->t_len;
/* try to find new page for this tuple */ /* try to find new page for this tuple */
if (ToBuf == InvalidBuffer || if (cur_buffer == InvalidBuffer ||
!vc_enough_space(ToVpd, tlen)) !vc_enough_space(cur_page, tuple_len))
{ {
if (ToBuf != InvalidBuffer) if (cur_buffer != InvalidBuffer)
{ {
WriteBuffer(ToBuf); WriteBuffer(cur_buffer);
ToBuf = InvalidBuffer; cur_buffer = InvalidBuffer;
/* /*
* If no one tuple can't be added to this page - * If no one tuple can't be added to this page -
* remove page from Fvpl. - vadim 11/27/96 * remove page from fraged_pages. - vadim 11/27/96
* *
* But we can't remove last page - this is our * But we can't remove last page - this is our
* "show-stopper" !!! - vadim 02/25/98 * "show-stopper" !!! - vadim 02/25/98
*/ */
if (ToVpd != Fvplast && if (cur_page != last_fraged_page &&
!vc_enough_space(ToVpd, vacrelstats->min_tlen)) !vc_enough_space(cur_page, vacrelstats->min_tlen))
{ {
Assert(Fnum_pages > ToVpI + 1); Assert(num_fraged_pages > cur_item + 1);
memmove(Fvpl->vpl_pagedesc + ToVpI, memmove(fraged_pages->vpl_pagedesc + cur_item,
Fvpl->vpl_pagedesc + ToVpI + 1, fraged_pages->vpl_pagedesc + cur_item + 1,
sizeof(VPageDescr *) * (Fnum_pages - ToVpI - 1)); sizeof(VPageDescr *) * (num_fraged_pages - cur_item - 1));
Fnum_pages--; num_fraged_pages--;
Assert(Fvplast == Fvpl->vpl_pagedesc[Fnum_pages - 1]); Assert(last_fraged_page == fraged_pages->vpl_pagedesc[num_fraged_pages - 1]);
} }
} }
for (i = 0; i < Fnum_pages; i++) for (i = 0; i < num_fraged_pages; i++)
{ {
if (vc_enough_space(Fvpl->vpl_pagedesc[i], tlen)) if (vc_enough_space(fraged_pages->vpl_pagedesc[i], tuple_len))
break; break;
} }
if (i == Fnum_pages) if (i == num_fraged_pages)
break; /* can't move item anywhere */ break; /* can't move item anywhere */
ToVpI = i; cur_item = i;
ToVpd = Fvpl->vpl_pagedesc[ToVpI]; cur_page = fraged_pages->vpl_pagedesc[cur_item];
ToBuf = ReadBuffer(onerel, ToVpd->vpd_blkno); cur_buffer = ReadBuffer(onerel, cur_page->vpd_blkno);
ToPage = BufferGetPage(ToBuf); ToPage = BufferGetPage(cur_buffer);
/* if this page was not used before - clean it */ /* if this page was not used before - clean it */
if (!PageIsEmpty(ToPage) && ToVpd->vpd_offsets_used == 0) if (!PageIsEmpty(ToPage) && cur_page->vpd_offsets_used == 0)
vc_vacpage(ToPage, ToVpd); vc_vacpage(ToPage, cur_page);
} }
/* copy tuple */ /* copy tuple */
newtup = (HeapTuple) palloc(tlen); newtup = (HeapTuple) palloc(tuple_len);
memmove((char *) newtup, (char *) tuple, tlen); memmove((char *) newtup, (char *) tuple, tuple_len);
/* store transaction information */ /* store transaction information */
TransactionIdStore(myXID, &(newtup->t_xmin)); TransactionIdStore(myXID, &(newtup->t_xmin));
...@@ -1109,19 +1110,19 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel, ...@@ -1109,19 +1110,19 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
newtup->t_infomask |= HEAP_XMAX_INVALID; newtup->t_infomask |= HEAP_XMAX_INVALID;
/* add tuple to the page */ /* add tuple to the page */
newoff = PageAddItem(ToPage, (Item) newtup, tlen, newoff = PageAddItem(ToPage, (Item) newtup, tuple_len,
InvalidOffsetNumber, LP_USED); InvalidOffsetNumber, LP_USED);
if (newoff == InvalidOffsetNumber) if (newoff == InvalidOffsetNumber)
{ {
elog(ERROR, "\ elog(ERROR, "\
failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)", failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
tlen, ToVpd->vpd_blkno, ToVpd->vpd_free, tuple_len, cur_page->vpd_blkno, cur_page->vpd_free,
ToVpd->vpd_offsets_used, ToVpd->vpd_offsets_free); cur_page->vpd_offsets_used, cur_page->vpd_offsets_free);
} }
newitemid = PageGetItemId(ToPage, newoff); newitemid = PageGetItemId(ToPage, newoff);
pfree(newtup); pfree(newtup);
newtup = (HeapTuple) PageGetItem(ToPage, newitemid); newtup = (HeapTuple) PageGetItem(ToPage, newitemid);
ItemPointerSet(&(newtup->t_ctid), ToVpd->vpd_blkno, newoff); ItemPointerSet(&(newtup->t_ctid), cur_page->vpd_blkno, newoff);
/* now logically delete end-tuple */ /* now logically delete end-tuple */
TransactionIdStore(myXID, &(tuple->t_xmax)); TransactionIdStore(myXID, &(tuple->t_xmax));
...@@ -1129,9 +1130,9 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)", ...@@ -1129,9 +1130,9 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
/* set xmax to unknown */ /* set xmax to unknown */
tuple->t_infomask &= ~(HEAP_XMAX_INVALID | HEAP_XMAX_COMMITTED); tuple->t_infomask &= ~(HEAP_XMAX_INVALID | HEAP_XMAX_COMMITTED);
ToVpd->vpd_offsets_used++; cur_page->vpd_offsets_used++;
nmoved++; num_moved++;
ToVpd->vpd_free = ((PageHeader) ToPage)->pd_upper - ((PageHeader) ToPage)->pd_lower; cur_page->vpd_free = ((PageHeader) ToPage)->pd_upper - ((PageHeader) ToPage)->pd_lower;
vpc->vpd_offsets[vpc->vpd_offsets_free++] = offnum; vpc->vpd_offsets[vpc->vpd_offsets_free++] = offnum;
/* insert index' tuples if needed */ /* insert index' tuples if needed */
...@@ -1177,13 +1178,13 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)", ...@@ -1177,13 +1178,13 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
blkno++; /* new number of blocks */ blkno++; /* new number of blocks */
if (ToBuf != InvalidBuffer) if (cur_buffer != InvalidBuffer)
{ {
Assert(nmoved > 0); Assert(num_moved > 0);
WriteBuffer(ToBuf); WriteBuffer(cur_buffer);
} }
if (nmoved > 0) if (num_moved > 0)
{ {
/* /*
...@@ -1198,11 +1199,11 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)", ...@@ -1198,11 +1199,11 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
} }
/* /*
* Clean uncleaned reapped pages from Vvpl list and set xmin committed * Clean uncleaned reapped pages from vacuum_pages list and set xmin committed
* for inserted tuples * for inserted tuples
*/ */
checked_moved = 0; checked_moved = 0;
for (i = 0, vpp = Vvpl->vpl_pagedesc; i < Vnum_pages; i++, vpp++) for (i = 0, vpp = vacuum_pages->vpl_pagedesc; i < vacuumed_pages; i++, vpp++)
{ {
Assert((*vpp)->vpd_blkno < blkno); Assert((*vpp)->vpd_blkno < blkno);
buf = ReadBuffer(onerel, (*vpp)->vpd_blkno); buf = ReadBuffer(onerel, (*vpp)->vpd_blkno);
...@@ -1241,14 +1242,14 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)", ...@@ -1241,14 +1242,14 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
} }
WriteBuffer(buf); WriteBuffer(buf);
} }
Assert(nmoved == checked_moved); Assert(num_moved == checked_moved);
getrusage(RUSAGE_SELF, &ru1); getrusage(RUSAGE_SELF, &ru1);
elog(MESSAGE_LEVEL, "Rel %s: Pages: %u --> %u; Tuple(s) moved: %u. \ elog(MESSAGE_LEVEL, "Rel %s: Pages: %u --> %u; Tuple(s) moved: %u. \
Elapsed %u/%u sec.", Elapsed %u/%u sec.",
(RelationGetRelationName(onerel))->data, (RelationGetRelationName(onerel))->data,
nblocks, blkno, nmoved, nblocks, blkno, num_moved,
ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec, ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec); ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
...@@ -1339,7 +1340,7 @@ Elapsed %u/%u sec.", ...@@ -1339,7 +1340,7 @@ Elapsed %u/%u sec.",
* if there are "empty" end-blocks. * if there are "empty" end-blocks.
*/ */
static void static void
vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl) vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList vacuum_pages)
{ {
Buffer buf; Buffer buf;
Page page; Page page;
...@@ -1347,10 +1348,10 @@ vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl) ...@@ -1347,10 +1348,10 @@ vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl)
int nblocks; int nblocks;
int i; int i;
nblocks = Vvpl->vpl_num_pages; nblocks = vacuum_pages->vpl_num_pages;
nblocks -= Vvpl->vpl_empty_end_pages;/* nothing to do with them */ nblocks -= vacuum_pages->vpl_empty_end_pages;/* nothing to do with them */
for (i = 0, vpp = Vvpl->vpl_pagedesc; i < nblocks; i++, vpp++) for (i = 0, vpp = vacuum_pages->vpl_pagedesc; i < nblocks; i++, vpp++)
{ {
if ((*vpp)->vpd_offsets_free > 0) if ((*vpp)->vpd_offsets_free > 0)
{ {
...@@ -1362,10 +1363,10 @@ vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl) ...@@ -1362,10 +1363,10 @@ vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl)
} }
/* truncate relation if there are some empty end-pages */ /* truncate relation if there are some empty end-pages */
if (Vvpl->vpl_empty_end_pages > 0) if (vacuum_pages->vpl_empty_end_pages > 0)
{ {
Assert(vacrelstats->num_pages >= Vvpl->vpl_empty_end_pages); Assert(vacrelstats->num_pages >= vacuum_pages->vpl_empty_end_pages);
nblocks = vacrelstats->num_pages - Vvpl->vpl_empty_end_pages; nblocks = vacrelstats->num_pages - vacuum_pages->vpl_empty_end_pages;
elog(MESSAGE_LEVEL, "Rel %s: Pages: %u --> %u.", elog(MESSAGE_LEVEL, "Rel %s: Pages: %u --> %u.",
(RelationGetRelationName(onerel))->data, (RelationGetRelationName(onerel))->data,
vacrelstats->num_pages, nblocks); vacrelstats->num_pages, nblocks);
...@@ -1412,7 +1413,7 @@ vc_vacpage(Page page, VPageDescr vpd) ...@@ -1412,7 +1413,7 @@ vc_vacpage(Page page, VPageDescr vpd)
* *
*/ */
static void static void
vc_scanoneind(Relation indrel, int nhtups) vc_scanoneind(Relation indrel, int num_tuples)
{ {
RetrieveIndexResult res; RetrieveIndexResult res;
IndexScanDesc iscan; IndexScanDesc iscan;
...@@ -1447,9 +1448,9 @@ vc_scanoneind(Relation indrel, int nhtups) ...@@ -1447,9 +1448,9 @@ vc_scanoneind(Relation indrel, int nhtups)
ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec, ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec); ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
if (nitups != nhtups) if (nitups != num_tuples)
elog(NOTICE, "Ind %s: NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)", elog(NOTICE, "Ind %s: NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)",
indrel->rd_rel->relname.data, nitups, nhtups); indrel->rd_rel->relname.data, nitups, num_tuples);
} /* vc_scanoneind */ } /* vc_scanoneind */
...@@ -1466,14 +1467,14 @@ vc_scanoneind(Relation indrel, int nhtups) ...@@ -1466,14 +1467,14 @@ vc_scanoneind(Relation indrel, int nhtups)
* pg_class. * pg_class.
*/ */
static void static void
vc_vaconeind(VPageList vpl, Relation indrel, int nhtups) vc_vaconeind(VPageList vpl, Relation indrel, int num_tuples)
{ {
RetrieveIndexResult res; RetrieveIndexResult res;
IndexScanDesc iscan; IndexScanDesc iscan;
ItemPointer heapptr; ItemPointer heapptr;
int tups_vacuumed; int tups_vacuumed;
int nitups; int num_index_tuples;
int nipages; int num_pages;
VPageDescr vp; VPageDescr vp;
struct rusage ru0, struct rusage ru0,
ru1; ru1;
...@@ -1483,7 +1484,7 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups) ...@@ -1483,7 +1484,7 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
/* walk through the entire index */ /* walk through the entire index */
iscan = index_beginscan(indrel, false, 0, (ScanKey) NULL); iscan = index_beginscan(indrel, false, 0, (ScanKey) NULL);
tups_vacuumed = 0; tups_vacuumed = 0;
nitups = 0; num_index_tuples = 0;
while ((res = index_getnext(iscan, ForwardScanDirection)) while ((res = index_getnext(iscan, ForwardScanDirection))
!= (RetrieveIndexResult) NULL) != (RetrieveIndexResult) NULL)
...@@ -1509,7 +1510,7 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups) ...@@ -1509,7 +1510,7 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
index_delete(indrel, &res->index_iptr); index_delete(indrel, &res->index_iptr);
} }
else else
nitups++; num_index_tuples++;
pfree(res); pfree(res);
} }
...@@ -1517,19 +1518,19 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups) ...@@ -1517,19 +1518,19 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
index_endscan(iscan); index_endscan(iscan);
/* now update statistics in pg_class */ /* now update statistics in pg_class */
nipages = RelationGetNumberOfBlocks(indrel); num_pages = RelationGetNumberOfBlocks(indrel);
vc_updstats(RelationGetRelid(indrel), nipages, nitups, false, NULL); vc_updstats(RelationGetRelid(indrel), num_pages, num_index_tuples, false, NULL);
getrusage(RUSAGE_SELF, &ru1); getrusage(RUSAGE_SELF, &ru1);
elog(MESSAGE_LEVEL, "Ind %s: Pages %u; Tuples %u: Deleted %u. Elapsed %u/%u sec.", elog(MESSAGE_LEVEL, "Ind %s: Pages %u; Tuples %u: Deleted %u. Elapsed %u/%u sec.",
indrel->rd_rel->relname.data, nipages, nitups, tups_vacuumed, indrel->rd_rel->relname.data, num_pages, num_index_tuples, tups_vacuumed,
ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec, ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec); ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
if (nitups != nhtups) if (num_index_tuples != num_tuples)
elog(NOTICE, "Ind %s: NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)", elog(NOTICE, "Ind %s: NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)",
indrel->rd_rel->relname.data, nitups, nhtups); indrel->rd_rel->relname.data, num_index_tuples, num_tuples);
} /* vc_vaconeind */ } /* vc_vaconeind */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment