Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb611c38

Browse files
committed
Patch VACUUM problem with moving chain of update tuples when source
and destination of a tuple lie on the same page.
1 parentc3bbbb1 commitb611c38

File tree

1 file changed

+56
-22
lines changed

1 file changed

+56
-22
lines changed

‎src/backend/commands/vacuum.c

Lines changed: 56 additions & 22 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.148.2.1 2000/09/19 21:01:04 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.148.2.2 2000/10/1701:39:56 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -815,6 +815,7 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
815815
tuple.t_data->t_cmin))
816816
{
817817
tuple.t_data->t_infomask |=HEAP_XMIN_INVALID;
818+
pgchanged= true;
818819
tupgone= true;
819820
}
820821
else
@@ -829,6 +830,7 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
829830
tuple.t_data->t_cmin))
830831
{
831832
tuple.t_data->t_infomask |=HEAP_XMIN_INVALID;
833+
pgchanged= true;
832834
tupgone= true;
833835
}
834836
else
@@ -876,8 +878,10 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
876878
{
877879
if (tuple.t_data->t_infomask&HEAP_MARKED_FOR_UPDATE)
878880
{
879-
pgchanged= true;
880881
tuple.t_data->t_infomask |=HEAP_XMAX_INVALID;
882+
tuple.t_data->t_infomask &=
883+
~(HEAP_XMAX_COMMITTED |HEAP_MARKED_FOR_UPDATE);
884+
pgchanged= true;
881885
}
882886
else
883887
tupgone= true;
@@ -892,6 +896,8 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
892896
if (tuple.t_data->t_infomask&HEAP_MARKED_FOR_UPDATE)
893897
{
894898
tuple.t_data->t_infomask |=HEAP_XMAX_INVALID;
899+
tuple.t_data->t_infomask &=
900+
~(HEAP_XMAX_COMMITTED |HEAP_MARKED_FOR_UPDATE);
895901
pgchanged= true;
896902
}
897903
else
@@ -905,6 +911,8 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
905911
* from crashed process. - vadim 06/02/97
906912
*/
907913
tuple.t_data->t_infomask |=HEAP_XMAX_INVALID;
914+
tuple.t_data->t_infomask &=
915+
~(HEAP_XMAX_COMMITTED |HEAP_MARKED_FOR_UPDATE);
908916
pgchanged= true;
909917
}
910918
else
@@ -964,6 +972,14 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
964972
{
965973
ItemIdlpp;
966974

975+
/*
976+
* Here we are building a temporary copy of the page with
977+
* dead tuples removed. Below we will apply
978+
* PageRepairFragmentation to the copy, so that we can
979+
* determine how much space will be available after
980+
* removal of dead tuples. But note we are NOT changing
981+
* the real page yet...
982+
*/
967983
if (tempPage== (Page)NULL)
968984
{
969985
SizepageSize;
@@ -973,14 +989,12 @@ vc_scanheap(VRelStats *vacrelstats, Relation onerel,
973989
memmove(tempPage,page,pageSize);
974990
}
975991

992+
/* mark it unused on the temp page */
976993
lpp=&(((PageHeader)tempPage)->pd_linp[offnum-1]);
977-
978-
/* mark it unused */
979994
lpp->lp_flags &= ~LP_USED;
980995

981996
vpc->vpd_offsets[vpc->vpd_offsets_free++]=offnum;
982997
tups_vacuumed++;
983-
984998
}
985999
else
9861000
{
@@ -1548,20 +1562,45 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
15481562
tuple.t_datamcxt=NULL;
15491563
tuple.t_data= (HeapTupleHeader)PageGetItem(Cpage,Citemid);
15501564
tuple_len=tuple.t_len=ItemIdGetLength(Citemid);
1551-
/* Get page to move in */
1565+
1566+
/*
1567+
* make a copy of the source tuple, and then mark the
1568+
* source tuple MOVED_OFF.
1569+
*/
1570+
heap_copytuple_with_tuple(&tuple,&newtup);
1571+
1572+
RelationInvalidateHeapTuple(onerel,&tuple);
1573+
1574+
TransactionIdStore(myXID, (TransactionId*)&(tuple.t_data->t_cmin));
1575+
tuple.t_data->t_infomask &=
1576+
~(HEAP_XMIN_COMMITTED |HEAP_XMIN_INVALID |HEAP_MOVED_IN);
1577+
tuple.t_data->t_infomask |=HEAP_MOVED_OFF;
1578+
1579+
/* Get page to move to */
15521580
cur_buffer=ReadBuffer(onerel,destvpd->vpd_blkno);
15531581

15541582
/*
15551583
* We should LockBuffer(cur_buffer) but don't, at the
1556-
* moment. If you'll do LockBuffer then UNLOCK it
1557-
* before index_insert: unique btree-s call heap_fetch
1558-
* to get t_infomask of inserted heap tuple !!!
1584+
* moment. This should be safe enough, since we have
1585+
* exclusive lock on the whole relation.
1586+
* If you'll do LockBuffer then UNLOCK it before
1587+
* index_insert: unique btree-s call heap_fetch to get
1588+
* t_infomask of inserted heap tuple !!!
15591589
*/
15601590
ToPage=BufferGetPage(cur_buffer);
15611591

15621592
/*
15631593
* If this page was not used before - clean it.
15641594
*
1595+
* NOTE: a nasty bug used to lurk here. It is possible
1596+
* for the source and destination pages to be the same
1597+
* (since this tuple-chain member can be on a page lower
1598+
* than the one we're currently processing in the outer
1599+
* loop). If that's true, then after vc_vacpage() the
1600+
* source tuple will have been moved, and tuple.t_data
1601+
* will be pointing at garbage. Therefore we must do
1602+
* everything that uses tuple.t_data BEFORE this step!!
1603+
*
15651604
* This path is different from the other callers of
15661605
* vc_vacpage, because we have already incremented the
15671606
* vpd's vpd_offsets_used field to account for the
@@ -1579,8 +1618,11 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
15791618
vc_vacpage(ToPage,destvpd);
15801619
destvpd->vpd_offsets_used=sv_offsets_used;
15811620
}
1582-
heap_copytuple_with_tuple(&tuple,&newtup);
1583-
RelationInvalidateHeapTuple(onerel,&tuple);
1621+
1622+
/*
1623+
* Update the state of the copied tuple, and store it
1624+
* on the destination page.
1625+
*/
15841626
TransactionIdStore(myXID, (TransactionId*)&(newtup.t_data->t_cmin));
15851627
newtup.t_data->t_infomask &=
15861628
~(HEAP_XMIN_COMMITTED |HEAP_XMIN_INVALID |HEAP_MOVED_OFF);
@@ -1601,20 +1643,15 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
16011643
last_move_dest_block=destvpd->vpd_blkno;
16021644

16031645
/*
1604-
* Set t_ctid pointing to itself for last tuple in
1605-
* chain and to next tuple in chain otherwise.
1646+
* Setnew tuple'st_ctid pointing to itself for last
1647+
*tuple inchain, and to next tuple in chain otherwise.
16061648
*/
16071649
if (!ItemPointerIsValid(&Ctid))
16081650
newtup.t_data->t_ctid=newtup.t_self;
16091651
else
16101652
newtup.t_data->t_ctid=Ctid;
16111653
Ctid=newtup.t_self;
16121654

1613-
TransactionIdStore(myXID, (TransactionId*)&(tuple.t_data->t_cmin));
1614-
tuple.t_data->t_infomask &=
1615-
~(HEAP_XMIN_COMMITTED |HEAP_XMIN_INVALID |HEAP_MOVED_IN);
1616-
tuple.t_data->t_infomask |=HEAP_MOVED_OFF;
1617-
16181655
num_moved++;
16191656

16201657
/*
@@ -1648,10 +1685,7 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
16481685
}
16491686
}
16501687
WriteBuffer(cur_buffer);
1651-
if (Cbuf==buf)
1652-
ReleaseBuffer(Cbuf);
1653-
else
1654-
WriteBuffer(Cbuf);
1688+
WriteBuffer(Cbuf);
16551689
}
16561690
cur_buffer=InvalidBuffer;
16571691
pfree(vtmove);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp