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

Commitdd8ad64

Browse files
committed
Fix tuptoaster bugs induced by making bytea toastable. Durn thing was
trying to toast tuples inserted into toast tables! Fix is two-pronged:first, ensure all columns of a toast table are marked attstorage='p',and second, alter the target chunk size so that it's less than thethreshold for trying to toast a tuple. (Code tried to do that but theexpression was wrong.) A few cosmetic cleanups in tuptoaster too.NOTE: initdb forced due to change in toaster chunk-size.
1 parented9ca68 commitdd8ad64

File tree

5 files changed

+107
-69
lines changed

5 files changed

+107
-69
lines changed

‎src/backend/access/heap/heapam.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.83 2000/08/03 19:18:54 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.84 2000/08/04 04:16:06 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -1362,7 +1362,7 @@ heap_insert(Relation relation, HeapTuple tup)
13621362
* ----------
13631363
*/
13641364
if (HeapTupleHasExtended(tup)||
1365-
(MAXALIGN(tup->t_len)>(MaxTupleSize /4)))
1365+
(MAXALIGN(tup->t_len)>TOAST_TUPLE_THRESHOLD))
13661366
heap_tuple_toast_attrs(relation,tup,NULL);
13671367
#endif
13681368

@@ -1621,13 +1621,15 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
16211621
#ifdefTUPLE_TOASTER_ACTIVE
16221622
/* ----------
16231623
* If this relation is enabled for toasting, let the toaster
1624-
* delete not any longer needed entries and create new ones to
1625-
* make the new tuple fit again.
1624+
* delete any no-longer-needed entries and create new ones to
1625+
* make the new tuple fit again. Also, if there are already-
1626+
* toasted values from some other relation, the toaster must
1627+
* fix them.
16261628
* ----------
16271629
*/
16281630
if (HeapTupleHasExtended(&oldtup)||
1629-
HeapTupleHasExtended(newtup)||
1630-
(MAXALIGN(newtup->t_len)>(MaxTupleSize /4)))
1631+
HeapTupleHasExtended(newtup)||
1632+
(MAXALIGN(newtup->t_len)>TOAST_TUPLE_THRESHOLD))
16311633
heap_tuple_toast_attrs(relation,newtup,&oldtup);
16321634
#endif
16331635

‎src/backend/access/heap/tuptoaster.c

Lines changed: 46 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.11 2000/08/0316:33:40 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.12 2000/08/04 04:16:07 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -22,11 +22,10 @@
2222
*-------------------------------------------------------------------------
2323
*/
2424

25-
#include<stdio.h>
26-
#include<stdlib.h>
25+
#include"postgres.h"
26+
2727
#include<unistd.h>
2828
#include<fcntl.h>
29-
#include"postgres.h"
3029

3130
#include"access/heapam.h"
3231
#include"access/genam.h"
@@ -39,6 +38,7 @@
3938

4039

4140
#ifdefTUPLE_TOASTER_ACTIVE
41+
4242
#undef TOAST_DEBUG
4343

4444
staticvoidtoast_delete(Relationrel,HeapTupleoldtup);
@@ -47,7 +47,6 @@ static voidtoast_insert_or_update(Relation rel, HeapTuple newtup,
4747
HeapTupleoldtup);
4848
staticDatumtoast_compress_datum(Datumvalue);
4949
staticDatumtoast_save_datum(Relationrel,Oidmainoid,int16attno,Datumvalue);
50-
5150
staticvarattrib*toast_fetch_datum(varattrib*attr);
5251

5352

@@ -209,7 +208,7 @@ toast_delete(Relation rel, HeapTuple oldtup)
209208
/* ----------
210209
* toast_insert_or_update -
211210
*
212-
*Delete no moreused toast-entries and create new ones to
211+
*Delete no-longer-used toast-entries and create new ones to
213212
*make the new tuple fit on INSERT or UPDATE
214213
* ----------
215214
*/
@@ -375,7 +374,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
375374
}
376375

377376
/* ----------
378-
* Compress and/or save external until data fits
377+
* Compress and/or save external until data fits into target length
379378
*
380379
*1: Inline compress attributes with attstorage 'x'
381380
*2: Store attributes with attstorage 'x' or 'e' external
@@ -386,7 +385,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
386385
maxDataLen= offsetof(HeapTupleHeaderData,t_bits);
387386
if (has_nulls)
388387
maxDataLen+=BITMAPLEN(numAttrs);
389-
maxDataLen=(MaxTupleSize /4)-MAXALIGN(maxDataLen);
388+
maxDataLen=TOAST_TUPLE_TARGET-MAXALIGN(maxDataLen);
390389

391390
/* ----------
392391
* Look for attributes with attstorage 'x' to compress
@@ -560,7 +559,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
560559

561560
/* ----------
562561
* Search for the biggest yet inlined attribute with
563-
* attstorage = 'x' or 'e'
562+
* attstorage = 'm'
564563
* ----------
565564
*/
566565
for (i=0;i<numAttrs;i++)
@@ -684,15 +683,13 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
684683
if (toast_delold[i])
685684
toast_delete_datum(rel,
686685
heap_getattr(oldtup,i+1,tupleDesc,&old_isnull));
687-
688-
return;
689686
}
690687

691688

692689
/* ----------
693690
* toast_compress_datum -
694691
*
695-
*Create a compressed version of a datum
692+
*Create a compressed version of avarlenadatum
696693
* ----------
697694
*/
698695
staticDatum
@@ -726,9 +723,9 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
726723
InsertIndexResultidxres;
727724
TupleDesctoasttupDesc;
728725
Datumt_values[3];
729-
chart_nulls[4];
726+
chart_nulls[3];
730727
varattrib*result;
731-
charchunk_data[MaxTupleSize];
728+
charchunk_data[VARHDRSZ+TOAST_MAX_CHUNK_SIZE];
732729
int32chunk_size;
733730
int32chunk_seq=0;
734731
char*data_p;
@@ -769,7 +766,6 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
769766
t_nulls[0]=' ';
770767
t_nulls[1]=' ';
771768
t_nulls[2]=' ';
772-
t_nulls[3]='\0';
773769

774770
/* ----------
775771
* Get the data to process
@@ -783,16 +779,8 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
783779
* ----------
784780
*/
785781
toastrel=heap_open(rel->rd_rel->reltoastrelid,RowExclusiveLock);
786-
if (toastrel==NULL)
787-
elog(ERROR,"Failed to open secondary relation of %s",
788-
DatumGetCString(DirectFunctionCall1(nameout,
789-
NameGetDatum(&(rel->rd_rel->relname)))));
790782
toasttupDesc=toastrel->rd_att;
791783
toastidx=index_open(rel->rd_rel->reltoastidxid);
792-
if (toastidx==NULL)
793-
elog(ERROR,"Failed to open index for secondary relation of %s",
794-
DatumGetCString(DirectFunctionCall1(nameout,
795-
NameGetDatum(&(rel->rd_rel->relname)))));
796784

797785
/* ----------
798786
* Split up the item into chunks
@@ -804,14 +792,13 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
804792
* Calculate the size of this chunk
805793
* ----------
806794
*/
807-
chunk_size= (TOAST_MAX_CHUNK_SIZE<data_todo) ?
808-
TOAST_MAX_CHUNK_SIZE :data_todo;
795+
chunk_size=Min(TOAST_MAX_CHUNK_SIZE,data_todo);
809796

810797
/* ----------
811798
* Build a tuple
812799
* ----------
813800
*/
814-
t_values[1]=(Datum)(chunk_seq++);
801+
t_values[1]=Int32GetDatum(chunk_seq++);
815802
VARATT_SIZEP(chunk_data)=chunk_size+VARHDRSZ;
816803
memcpy(VARATT_DATA(chunk_data),data_p,chunk_size);
817804
toasttup=heap_formtuple(toasttupDesc,t_values,t_nulls);
@@ -882,11 +869,7 @@ toast_delete_datum(Relation rel, Datum value)
882869
*/
883870
toastrel=heap_open(attr->va_content.va_external.va_toastrelid,
884871
RowExclusiveLock);
885-
if (toastrel==NULL)
886-
elog(ERROR,"Failed to open secondary relation at TOAST fetch");
887872
toastidx=index_open(attr->va_content.va_external.va_toastidxid);
888-
if (toastidx==NULL)
889-
elog(ERROR,"Failed to open index of secondary relation at TOAST fetch");
890873

891874
/* ----------
892875
* Setup a scan key to fetch from the index by va_valueid
@@ -928,8 +911,6 @@ toast_delete_datum(Relation rel, Datum value)
928911
index_endscan(toastscan);
929912
index_close(toastidx);
930913
heap_close(toastrel,RowExclusiveLock);
931-
932-
return;
933914
}
934915

935916

@@ -957,14 +938,15 @@ toast_fetch_datum(varattrib *attr)
957938
int32ressize;
958939
int32residx;
959940
intnumchunks;
960-
Datumchunk;
941+
Pointerchunk;
961942
boolisnull;
943+
int32chunksize;
962944

963945
char*chunks_found;
964946
char*chunks_expected;
965947

966948
ressize=attr->va_content.va_external.va_extsize;
967-
numchunks= (ressize /TOAST_MAX_CHUNK_SIZE)+1;
949+
numchunks= ((ressize-1) /TOAST_MAX_CHUNK_SIZE)+1;
968950

969951
chunks_found=palloc(numchunks);
970952
chunks_expected=palloc(numchunks);
@@ -982,12 +964,8 @@ toast_fetch_datum(varattrib *attr)
982964
*/
983965
toastrel=heap_open(attr->va_content.va_external.va_toastrelid,
984966
AccessShareLock);
985-
if (toastrel==NULL)
986-
elog(ERROR,"Failed to open secondary relation at TOAST fetch");
987967
toasttupDesc=toastrel->rd_att;
988968
toastidx=index_open(attr->va_content.va_external.va_toastidxid);
989-
if (toastidx==NULL)
990-
elog(ERROR,"Failed to open index of secondary relation at TOAST fetch");
991969

992970
/* ----------
993971
* Setup a scan key to fetch from the index by va_valueid
@@ -1001,6 +979,8 @@ toast_fetch_datum(varattrib *attr)
1001979

1002980
/* ----------
1003981
* Read the chunks by index
982+
*
983+
* Note we will not necessarily see the chunks in sequence-number order.
1004984
* ----------
1005985
*/
1006986
toastscan=index_beginscan(toastidx, false,1,&toastkey);
@@ -1018,30 +998,46 @@ toast_fetch_datum(varattrib *attr)
1018998
* Have a chunk, extract the sequence number and the data
1019999
* ----------
10201000
*/
1021-
residx= (int32)heap_getattr(ttup,2,toasttupDesc,&isnull);
1022-
chunk=heap_getattr(ttup,3,toasttupDesc,&isnull);
1001+
residx=DatumGetInt32(heap_getattr(ttup,2,toasttupDesc,&isnull));
1002+
Assert(!isnull);
1003+
chunk=DatumGetPointer(heap_getattr(ttup,3,toasttupDesc,&isnull));
1004+
Assert(!isnull);
1005+
chunksize=VARATT_SIZE(chunk)-VARHDRSZ;
10231006

10241007
/* ----------
10251008
* Some checks on the data we've found
10261009
* ----------
10271010
*/
1028-
if (residx*TOAST_MAX_CHUNK_SIZE+VARATT_SIZE(chunk)-VARHDRSZ
1029-
>ressize)
1030-
elog(ERROR,"chunk data exceeds original data size for "
1031-
"toast value %d",
1032-
attr->va_content.va_external.va_valueid);
1011+
if (residx<0||residx >=numchunks)
1012+
elog(ERROR,"unexpected chunk number %d for toast value %d",
1013+
residx,
1014+
attr->va_content.va_external.va_valueid);
1015+
if (residx<numchunks-1)
1016+
{
1017+
if (chunksize!=TOAST_MAX_CHUNK_SIZE)
1018+
elog(ERROR,"unexpected chunk size %d in chunk %d for toast value %d",
1019+
chunksize,residx,
1020+
attr->va_content.va_external.va_valueid);
1021+
}
1022+
else
1023+
{
1024+
if ((residx*TOAST_MAX_CHUNK_SIZE+chunksize)!=ressize)
1025+
elog(ERROR,"unexpected chunk size %d in chunk %d for toast value %d",
1026+
chunksize,residx,
1027+
attr->va_content.va_external.va_valueid);
1028+
}
10331029
if (chunks_found[residx]++>0)
10341030
elog(ERROR,"chunk %d for toast value %d appears multiple times",
1035-
residx,
1036-
attr->va_content.va_external.va_valueid);
1031+
residx,
1032+
attr->va_content.va_external.va_valueid);
10371033

10381034
/* ----------
1039-
* Copy the data into our result
1035+
* Copy the data intoproper place inour result
10401036
* ----------
10411037
*/
10421038
memcpy(((char*)VARATT_DATA(result))+residx*TOAST_MAX_CHUNK_SIZE,
1043-
VARATT_DATA(chunk),
1044-
VARATT_SIZE(chunk)-VARHDRSZ);
1039+
VARATT_DATA(chunk),
1040+
chunksize);
10451041

10461042
ReleaseBuffer(buffer);
10471043
}

‎src/backend/commands/command.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.93 2000/08/03 19:19:18 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.94 2000/08/04 04:16:06 tgl Exp $
1212
*
1313
* NOTES
1414
* The PerformAddAttribute() code, like most of the relation
@@ -1503,6 +1503,14 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
15031503
"chunk_data",
15041504
BYTEAOID,
15051505
-1,0, false);
1506+
/*
1507+
* Ensure that the toast table doesn't itself get toasted,
1508+
* or we'll be toast :-(. This is essential for chunk_data because
1509+
* type bytea is toastable; hit the other two just to be sure.
1510+
*/
1511+
tupdesc->attrs[0]->attstorage='p';
1512+
tupdesc->attrs[1]->attstorage='p';
1513+
tupdesc->attrs[2]->attstorage='p';
15061514

15071515
/*
15081516
* Note: the toast relation is considered a "normal" relation even if

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp