Skip to content

Commit dda830d

Browse files
dvcerCommitfest Bot
authored andcommitted
amcheck: common_verify - snapshot indcheckxmin check
Moves check to common_verify. Every index needs it for heapallindexed check.
1 parent 29c0227 commit dda830d

File tree

3 files changed

+29
-21
lines changed

3 files changed

+29
-21
lines changed

contrib/amcheck/verify_common.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,28 @@ index_checkable(Relation rel, Oid am_id)
189189

190190
return amcheck_index_mainfork_expected(rel);
191191
}
192+
193+
/*
194+
* GetTransactionSnapshot() always acquires a new MVCC snapshot in
195+
* READ COMMITTED mode. A new snapshot is guaranteed to have all
196+
* the entries it requires in the index.
197+
*
198+
* We must defend against the possibility that an old xact
199+
* snapshot was returned at higher isolation levels when that
200+
* snapshot is not safe for index scans of the target index. This
201+
* is possible when the snapshot sees tuples that are before the
202+
* index's indcheckxmin horizon. Throwing an error here should be
203+
* very rare. It doesn't seem worth using a secondary snapshot to
204+
* avoid this.
205+
*/
206+
void
207+
check_indcheckxmin(Relation idxrel, Snapshot snapshot)
208+
{
209+
if (IsolationUsesXactSnapshot() && idxrel->rd_index->indcheckxmin &&
210+
!TransactionIdPrecedes(HeapTupleHeaderGetXmin(idxrel->rd_indextuple->t_data),
211+
snapshot->xmin))
212+
ereport(ERROR,
213+
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
214+
errmsg("index \"%s\" cannot be verified using transaction snapshot",
215+
RelationGetRelationName(idxrel))));
216+
}

contrib/amcheck/verify_common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "storage/lmgr.h"
1515
#include "storage/lockdefs.h"
1616
#include "utils/relcache.h"
17+
#include "utils/snapshot.h"
1718
#include "miscadmin.h"
1819

1920
/* Typedef for callback function for amcheck_lock_relation_and_check */
@@ -26,3 +27,5 @@ extern void amcheck_lock_relation_and_check(Oid indrelid,
2627
Oid am_id,
2728
IndexDoCheckCallback check,
2829
LOCKMODE lockmode, void *state);
30+
31+
extern void check_indcheckxmin(Relation idxrel, Snapshot snapshot);

contrib/amcheck/verify_nbtree.c

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -442,27 +442,7 @@ bt_check_every_level(Relation rel, Relation heaprel, bool heapkeyspace,
442442
if (!state->readonly)
443443
{
444444
snapshot = RegisterSnapshot(GetTransactionSnapshot());
445-
446-
/*
447-
* GetTransactionSnapshot() always acquires a new MVCC snapshot in
448-
* READ COMMITTED mode. A new snapshot is guaranteed to have all
449-
* the entries it requires in the index.
450-
*
451-
* We must defend against the possibility that an old xact
452-
* snapshot was returned at higher isolation levels when that
453-
* snapshot is not safe for index scans of the target index. This
454-
* is possible when the snapshot sees tuples that are before the
455-
* index's indcheckxmin horizon. Throwing an error here should be
456-
* very rare. It doesn't seem worth using a secondary snapshot to
457-
* avoid this.
458-
*/
459-
if (IsolationUsesXactSnapshot() && rel->rd_index->indcheckxmin &&
460-
!TransactionIdPrecedes(HeapTupleHeaderGetXmin(rel->rd_indextuple->t_data),
461-
snapshot->xmin))
462-
ereport(ERROR,
463-
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
464-
errmsg("index \"%s\" cannot be verified using transaction snapshot",
465-
RelationGetRelationName(rel))));
445+
check_indcheckxmin(state->rel, snapshot);
466446
}
467447
}
468448

0 commit comments

Comments
 (0)