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

Commit7e14593

Browse files
committed
Fix tuple chain moving bug found by "Hiroshi Inoue" <Inoue@tpf.co.jp>.
1 parentb14c99d commit7e14593

File tree

1 file changed

+105
-17
lines changed

1 file changed

+105
-17
lines changed

‎src/backend/commands/vacuum.c

Lines changed: 105 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.102 1999/05/10 00:44:59 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.103 1999/05/23 09:10:24 vadim Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -87,7 +87,7 @@ static void vc_scanheap(VRelStats *vacrelstats, Relation onerel, VPageList vacuu
8787
staticvoidvc_rpfheap(VRelStats*vacrelstats,Relationonerel,VPageListvacuum_pages,VPageListfraged_pages,intnindices,Relation*Irel);
8888
staticvoidvc_vacheap(VRelStats*vacrelstats,Relationonerel,VPageListvpl);
8989
staticvoidvc_vacpage(Pagepage,VPageDescrvpd);
90-
staticvoidvc_vaconeind(VPageListvpl,Relationindrel,intnum_tuples);
90+
staticvoidvc_vaconeind(VPageListvpl,Relationindrel,intnum_tuples,intkeep_tuples);
9191
staticvoidvc_scanoneind(Relationindrel,intnum_tuples);
9292
staticvoidvc_attrstats(Relationonerel,VRelStats*vacrelstats,HeapTupletuple);
9393
staticvoidvc_bucketcpy(Form_pg_attributeattr,Datumvalue,Datum*bucket,int16*bucket_len);
@@ -541,7 +541,7 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
541541
if (vacuum_pages.vpl_num_pages>0)
542542
{
543543
for (i=0;i<nindices;i++)
544-
vc_vaconeind(&vacuum_pages,Irel[i],vacrelstats->num_tuples);
544+
vc_vaconeind(&vacuum_pages,Irel[i],vacrelstats->num_tuples,0);
545545
}
546546
else
547547
/* just scan indices to update statistic */
@@ -1042,9 +1042,11 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
10421042
num_fraged_pages,
10431043
vacuumed_pages;
10441044
intchecked_moved,
1045-
num_tuples;
1045+
num_tuples,
1046+
keep_tuples=0;
10461047
boolisempty,
1047-
dowrite;
1048+
dowrite,
1049+
chain_tuple_moved;
10481050
structrusageru0,
10491051
ru1;
10501052

@@ -1126,6 +1128,7 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
11261128
else
11271129
Assert(!isempty);
11281130

1131+
chain_tuple_moved= false;/* no one chain-tuple was moved off this page, yet */
11291132
vpc->vpd_blkno=blkno;
11301133
maxoff=PageGetMaxOffsetNumber(page);
11311134
for (offnum=FirstOffsetNumber;
@@ -1145,11 +1148,39 @@ vc_rpfheap(VRelStats *vacrelstats, Relation onerel,
11451148
{
11461149
if ((TransactionId)tuple.t_data->t_cmin!=myXID)
11471150
elog(ERROR,"Invalid XID in t_cmin");
1148-
if (tuple.t_data->t_infomask&HEAP_MOVED_OFF)
1149-
continue;/* already removed by me */
11501151
if (tuple.t_data->t_infomask&HEAP_MOVED_IN)
1151-
break;
1152-
elog(ERROR,"HEAP_MOVED_OFF/HEAP_MOVED_IN was expected");
1152+
elog(ERROR,"HEAP_MOVED_IN was not expected");
1153+
/*
1154+
* If this (chain) tuple is moved by me already then
1155+
* I have to check is it in vpc or not - i.e. is it
1156+
* moved while cleaning this page or some previous one.
1157+
*/
1158+
if (tuple.t_data->t_infomask&HEAP_MOVED_OFF)
1159+
{
1160+
if (keep_tuples==0)
1161+
continue;
1162+
if (chain_tuple_moved)/* some chains was moved while */
1163+
{/* cleaning this page */
1164+
Assert(vpc->vpd_offsets_free>0);
1165+
for (i=0;i<vpc->vpd_offsets_free;i++)
1166+
{
1167+
if (vpc->vpd_offsets[i]==offnum)
1168+
break;
1169+
}
1170+
if (i >=vpc->vpd_offsets_free)/* not found */
1171+
{
1172+
vpc->vpd_offsets[vpc->vpd_offsets_free++]=offnum;
1173+
keep_tuples--;
1174+
}
1175+
}
1176+
else
1177+
{
1178+
vpc->vpd_offsets[vpc->vpd_offsets_free++]=offnum;
1179+
keep_tuples--;
1180+
}
1181+
continue;
1182+
}
1183+
elog(ERROR,"HEAP_MOVED_OFF was expected");
11531184
}
11541185

11551186
/*
@@ -1386,9 +1417,15 @@ moving chain: failed to add item with len = %u to page %u",
13861417
tuple.t_data->t_infomask |=HEAP_MOVED_OFF;
13871418

13881419
num_moved++;
1420+
/*
1421+
* Remember that we moved tuple from the current page
1422+
* (corresponding index tuple will be cleaned).
1423+
*/
13891424
if (Cbuf==buf)
13901425
vpc->vpd_offsets[vpc->vpd_offsets_free++]=
13911426
ItemPointerGetOffsetNumber(&(tuple.t_self));
1427+
else
1428+
keep_tuples++;
13921429

13931430
if (Irel!= (Relation*)NULL)
13941431
{
@@ -1418,6 +1455,7 @@ moving chain: failed to add item with len = %u to page %u",
14181455
}
14191456
cur_buffer=InvalidBuffer;
14201457
pfree(vtmove);
1458+
chain_tuple_moved= true;
14211459
continue;
14221460
}
14231461

@@ -1532,10 +1570,58 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
15321570

15331571
}/* walk along page */
15341572

1573+
if (offnum<maxoff&&keep_tuples>0)
1574+
{
1575+
OffsetNumberoff;
1576+
1577+
for (off=OffsetNumberNext(offnum);
1578+
off <=maxoff;
1579+
off=OffsetNumberNext(off))
1580+
{
1581+
itemid=PageGetItemId(page,off);
1582+
if (!ItemIdIsUsed(itemid))
1583+
continue;
1584+
tuple.t_data= (HeapTupleHeader)PageGetItem(page,itemid);
1585+
if (tuple.t_data->t_infomask&HEAP_XMIN_COMMITTED)
1586+
continue;
1587+
if ((TransactionId)tuple.t_data->t_cmin!=myXID)
1588+
elog(ERROR,"Invalid XID in t_cmin (4)");
1589+
if (tuple.t_data->t_infomask&HEAP_MOVED_IN)
1590+
elog(ERROR,"HEAP_MOVED_IN was not expected (2)");
1591+
if (tuple.t_data->t_infomask&HEAP_MOVED_OFF)
1592+
{
1593+
if (chain_tuple_moved)/* some chains was moved while */
1594+
{/* cleaning this page */
1595+
Assert(vpc->vpd_offsets_free>0);
1596+
for (i=0;i<vpc->vpd_offsets_free;i++)
1597+
{
1598+
if (vpc->vpd_offsets[i]==off)
1599+
break;
1600+
}
1601+
if (i >=vpc->vpd_offsets_free)/* not found */
1602+
{
1603+
vpc->vpd_offsets[vpc->vpd_offsets_free++]=off;
1604+
Assert(keep_tuples>0);
1605+
keep_tuples--;
1606+
}
1607+
}
1608+
else
1609+
{
1610+
vpc->vpd_offsets[vpc->vpd_offsets_free++]=off;
1611+
Assert(keep_tuples>0);
1612+
keep_tuples--;
1613+
}
1614+
}
1615+
}
1616+
}
1617+
15351618
if (vpc->vpd_offsets_free>0)/* some tuples were moved */
15361619
{
1537-
qsort((char*) (vpc->vpd_offsets),vpc->vpd_offsets_free,
1620+
if (chain_tuple_moved)/* else - they are ordered */
1621+
{
1622+
qsort((char*) (vpc->vpd_offsets),vpc->vpd_offsets_free,
15381623
sizeof(OffsetNumber),vc_cmp_offno);
1624+
}
15391625
vc_reappage(&Nvpl,vpc);
15401626
WriteBuffer(buf);
15411627
}
@@ -1559,7 +1645,6 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
15591645

15601646
if (num_moved>0)
15611647
{
1562-
15631648
/*
15641649
* We have to commit our tuple' movings before we'll truncate
15651650
* relation, but we shouldn't lose our locks. And so - quick hack:
@@ -1610,7 +1695,7 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
16101695
elseif (tuple.t_data->t_infomask&HEAP_MOVED_OFF)
16111696
tuple.t_data->t_infomask |=HEAP_XMIN_INVALID;
16121697
else
1613-
elog(ERROR,"HEAP_MOVED_OFF/HEAP_MOVED_IN was expected (2)");
1698+
elog(ERROR,"HEAP_MOVED_OFF/HEAP_MOVED_IN was expected");
16141699
}
16151700
}
16161701
Assert((*vpp)->vpd_offsets_used==num_tuples);
@@ -1647,8 +1732,10 @@ Elapsed %u/%u sec.",
16471732
*vpleft=*vpright;
16481733
*vpright=vpsave;
16491734
}
1735+
Assert(keep_tuples >=0);
16501736
for (i=0;i<nindices;i++)
1651-
vc_vaconeind(&Nvpl,Irel[i],vacrelstats->num_tuples);
1737+
vc_vaconeind(&Nvpl,Irel[i],
1738+
vacrelstats->num_tuples,keep_tuples);
16521739
}
16531740

16541741
/*
@@ -1678,7 +1765,7 @@ Elapsed %u/%u sec.",
16781765
num_tuples++;
16791766
}
16801767
else
1681-
elog(ERROR,"HEAP_MOVED_OFF was expected");
1768+
elog(ERROR,"HEAP_MOVED_OFF was expected (2)");
16821769
}
16831770

16841771
}
@@ -1854,7 +1941,7 @@ vc_scanoneind(Relation indrel, int num_tuples)
18541941
*pg_class.
18551942
*/
18561943
staticvoid
1857-
vc_vaconeind(VPageListvpl,Relationindrel,intnum_tuples)
1944+
vc_vaconeind(VPageListvpl,Relationindrel,intnum_tuples,intkeep_tuples)
18581945
{
18591946
RetrieveIndexResultres;
18601947
IndexScanDesciscan;
@@ -1911,11 +1998,12 @@ vc_vaconeind(VPageList vpl, Relation indrel, int num_tuples)
19111998
getrusage(RUSAGE_SELF,&ru1);
19121999

19132000
elog(MESSAGE_LEVEL,"Index %s: Pages %u; Tuples %u: Deleted %u. Elapsed %u/%u sec.",
1914-
indrel->rd_rel->relname.data,num_pages,num_index_tuples,tups_vacuumed,
2001+
indrel->rd_rel->relname.data,num_pages,
2002+
num_index_tuples-keep_tuples,tups_vacuumed,
19152003
ru1.ru_stime.tv_sec-ru0.ru_stime.tv_sec,
19162004
ru1.ru_utime.tv_sec-ru0.ru_utime.tv_sec);
19172005

1918-
if (num_index_tuples!=num_tuples)
2006+
if (num_index_tuples!=num_tuples+keep_tuples)
19192007
elog(NOTICE,"Index %s: NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)",
19202008
indrel->rd_rel->relname.data,num_index_tuples,num_tuples);
19212009

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp