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

Commit50529e5

Browse files
committed
amcheck: Improve some confusing reports about TOAST problems.
Don't phrase reports in terms of the number of tuples thus-farreturned by the index scan, but rather in terms of the chunk_seqvalues found inside the tuples.Patch by me, reviewed by Mark Dilger.Discussion:http://postgr.es/m/CA+TgmoZUONCkdcdR778EKuE+f1r5Obieu63db2OgMPHaEvEPTQ@mail.gmail.com
1 parentf68970e commit50529e5

File tree

1 file changed

+40
-35
lines changed

1 file changed

+40
-35
lines changed

‎contrib/amcheck/verify_heapam.c

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ typedef struct HeapCheckContext
150150
staticvoidsanity_check_relation(Relationrel);
151151
staticvoidcheck_tuple(HeapCheckContext*ctx);
152152
staticvoidcheck_toast_tuple(HeapTupletoasttup,HeapCheckContext*ctx,
153-
ToastedAttribute*ta,int32chunkno,
154-
int32endchunk);
153+
ToastedAttribute*ta,int32*expected_chunk_seq,
154+
uint32extsize);
155155

156156
staticboolcheck_tuple_attribute(HeapCheckContext*ctx);
157157
staticvoidcheck_toasted_attribute(HeapCheckContext*ctx,
@@ -1159,37 +1159,51 @@ check_tuple_visibility(HeapCheckContext *ctx)
11591159
* each toast tuple being checked against where we are in the sequence, as well
11601160
* as each toast tuple having its varlena structure sanity checked.
11611161
*
1162-
* Returns whether the toast tuple passed the corruption checks.
1162+
* On entry, *expected_chunk_seq should be the chunk_seq value that we expect
1163+
* to find in toasttup. On exit, it will be updated to the value the next call
1164+
* to this function should expect to see.
11631165
*/
11641166
staticvoid
11651167
check_toast_tuple(HeapTupletoasttup,HeapCheckContext*ctx,
1166-
ToastedAttribute*ta,int32chunkno,int32endchunk)
1168+
ToastedAttribute*ta,int32*expected_chunk_seq,
1169+
uint32extsize)
11671170
{
1168-
int32curchunk;
1171+
int32chunk_seq;
1172+
int32last_chunk_seq= (extsize-1) /TOAST_MAX_CHUNK_SIZE;
11691173
Pointerchunk;
11701174
boolisnull;
11711175
int32chunksize;
11721176
int32expected_size;
11731177

1174-
/*
1175-
* Have a chunk, extract the sequence number and the data
1176-
*/
1177-
curchunk=DatumGetInt32(fastgetattr(toasttup,2,
1178-
ctx->toast_rel->rd_att,&isnull));
1178+
/* Sanity-check the sequence number. */
1179+
chunk_seq=DatumGetInt32(fastgetattr(toasttup,2,
1180+
ctx->toast_rel->rd_att,&isnull));
11791181
if (isnull)
11801182
{
11811183
report_toast_corruption(ctx,ta,
11821184
psprintf("toast value %u has toast chunk with null sequence number",
11831185
ta->toast_pointer.va_valueid));
11841186
return;
11851187
}
1188+
if (chunk_seq!=*expected_chunk_seq)
1189+
{
1190+
/* Either the TOAST index is corrupt, or we don't have all chunks. */
1191+
report_toast_corruption(ctx,ta,
1192+
psprintf("toast value %u index scan returned chunk %d when expecting chunk %d",
1193+
ta->toast_pointer.va_valueid,
1194+
chunk_seq,*expected_chunk_seq));
1195+
}
1196+
*expected_chunk_seq=chunk_seq+1;
1197+
1198+
/* Sanity-check the chunk data. */
11861199
chunk=DatumGetPointer(fastgetattr(toasttup,3,
11871200
ctx->toast_rel->rd_att,&isnull));
11881201
if (isnull)
11891202
{
11901203
report_toast_corruption(ctx,ta,
11911204
psprintf("toast value %u chunk %d has null data",
1192-
ta->toast_pointer.va_valueid,chunkno));
1205+
ta->toast_pointer.va_valueid,
1206+
chunk_seq));
11931207
return;
11941208
}
11951209
if (!VARATT_IS_EXTENDED(chunk))
@@ -1209,40 +1223,31 @@ check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
12091223
report_toast_corruption(ctx,ta,
12101224
psprintf("toast value %u chunk %d has invalid varlena header %0x",
12111225
ta->toast_pointer.va_valueid,
1212-
chunkno,header));
1226+
chunk_seq,header));
12131227
return;
12141228
}
12151229

12161230
/*
12171231
* Some checks on the data we've found
12181232
*/
1219-
if (curchunk!=chunkno)
1220-
{
1221-
report_toast_corruption(ctx,ta,
1222-
psprintf("toast value %u chunk %d has sequence number %d, but expected sequence number %d",
1223-
ta->toast_pointer.va_valueid,
1224-
chunkno,curchunk,chunkno));
1225-
return;
1226-
}
1227-
if (chunkno>endchunk)
1233+
if (chunk_seq>last_chunk_seq)
12281234
{
12291235
report_toast_corruption(ctx,ta,
12301236
psprintf("toast value %u chunk %d follows last expected chunk %d",
12311237
ta->toast_pointer.va_valueid,
1232-
chunkno,endchunk));
1238+
chunk_seq,last_chunk_seq));
12331239
return;
12341240
}
12351241

1236-
expected_size=curchunk<endchunk ?TOAST_MAX_CHUNK_SIZE
1237-
:VARATT_EXTERNAL_GET_EXTSIZE(ta->toast_pointer)- (endchunk*TOAST_MAX_CHUNK_SIZE);
1242+
expected_size=chunk_seq<last_chunk_seq ?TOAST_MAX_CHUNK_SIZE
1243+
:extsize- (last_chunk_seq*TOAST_MAX_CHUNK_SIZE);
12381244

12391245
if (chunksize!=expected_size)
12401246
report_toast_corruption(ctx,ta,
12411247
psprintf("toast value %u chunk %d has size %u, but expected size %u",
12421248
ta->toast_pointer.va_valueid,
1243-
chunkno,chunksize,expected_size));
1249+
chunk_seq,chunksize,expected_size));
12441250
}
1245-
12461251
/*
12471252
* Check the current attribute as tracked in ctx, recording any corruption
12481253
* found in ctx->tupstore.
@@ -1436,10 +1441,12 @@ check_toasted_attribute(HeapCheckContext *ctx, ToastedAttribute *ta)
14361441
SysScanDesctoastscan;
14371442
boolfound_toasttup;
14381443
HeapTupletoasttup;
1439-
int32chunkno;
1440-
int32endchunk;
1444+
uint32extsize;
1445+
int32expected_chunk_seq=0;
1446+
int32last_chunk_seq;
14411447

1442-
endchunk= (VARATT_EXTERNAL_GET_EXTSIZE(ta->toast_pointer)-1) /TOAST_MAX_CHUNK_SIZE;
1448+
extsize=VARATT_EXTERNAL_GET_EXTSIZE(ta->toast_pointer);
1449+
last_chunk_seq= (extsize-1) /TOAST_MAX_CHUNK_SIZE;
14431450

14441451
/*
14451452
* Setup a scan key to find chunks in toast table with matching va_valueid
@@ -1458,27 +1465,25 @@ check_toasted_attribute(HeapCheckContext *ctx, ToastedAttribute *ta)
14581465
ctx->valid_toast_index,
14591466
&SnapshotToast,1,
14601467
&toastkey);
1461-
chunkno=0;
14621468
found_toasttup= false;
14631469
while ((toasttup=
14641470
systable_getnext_ordered(toastscan,
14651471
ForwardScanDirection))!=NULL)
14661472
{
14671473
found_toasttup= true;
1468-
check_toast_tuple(toasttup,ctx,ta,chunkno,endchunk);
1469-
chunkno++;
1474+
check_toast_tuple(toasttup,ctx,ta,&expected_chunk_seq,extsize);
14701475
}
14711476
systable_endscan_ordered(toastscan);
14721477

14731478
if (!found_toasttup)
14741479
report_toast_corruption(ctx,ta,
14751480
psprintf("toast value %u not found in toast table",
14761481
ta->toast_pointer.va_valueid));
1477-
elseif (chunkno!= (endchunk+1))
1482+
elseif (expected_chunk_seq <=last_chunk_seq)
14781483
report_toast_corruption(ctx,ta,
1479-
psprintf("toast value %u was expected to end at chunk %d, but endedat chunk %d",
1484+
psprintf("toast value %u was expected to end at chunk %d, but endedwhile expecting chunk %d",
14801485
ta->toast_pointer.va_valueid,
1481-
(endchunk+1),chunkno));
1486+
last_chunk_seq,expected_chunk_seq));
14821487
}
14831488

14841489
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp