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

Commitb3a8305

Browse files
committed
amcheck: Fix FullTransactionIdFromXidAndCtx() for xids before epoch 0
64bit xids can't represent xids before epoch 0 (see alsobe504a3). WhenFullTransactionIdFromXidAndCtx() was passed such an xid, it'd create a 64bitxid far into the future. Noticed while adding assertions in the course ofinvestigatingbe504a3, as amcheck's test create such xids.To fix the issue, just return FirstNormalFullTransactionId in this case. Afreshly initdb'd cluster already has a newer horizon. The most minimal versionof this would make the messages for some detected corruptions differentlyinaccurate. To make those cases accurate, switchFullTransactionIdFromXidAndCtx() to use the 32bit modulo difference betweenxid and nextxid to compute the 64bit xid, yielding sensible "in the future" /"in the past" answers.Reviewed-by: Mark Dilger <mark.dilger@enterprisedb.com>Discussion:https://postgr.es/m/20230108002923.cyoser3ttmt63bfn@awork3.anarazel.deBackpatch: 14-, where heapam verification was introduced
1 parenta42f515 commitb3a8305

File tree

2 files changed

+49
-14
lines changed

2 files changed

+49
-14
lines changed

‎contrib/amcheck/verify_heapam.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,17 +1576,40 @@ check_tuple(HeapCheckContext *ctx)
15761576
staticFullTransactionId
15771577
FullTransactionIdFromXidAndCtx(TransactionIdxid,constHeapCheckContext*ctx)
15781578
{
1579-
uint32epoch;
1579+
uint64nextfxid_i;
1580+
int32diff;
1581+
FullTransactionIdfxid;
15801582

15811583
Assert(TransactionIdIsNormal(ctx->next_xid));
15821584
Assert(FullTransactionIdIsNormal(ctx->next_fxid));
1585+
Assert(XidFromFullTransactionId(ctx->next_fxid)==ctx->next_xid);
15831586

15841587
if (!TransactionIdIsNormal(xid))
15851588
returnFullTransactionIdFromEpochAndXid(0,xid);
1586-
epoch=EpochFromFullTransactionId(ctx->next_fxid);
1587-
if (xid>ctx->next_xid)
1588-
epoch--;
1589-
returnFullTransactionIdFromEpochAndXid(epoch,xid);
1589+
1590+
nextfxid_i=U64FromFullTransactionId(ctx->next_fxid);
1591+
1592+
/* compute the 32bit modulo difference */
1593+
diff= (int32) (ctx->next_xid-xid);
1594+
1595+
/*
1596+
* In cases of corruption we might see a 32bit xid that is before epoch
1597+
* 0. We can't represent that as a 64bit xid, due to 64bit xids being
1598+
* unsigned integers, without the modulo arithmetic of 32bit xid. There's
1599+
* no really nice way to deal with that, but it works ok enough to use
1600+
* FirstNormalFullTransactionId in that case, as a freshly initdb'd
1601+
* cluster already has a newer horizon.
1602+
*/
1603+
if (diff>0&& (nextfxid_i-FirstNormalTransactionId)< (int64)diff)
1604+
{
1605+
Assert(EpochFromFullTransactionId(ctx->next_fxid)==0);
1606+
fxid=FirstNormalFullTransactionId;
1607+
}
1608+
else
1609+
fxid=FullTransactionIdFromU64(nextfxid_i-diff);
1610+
1611+
Assert(FullTransactionIdIsNormal(fxid));
1612+
returnfxid;
15901613
}
15911614

15921615
/*

‎src/bin/pg_amcheck/t/004_verify_heapam.pl

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ sub write_tuple
217217
my$relpath ="$pgdata/$rel";
218218

219219
# Insert data and freeze public.test
220-
use constantROWCOUNT=>16;
220+
use constantROWCOUNT=>17;
221221
$node->safe_psql(
222222
'postgres',qq(
223223
INSERT INTO public.test (a, b, c)
@@ -296,7 +296,7 @@ sub write_tuple
296296
$node->start;
297297

298298
# Ok, Xids and page layout look ok. We can run corruption tests.
299-
plantests=>19;
299+
plantests=>20;
300300

301301
# Check that pg_amcheck runs against the uncorrupted table without error.
302302
$node->command_ok(
@@ -379,23 +379,24 @@ sub header
379379
elsif ($offnum == 3)
380380
{
381381
# Corruptly set xmin < datfrozenxid, further back, noting circularity
382-
# of xid comparison. For a new cluster with epoch = 0, the corrupt
383-
#xminwill be interpreted as in the future
384-
$tup->{t_xmin} =4026531839;
382+
# of xid comparison.
383+
my$xmin= 4026531839;
384+
$tup->{t_xmin} =$xmin;
385385
$tup->{t_infomask} &= ~HEAP_XMIN_COMMITTED;
386386
$tup->{t_infomask} &= ~HEAP_XMIN_INVALID;
387387

388388
push@expected,
389-
qr/${$header}xmin4026531839 equals or exceeds next valid transaction ID 0:\d+/;
389+
qr/${$header}xmin${xmin} precedes oldest valid transaction ID 0:\d+/;
390390
}
391391
elsif ($offnum == 4)
392392
{
393393
# Corruptly set xmax < relminmxid;
394-
$tup->{t_xmax} = 4026531839;
394+
my$xmax = 4026531839;
395+
$tup->{t_xmax} =$xmax;
395396
$tup->{t_infomask} &= ~HEAP_XMAX_INVALID;
396397

397398
push@expected,
398-
qr/${$header}xmax4026531839 equals or exceeds next valid transaction ID 0:\d+/;
399+
qr/${$header}xmax${xmax} precedes oldest valid transaction ID 0:\d+/;
399400
}
400401
elsif ($offnum == 5)
401402
{
@@ -503,7 +504,7 @@ sub header
503504
push@expected,
504505
qr/${header}multitransaction ID 4 equals or exceeds next valid multitransaction ID 1/;
505506
}
506-
elsif ($offnum == 15)# Last offnum must equal ROWCOUNT
507+
elsif ($offnum == 15)
507508
{
508509
# Set both HEAP_XMAX_COMMITTED and HEAP_XMAX_IS_MULTI
509510
$tup->{t_infomask} |= HEAP_XMAX_COMMITTED;
@@ -513,6 +514,17 @@ sub header
513514
push@expected,
514515
qr/${header}multitransaction ID 4000000000 precedes relation minimum multitransaction ID threshold 1/;
515516
}
517+
elsif ($offnum == 16)# Last offnum must equal ROWCOUNT
518+
{
519+
# Corruptly set xmin > next_xid to be in the future.
520+
my$xmin = 123456;
521+
$tup->{t_xmin} =$xmin;
522+
$tup->{t_infomask} &= ~HEAP_XMIN_COMMITTED;
523+
$tup->{t_infomask} &= ~HEAP_XMIN_INVALID;
524+
525+
push@expected,
526+
qr/${$header}xmin${xmin} equals or exceeds next valid transaction ID 0:\d+/;
527+
}
516528
write_tuple($file,$offset,$tup);
517529
}
518530
close($file)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp