Vacuum cleanup.
This commit is contained in:
parent
bd5aaca391
commit
a4d3695f28
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* 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);
|
||||
static void vc_vacuum(NameData *VacRelP, bool analyze, List *va_cols);
|
||||
static VRelList vc_getrels(NameData *VacRelP);
|
||||
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_rpfheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl, VPageList Fvpl, int nindices, Relation *Irel);
|
||||
static void vc_scanheap(VRelStats *vacrelstats, Relation onerel, VPageList vacuum_pages, VPageList fraged_pages);
|
||||
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_vacpage(Page page, VPageDescr vpd);
|
||||
static void vc_vaconeind(VPageList vpl, Relation indrel, int nhtups);
|
||||
static void vc_scanoneind(Relation indrel, int nhtups);
|
||||
static void vc_vaconeind(VPageList vpl, Relation indrel, int num_tuples);
|
||||
static void vc_scanoneind(Relation indrel, int num_tuples);
|
||||
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_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)
|
||||
HeapTuple tuple,
|
||||
typetuple;
|
||||
Relation onerel;
|
||||
VPageListData Vvpl; /* List of pages to vacuum and/or clean
|
||||
VPageListData vacuum_pages; /* List of pages to vacuum and/or clean
|
||||
* indices */
|
||||
VPageListData Fvpl; /* List of pages with space enough for
|
||||
VPageListData fraged_pages; /* List of pages with space enough for
|
||||
* re-using */
|
||||
VPageDescr *vpp;
|
||||
Relation *Irel;
|
||||
@ -517,8 +517,8 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
|
||||
RelationSetLockForWrite(onerel);
|
||||
|
||||
/* scan it */
|
||||
Vvpl.vpl_num_pages = Fvpl.vpl_num_pages = 0;
|
||||
vc_scanheap(vacrelstats, onerel, &Vvpl, &Fvpl);
|
||||
vacuum_pages.vpl_num_pages = fraged_pages.vpl_num_pages = 0;
|
||||
vc_scanheap(vacrelstats, onerel, &vacuum_pages, &fraged_pages);
|
||||
|
||||
/* Now open indices */
|
||||
Irel = (Relation *) NULL;
|
||||
@ -532,10 +532,10 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
|
||||
/* Clean/scan index relation(s) */
|
||||
if (Irel != (Relation *) NULL)
|
||||
{
|
||||
if (Vvpl.vpl_num_pages > 0)
|
||||
if (vacuum_pages.vpl_num_pages > 0)
|
||||
{
|
||||
for (i = 0; i < nindices; i++)
|
||||
vc_vaconeind(&Vvpl, Irel[i], vacrelstats->num_tuples);
|
||||
vc_vaconeind(&vacuum_pages, Irel[i], vacrelstats->num_tuples);
|
||||
}
|
||||
else
|
||||
/* just scan indices to update statistic */
|
||||
@ -545,25 +545,25 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
|
||||
}
|
||||
}
|
||||
|
||||
if (Fvpl.vpl_num_pages > 0) /* Try to shrink heap */
|
||||
vc_rpfheap(vacrelstats, onerel, &Vvpl, &Fvpl, nindices, Irel);
|
||||
if (fraged_pages.vpl_num_pages > 0) /* Try to shrink heap */
|
||||
vc_rpfheap(vacrelstats, onerel, &vacuum_pages, &fraged_pages, nindices, Irel);
|
||||
else
|
||||
{
|
||||
if (Irel != (Relation *) NULL)
|
||||
vc_clsindices(nindices, Irel);
|
||||
if (Vvpl.vpl_num_pages > 0)/* Clean pages from Vvpl list */
|
||||
vc_vacheap(vacrelstats, onerel, &Vvpl);
|
||||
if (vacuum_pages.vpl_num_pages > 0)/* Clean pages from vacuum_pages list */
|
||||
vc_vacheap(vacrelstats, onerel, &vacuum_pages);
|
||||
}
|
||||
|
||||
/* ok - free Vvpl list of reapped pages */
|
||||
if (Vvpl.vpl_num_pages > 0)
|
||||
/* ok - free vacuum_pages list of reapped pages */
|
||||
if (vacuum_pages.vpl_num_pages > 0)
|
||||
{
|
||||
vpp = Vvpl.vpl_pagedesc;
|
||||
for (i = 0; i < Vvpl.vpl_num_pages; i++, vpp++)
|
||||
vpp = vacuum_pages.vpl_pagedesc;
|
||||
for (i = 0; i < vacuum_pages.vpl_num_pages; i++, vpp++)
|
||||
pfree(*vpp);
|
||||
pfree(Vvpl.vpl_pagedesc);
|
||||
if (Fvpl.vpl_num_pages > 0)
|
||||
pfree(Fvpl.vpl_pagedesc);
|
||||
pfree(vacuum_pages.vpl_pagedesc);
|
||||
if (fraged_pages.vpl_num_pages > 0)
|
||||
pfree(fraged_pages.vpl_pagedesc);
|
||||
}
|
||||
|
||||
/* all done with this class */
|
||||
@ -582,15 +582,15 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
|
||||
/*
|
||||
* 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
|
||||
* ~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
|
||||
* on the number of live tuples in a heap.
|
||||
*/
|
||||
static void
|
||||
vc_scanheap(VRelStats *vacrelstats, Relation onerel,
|
||||
VPageList Vvpl, VPageList Fvpl)
|
||||
VPageList vacuum_pages, VPageList fraged_pages)
|
||||
{
|
||||
int nblocks,
|
||||
blkno;
|
||||
@ -616,9 +616,9 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
|
||||
empty_pages,
|
||||
new_pages,
|
||||
changed_pages,
|
||||
nemend;
|
||||
Size frsize,
|
||||
frsusf;
|
||||
empty_end_pages;
|
||||
Size free_size,
|
||||
usable_free_size;
|
||||
Size min_tlen = MAXTUPLEN;
|
||||
Size max_tlen = 0;
|
||||
int32 i;
|
||||
@ -628,8 +628,9 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
|
||||
|
||||
getrusage(RUSAGE_SELF, &ru0);
|
||||
|
||||
tups_vacuumed = num_tuples = nunused = ncrash = empty_pages = new_pages = changed_pages = nemend = 0;
|
||||
frsize = frsusf = 0;
|
||||
tups_vacuumed = num_tuples = nunused = ncrash = empty_pages =
|
||||
new_pages = changed_pages = empty_end_pages = 0;
|
||||
free_size = usable_free_size = 0;
|
||||
|
||||
relname = (RelationGetRelationName(onerel))->data;
|
||||
|
||||
@ -653,10 +654,10 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
|
||||
relname, blkno);
|
||||
PageInit(page, BufferGetPageSize(buf), 0);
|
||||
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++;
|
||||
nemend++;
|
||||
vc_reappage(Vvpl, vpc);
|
||||
empty_end_pages++;
|
||||
vc_reappage(vacuum_pages, vpc);
|
||||
WriteBuffer(buf);
|
||||
continue;
|
||||
}
|
||||
@ -664,10 +665,10 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
|
||||
if (PageIsEmpty(page))
|
||||
{
|
||||
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++;
|
||||
nemend++;
|
||||
vc_reappage(Vvpl, vpc);
|
||||
empty_end_pages++;
|
||||
vc_reappage(vacuum_pages, vpc);
|
||||
ReleaseBuffer(buf);
|
||||
continue;
|
||||
}
|
||||
@ -836,23 +837,23 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
|
||||
{ /* Some tuples are gone */
|
||||
PageRepairFragmentation(tempPage);
|
||||
vpc->vpd_free = ((PageHeader) tempPage)->pd_upper - ((PageHeader) tempPage)->pd_lower;
|
||||
frsize += vpc->vpd_free;
|
||||
vc_reappage(Vvpl, vpc);
|
||||
free_size += vpc->vpd_free;
|
||||
vc_reappage(vacuum_pages, vpc);
|
||||
pfree(tempPage);
|
||||
tempPage = (Page) NULL;
|
||||
}
|
||||
else if (vpc->vpd_offsets_free > 0)
|
||||
{ /* there are only ~LP_USED line pointers */
|
||||
vpc->vpd_free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower;
|
||||
frsize += vpc->vpd_free;
|
||||
vc_reappage(Vvpl, vpc);
|
||||
free_size += vpc->vpd_free;
|
||||
vc_reappage(vacuum_pages, vpc);
|
||||
}
|
||||
if (dobufrel)
|
||||
ReleaseBuffer(buf);
|
||||
if (notup)
|
||||
nemend++;
|
||||
empty_end_pages++;
|
||||
else
|
||||
nemend = 0;
|
||||
empty_end_pages = 0;
|
||||
}
|
||||
|
||||
pfree(vpc);
|
||||
@ -866,28 +867,28 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
|
||||
vacrelstats->min_tlen = min_tlen;
|
||||
vacrelstats->max_tlen = max_tlen;
|
||||
|
||||
Vvpl->vpl_empty_end_pages = nemend;
|
||||
Fvpl->vpl_empty_end_pages = nemend;
|
||||
vacuum_pages->vpl_empty_end_pages = empty_end_pages;
|
||||
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.
|
||||
*/
|
||||
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 */
|
||||
|
||||
nusf = Vvpl->vpl_num_pages - nemend;
|
||||
if ((Vvpl->vpl_pagedesc[nusf - 1])->vpd_blkno == nblocks - nemend - 1)
|
||||
nusf = vacuum_pages->vpl_num_pages - empty_end_pages;
|
||||
if ((vacuum_pages->vpl_pagedesc[nusf - 1])->vpd_blkno == nblocks - empty_end_pages - 1)
|
||||
nusf--;
|
||||
|
||||
for (i = 0; i < nusf; i++)
|
||||
{
|
||||
vp = Vvpl->vpl_pagedesc[i];
|
||||
vp = vacuum_pages->vpl_pagedesc[i];
|
||||
if (vc_enough_space(vp, min_tlen))
|
||||
{
|
||||
vc_vpinsert(Fvpl, vp);
|
||||
frsusf += vp->vpd_free;
|
||||
vc_vpinsert(fraged_pages, vp);
|
||||
usable_free_size += vp->vpd_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -896,9 +897,9 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
|
||||
|
||||
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.",
|
||||
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,
|
||||
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_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.
|
||||
*/
|
||||
static void
|
||||
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;
|
||||
CommandId myCID;
|
||||
Buffer buf,
|
||||
ToBuf;
|
||||
cur_buffer;
|
||||
int nblocks,
|
||||
blkno;
|
||||
Page page,
|
||||
@ -940,21 +941,21 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
|
||||
char *inulls = NULL;
|
||||
InsertIndexResult iresult;
|
||||
VPageListData Nvpl;
|
||||
VPageDescr ToVpd = NULL,
|
||||
Fvplast,
|
||||
Vvplast,
|
||||
VPageDescr cur_page = NULL,
|
||||
last_fraged_page,
|
||||
last_vacuum_page,
|
||||
vpc,
|
||||
*vpp;
|
||||
int ToVpI = 0;
|
||||
int cur_item = 0;
|
||||
IndDesc *Idesc,
|
||||
*idcur;
|
||||
int Fblklast,
|
||||
Vblklast,
|
||||
int last_fraged_block,
|
||||
last_vacuum_block,
|
||||
i;
|
||||
Size tlen;
|
||||
int nmoved,
|
||||
Fnum_pages,
|
||||
Vnum_pages;
|
||||
Size tuple_len;
|
||||
int num_moved,
|
||||
num_fraged_pages,
|
||||
vacuumed_pages;
|
||||
int checked_moved,
|
||||
num_tuples;
|
||||
bool isempty,
|
||||
@ -976,25 +977,25 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
|
||||
}
|
||||
|
||||
Nvpl.vpl_num_pages = 0;
|
||||
Fnum_pages = Fvpl->vpl_num_pages;
|
||||
Fvplast = Fvpl->vpl_pagedesc[Fnum_pages - 1];
|
||||
Fblklast = Fvplast->vpd_blkno;
|
||||
Assert(Vvpl->vpl_num_pages > Vvpl->vpl_empty_end_pages);
|
||||
Vnum_pages = Vvpl->vpl_num_pages - Vvpl->vpl_empty_end_pages;
|
||||
Vvplast = Vvpl->vpl_pagedesc[Vnum_pages - 1];
|
||||
Vblklast = Vvplast->vpd_blkno;
|
||||
Assert(Vblklast >= Fblklast);
|
||||
ToBuf = InvalidBuffer;
|
||||
nmoved = 0;
|
||||
num_fraged_pages = fraged_pages->vpl_num_pages;
|
||||
last_fraged_page = fraged_pages->vpl_pagedesc[num_fraged_pages - 1];
|
||||
last_fraged_block = last_fraged_page->vpd_blkno;
|
||||
Assert(vacuum_pages->vpl_num_pages > vacuum_pages->vpl_empty_end_pages);
|
||||
vacuumed_pages = vacuum_pages->vpl_num_pages - vacuum_pages->vpl_empty_end_pages;
|
||||
last_vacuum_page = vacuum_pages->vpl_pagedesc[vacuumed_pages - 1];
|
||||
last_vacuum_block = last_vacuum_page->vpd_blkno;
|
||||
Assert(last_vacuum_block >= last_fraged_block);
|
||||
cur_buffer = InvalidBuffer;
|
||||
num_moved = 0;
|
||||
|
||||
vpc = (VPageDescr) palloc(sizeof(VPageDescrData) + MaxOffsetNumber * sizeof(OffsetNumber));
|
||||
vpc->vpd_offsets_used = vpc->vpd_offsets_free = 0;
|
||||
|
||||
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 (blkno == Fblklast && Fvplast->vpd_offsets_used > 0)
|
||||
if (blkno == last_fraged_block && last_fraged_page->vpd_offsets_used > 0)
|
||||
break;
|
||||
|
||||
buf = ReadBuffer(onerel, blkno);
|
||||
@ -1005,31 +1006,31 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
|
||||
isempty = PageIsEmpty(page);
|
||||
|
||||
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 */
|
||||
Assert(!isempty);
|
||||
vc_vacpage(page, Vvplast);
|
||||
vc_vacpage(page, last_vacuum_page);
|
||||
dowrite = true;
|
||||
}
|
||||
else
|
||||
Assert(isempty);
|
||||
--Vnum_pages;
|
||||
Assert(Vnum_pages > 0);
|
||||
/* get prev reapped page from Vvpl */
|
||||
Vvplast = Vvpl->vpl_pagedesc[Vnum_pages - 1];
|
||||
Vblklast = Vvplast->vpd_blkno;
|
||||
if (blkno == Fblklast) /* this page in Fvpl too */
|
||||
--vacuumed_pages;
|
||||
Assert(vacuumed_pages > 0);
|
||||
/* get prev reapped page from vacuum_pages */
|
||||
last_vacuum_page = vacuum_pages->vpl_pagedesc[vacuumed_pages - 1];
|
||||
last_vacuum_block = last_vacuum_page->vpd_blkno;
|
||||
if (blkno == last_fraged_block) /* this page in fraged_pages too */
|
||||
{
|
||||
--Fnum_pages;
|
||||
Assert(Fnum_pages > 0);
|
||||
Assert(Fvplast->vpd_offsets_used == 0);
|
||||
/* get prev reapped page from Fvpl */
|
||||
Fvplast = Fvpl->vpl_pagedesc[Fnum_pages - 1];
|
||||
Fblklast = Fvplast->vpd_blkno;
|
||||
--num_fraged_pages;
|
||||
Assert(num_fraged_pages > 0);
|
||||
Assert(last_fraged_page->vpd_offsets_used == 0);
|
||||
/* get prev reapped page from fraged_pages */
|
||||
last_fraged_page = fraged_pages->vpl_pagedesc[num_fraged_pages - 1];
|
||||
last_fraged_block = last_fraged_page->vpd_blkno;
|
||||
}
|
||||
Assert(Fblklast <= Vblklast);
|
||||
Assert(last_fraged_block <= last_vacuum_block);
|
||||
if (isempty)
|
||||
{
|
||||
ReleaseBuffer(buf);
|
||||
@ -1051,54 +1052,54 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
|
||||
continue;
|
||||
|
||||
tuple = (HeapTuple) PageGetItem(page, itemid);
|
||||
tlen = tuple->t_len;
|
||||
tuple_len = tuple->t_len;
|
||||
|
||||
/* try to find new page for this tuple */
|
||||
if (ToBuf == InvalidBuffer ||
|
||||
!vc_enough_space(ToVpd, tlen))
|
||||
if (cur_buffer == InvalidBuffer ||
|
||||
!vc_enough_space(cur_page, tuple_len))
|
||||
{
|
||||
if (ToBuf != InvalidBuffer)
|
||||
if (cur_buffer != InvalidBuffer)
|
||||
{
|
||||
WriteBuffer(ToBuf);
|
||||
ToBuf = InvalidBuffer;
|
||||
WriteBuffer(cur_buffer);
|
||||
cur_buffer = InvalidBuffer;
|
||||
|
||||
/*
|
||||
* 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
|
||||
* "show-stopper" !!! - vadim 02/25/98
|
||||
*/
|
||||
if (ToVpd != Fvplast &&
|
||||
!vc_enough_space(ToVpd, vacrelstats->min_tlen))
|
||||
if (cur_page != last_fraged_page &&
|
||||
!vc_enough_space(cur_page, vacrelstats->min_tlen))
|
||||
{
|
||||
Assert(Fnum_pages > ToVpI + 1);
|
||||
memmove(Fvpl->vpl_pagedesc + ToVpI,
|
||||
Fvpl->vpl_pagedesc + ToVpI + 1,
|
||||
sizeof(VPageDescr *) * (Fnum_pages - ToVpI - 1));
|
||||
Fnum_pages--;
|
||||
Assert(Fvplast == Fvpl->vpl_pagedesc[Fnum_pages - 1]);
|
||||
Assert(num_fraged_pages > cur_item + 1);
|
||||
memmove(fraged_pages->vpl_pagedesc + cur_item,
|
||||
fraged_pages->vpl_pagedesc + cur_item + 1,
|
||||
sizeof(VPageDescr *) * (num_fraged_pages - cur_item - 1));
|
||||
num_fraged_pages--;
|
||||
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;
|
||||
}
|
||||
if (i == Fnum_pages)
|
||||
if (i == num_fraged_pages)
|
||||
break; /* can't move item anywhere */
|
||||
ToVpI = i;
|
||||
ToVpd = Fvpl->vpl_pagedesc[ToVpI];
|
||||
ToBuf = ReadBuffer(onerel, ToVpd->vpd_blkno);
|
||||
ToPage = BufferGetPage(ToBuf);
|
||||
cur_item = i;
|
||||
cur_page = fraged_pages->vpl_pagedesc[cur_item];
|
||||
cur_buffer = ReadBuffer(onerel, cur_page->vpd_blkno);
|
||||
ToPage = BufferGetPage(cur_buffer);
|
||||
/* if this page was not used before - clean it */
|
||||
if (!PageIsEmpty(ToPage) && ToVpd->vpd_offsets_used == 0)
|
||||
vc_vacpage(ToPage, ToVpd);
|
||||
if (!PageIsEmpty(ToPage) && cur_page->vpd_offsets_used == 0)
|
||||
vc_vacpage(ToPage, cur_page);
|
||||
}
|
||||
|
||||
/* copy tuple */
|
||||
newtup = (HeapTuple) palloc(tlen);
|
||||
memmove((char *) newtup, (char *) tuple, tlen);
|
||||
newtup = (HeapTuple) palloc(tuple_len);
|
||||
memmove((char *) newtup, (char *) tuple, tuple_len);
|
||||
|
||||
/* store transaction information */
|
||||
TransactionIdStore(myXID, &(newtup->t_xmin));
|
||||
@ -1109,19 +1110,19 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
|
||||
newtup->t_infomask |= HEAP_XMAX_INVALID;
|
||||
|
||||
/* add tuple to the page */
|
||||
newoff = PageAddItem(ToPage, (Item) newtup, tlen,
|
||||
newoff = PageAddItem(ToPage, (Item) newtup, tuple_len,
|
||||
InvalidOffsetNumber, LP_USED);
|
||||
if (newoff == InvalidOffsetNumber)
|
||||
{
|
||||
elog(ERROR, "\
|
||||
failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
|
||||
tlen, ToVpd->vpd_blkno, ToVpd->vpd_free,
|
||||
ToVpd->vpd_offsets_used, ToVpd->vpd_offsets_free);
|
||||
tuple_len, cur_page->vpd_blkno, cur_page->vpd_free,
|
||||
cur_page->vpd_offsets_used, cur_page->vpd_offsets_free);
|
||||
}
|
||||
newitemid = PageGetItemId(ToPage, newoff);
|
||||
pfree(newtup);
|
||||
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 */
|
||||
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)",
|
||||
/* set xmax to unknown */
|
||||
tuple->t_infomask &= ~(HEAP_XMAX_INVALID | HEAP_XMAX_COMMITTED);
|
||||
|
||||
ToVpd->vpd_offsets_used++;
|
||||
nmoved++;
|
||||
ToVpd->vpd_free = ((PageHeader) ToPage)->pd_upper - ((PageHeader) ToPage)->pd_lower;
|
||||
cur_page->vpd_offsets_used++;
|
||||
num_moved++;
|
||||
cur_page->vpd_free = ((PageHeader) ToPage)->pd_upper - ((PageHeader) ToPage)->pd_lower;
|
||||
vpc->vpd_offsets[vpc->vpd_offsets_free++] = offnum;
|
||||
|
||||
/* 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)",
|
||||
|
||||
blkno++; /* new number of blocks */
|
||||
|
||||
if (ToBuf != InvalidBuffer)
|
||||
if (cur_buffer != InvalidBuffer)
|
||||
{
|
||||
Assert(nmoved > 0);
|
||||
WriteBuffer(ToBuf);
|
||||
Assert(num_moved > 0);
|
||||
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)",
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
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);
|
||||
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)",
|
||||
}
|
||||
WriteBuffer(buf);
|
||||
}
|
||||
Assert(nmoved == checked_moved);
|
||||
Assert(num_moved == checked_moved);
|
||||
|
||||
getrusage(RUSAGE_SELF, &ru1);
|
||||
|
||||
elog(MESSAGE_LEVEL, "Rel %s: Pages: %u --> %u; Tuple(s) moved: %u. \
|
||||
Elapsed %u/%u sec.",
|
||||
(RelationGetRelationName(onerel))->data,
|
||||
nblocks, blkno, nmoved,
|
||||
nblocks, blkno, num_moved,
|
||||
ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
|
||||
ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
|
||||
|
||||
@ -1339,7 +1340,7 @@ Elapsed %u/%u sec.",
|
||||
* if there are "empty" end-blocks.
|
||||
*/
|
||||
static void
|
||||
vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl)
|
||||
vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList vacuum_pages)
|
||||
{
|
||||
Buffer buf;
|
||||
Page page;
|
||||
@ -1347,10 +1348,10 @@ vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl)
|
||||
int nblocks;
|
||||
int i;
|
||||
|
||||
nblocks = Vvpl->vpl_num_pages;
|
||||
nblocks -= Vvpl->vpl_empty_end_pages;/* nothing to do with them */
|
||||
nblocks = vacuum_pages->vpl_num_pages;
|
||||
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)
|
||||
{
|
||||
@ -1362,10 +1363,10 @@ vc_vacheap(VRelStats *vacrelstats, Relation onerel, VPageList Vvpl)
|
||||
}
|
||||
|
||||
/* 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);
|
||||
nblocks = vacrelstats->num_pages - Vvpl->vpl_empty_end_pages;
|
||||
Assert(vacrelstats->num_pages >= vacuum_pages->vpl_empty_end_pages);
|
||||
nblocks = vacrelstats->num_pages - vacuum_pages->vpl_empty_end_pages;
|
||||
elog(MESSAGE_LEVEL, "Rel %s: Pages: %u --> %u.",
|
||||
(RelationGetRelationName(onerel))->data,
|
||||
vacrelstats->num_pages, nblocks);
|
||||
@ -1412,7 +1413,7 @@ vc_vacpage(Page page, VPageDescr vpd)
|
||||
*
|
||||
*/
|
||||
static void
|
||||
vc_scanoneind(Relation indrel, int nhtups)
|
||||
vc_scanoneind(Relation indrel, int num_tuples)
|
||||
{
|
||||
RetrieveIndexResult res;
|
||||
IndexScanDesc iscan;
|
||||
@ -1447,9 +1448,9 @@ vc_scanoneind(Relation indrel, int nhtups)
|
||||
ru1.ru_stime.tv_sec - ru0.ru_stime.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)",
|
||||
indrel->rd_rel->relname.data, nitups, nhtups);
|
||||
indrel->rd_rel->relname.data, nitups, num_tuples);
|
||||
|
||||
} /* vc_scanoneind */
|
||||
|
||||
@ -1466,14 +1467,14 @@ vc_scanoneind(Relation indrel, int nhtups)
|
||||
* pg_class.
|
||||
*/
|
||||
static void
|
||||
vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
|
||||
vc_vaconeind(VPageList vpl, Relation indrel, int num_tuples)
|
||||
{
|
||||
RetrieveIndexResult res;
|
||||
IndexScanDesc iscan;
|
||||
ItemPointer heapptr;
|
||||
int tups_vacuumed;
|
||||
int nitups;
|
||||
int nipages;
|
||||
int num_index_tuples;
|
||||
int num_pages;
|
||||
VPageDescr vp;
|
||||
struct rusage ru0,
|
||||
ru1;
|
||||
@ -1483,7 +1484,7 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
|
||||
/* walk through the entire index */
|
||||
iscan = index_beginscan(indrel, false, 0, (ScanKey) NULL);
|
||||
tups_vacuumed = 0;
|
||||
nitups = 0;
|
||||
num_index_tuples = 0;
|
||||
|
||||
while ((res = index_getnext(iscan, ForwardScanDirection))
|
||||
!= (RetrieveIndexResult) NULL)
|
||||
@ -1509,7 +1510,7 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
|
||||
index_delete(indrel, &res->index_iptr);
|
||||
}
|
||||
else
|
||||
nitups++;
|
||||
num_index_tuples++;
|
||||
|
||||
pfree(res);
|
||||
}
|
||||
@ -1517,19 +1518,19 @@ vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
|
||||
index_endscan(iscan);
|
||||
|
||||
/* now update statistics in pg_class */
|
||||
nipages = RelationGetNumberOfBlocks(indrel);
|
||||
vc_updstats(RelationGetRelid(indrel), nipages, nitups, false, NULL);
|
||||
num_pages = RelationGetNumberOfBlocks(indrel);
|
||||
vc_updstats(RelationGetRelid(indrel), num_pages, num_index_tuples, false, NULL);
|
||||
|
||||
getrusage(RUSAGE_SELF, &ru1);
|
||||
|
||||
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_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)",
|
||||
indrel->rd_rel->relname.data, nitups, nhtups);
|
||||
indrel->rd_rel->relname.data, num_index_tuples, num_tuples);
|
||||
|
||||
} /* vc_vaconeind */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user