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

Commit5aeec4b

Browse files
committed
Patch VACUUM problem with moving chain of update tuples when source
and destination of a tuple lie on the same page.(Previously fixed in REL7_0 branch, now apply to current.)
1 parentcd57d64 commit5aeec4b

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.168 2000/10/16 17:08:05 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.169 2000/10/22 19:49:43 tgl Exp $
1212
*
1313
1414
*-------------------------------------------------------------------------
@@ -669,6 +669,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
669669
tuple.t_data->t_cmin))
670670
{
671671
tuple.t_data->t_infomask |=HEAP_XMIN_INVALID;
672+
pgchanged= true;
672673
tupgone= true;
673674
}
674675
else
@@ -683,6 +684,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
683684
tuple.t_data->t_cmin))
684685
{
685686
tuple.t_data->t_infomask |=HEAP_XMIN_INVALID;
687+
pgchanged= true;
686688
tupgone= true;
687689
}
688690
else
@@ -730,8 +732,10 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
730732
{
731733
if (tuple.t_data->t_infomask&HEAP_MARKED_FOR_UPDATE)
732734
{
733-
pgchanged= true;
734735
tuple.t_data->t_infomask |=HEAP_XMAX_INVALID;
736+
tuple.t_data->t_infomask &=
737+
~(HEAP_XMAX_COMMITTED |HEAP_MARKED_FOR_UPDATE);
738+
pgchanged= true;
735739
}
736740
else
737741
tupgone= true;
@@ -746,6 +750,8 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
746750
if (tuple.t_data->t_infomask&HEAP_MARKED_FOR_UPDATE)
747751
{
748752
tuple.t_data->t_infomask |=HEAP_XMAX_INVALID;
753+
tuple.t_data->t_infomask &=
754+
~(HEAP_XMAX_COMMITTED |HEAP_MARKED_FOR_UPDATE);
749755
pgchanged= true;
750756
}
751757
else
@@ -759,6 +765,8 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
759765
* from crashed process. - vadim 06/02/97
760766
*/
761767
tuple.t_data->t_infomask |=HEAP_XMAX_INVALID;
768+
tuple.t_data->t_infomask &=
769+
~(HEAP_XMAX_COMMITTED |HEAP_MARKED_FOR_UPDATE);
762770
pgchanged= true;
763771
}
764772
else
@@ -818,6 +826,14 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
818826
{
819827
ItemIdlpp;
820828

829+
/*
830+
* Here we are building a temporary copy of the page with
831+
* dead tuples removed. Below we will apply
832+
* PageRepairFragmentation to the copy, so that we can
833+
* determine how much space will be available after
834+
* removal of dead tuples. But note we are NOT changing
835+
* the real page yet...
836+
*/
821837
if (tempPage== (Page)NULL)
822838
{
823839
SizepageSize;
@@ -827,14 +843,12 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
827843
memmove(tempPage,page,pageSize);
828844
}
829845

846+
/* mark it unused on the temp page */
830847
lpp=&(((PageHeader)tempPage)->pd_linp[offnum-1]);
831-
832-
/* mark it unused */
833848
lpp->lp_flags &= ~LP_USED;
834849

835850
vacpage->offsets[vacpage->offsets_free++]=offnum;
836851
tups_vacuumed++;
837-
838852
}
839853
else
840854
{
@@ -1397,20 +1411,45 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
13971411
tuple.t_datamcxt=NULL;
13981412
tuple.t_data= (HeapTupleHeader)PageGetItem(Cpage,Citemid);
13991413
tuple_len=tuple.t_len=ItemIdGetLength(Citemid);
1400-
/* Get page to move in */
1414+
1415+
/*
1416+
* make a copy of the source tuple, and then mark the
1417+
* source tuple MOVED_OFF.
1418+
*/
1419+
heap_copytuple_with_tuple(&tuple,&newtup);
1420+
1421+
RelationInvalidateHeapTuple(onerel,&tuple);
1422+
1423+
TransactionIdStore(myXID, (TransactionId*)&(tuple.t_data->t_cmin));
1424+
tuple.t_data->t_infomask &=
1425+
~(HEAP_XMIN_COMMITTED |HEAP_XMIN_INVALID |HEAP_MOVED_IN);
1426+
tuple.t_data->t_infomask |=HEAP_MOVED_OFF;
1427+
1428+
/* Get page to move to */
14011429
cur_buffer=ReadBuffer(onerel,destvacpage->blkno);
14021430

14031431
/*
14041432
* We should LockBuffer(cur_buffer) but don't, at the
1405-
* moment. If you'll do LockBuffer then UNLOCK it
1406-
* before index_insert: unique btree-s call heap_fetch
1407-
* to get t_infomask of inserted heap tuple !!!
1433+
* moment. This should be safe enough, since we have
1434+
* exclusive lock on the whole relation.
1435+
* If you'll do LockBuffer then UNLOCK it before
1436+
* index_insert: unique btree-s call heap_fetch to get
1437+
* t_infomask of inserted heap tuple !!!
14081438
*/
14091439
ToPage=BufferGetPage(cur_buffer);
14101440

14111441
/*
14121442
* If this page was not used before - clean it.
14131443
*
1444+
* NOTE: a nasty bug used to lurk here. It is possible
1445+
* for the source and destination pages to be the same
1446+
* (since this tuple-chain member can be on a page lower
1447+
* than the one we're currently processing in the outer
1448+
* loop). If that's true, then after vacuum_page() the
1449+
* source tuple will have been moved, and tuple.t_data
1450+
* will be pointing at garbage. Therefore we must do
1451+
* everything that uses tuple.t_data BEFORE this step!!
1452+
*
14141453
* This path is different from the other callers of
14151454
* vacuum_page, because we have already incremented the
14161455
* vacpage's offsets_used field to account for the
@@ -1428,8 +1467,11 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
14281467
vacuum_page(ToPage,destvacpage);
14291468
destvacpage->offsets_used=sv_offsets_used;
14301469
}
1431-
heap_copytuple_with_tuple(&tuple,&newtup);
1432-
RelationInvalidateHeapTuple(onerel,&tuple);
1470+
1471+
/*
1472+
* Update the state of the copied tuple, and store it
1473+
* on the destination page.
1474+
*/
14331475
TransactionIdStore(myXID, (TransactionId*)&(newtup.t_data->t_cmin));
14341476
newtup.t_data->t_infomask &=
14351477
~(HEAP_XMIN_COMMITTED |HEAP_XMIN_INVALID |HEAP_MOVED_OFF);
@@ -1450,20 +1492,15 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
14501492
last_move_dest_block=destvacpage->blkno;
14511493

14521494
/*
1453-
* Set t_ctid pointing to itself for last tuple in
1454-
* chain and to next tuple in chain otherwise.
1495+
* Setnew tuple'st_ctid pointing to itself for last
1496+
*tuple inchain, and to next tuple in chain otherwise.
14551497
*/
14561498
if (!ItemPointerIsValid(&Ctid))
14571499
newtup.t_data->t_ctid=newtup.t_self;
14581500
else
14591501
newtup.t_data->t_ctid=Ctid;
14601502
Ctid=newtup.t_self;
14611503

1462-
TransactionIdStore(myXID, (TransactionId*)&(tuple.t_data->t_cmin));
1463-
tuple.t_data->t_infomask &=
1464-
~(HEAP_XMIN_COMMITTED |HEAP_XMIN_INVALID |HEAP_MOVED_IN);
1465-
tuple.t_data->t_infomask |=HEAP_MOVED_OFF;
1466-
14671504
num_moved++;
14681505

14691506
/*
@@ -1504,10 +1541,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
15041541
}
15051542
}
15061543
WriteBuffer(cur_buffer);
1507-
if (Cbuf==buf)
1508-
ReleaseBuffer(Cbuf);
1509-
else
1510-
WriteBuffer(Cbuf);
1544+
WriteBuffer(Cbuf);
15111545
}
15121546
cur_buffer=InvalidBuffer;
15131547
pfree(vtmove);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp