Skip to content

Commit

Permalink
Options to turn off different validation types
Browse files Browse the repository at this point in the history
  • Loading branch information
ctring committed Oct 26, 2023
1 parent 7dda686 commit 13d431b
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 14 deletions.
3 changes: 3 additions & 0 deletions control_plane/src/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,9 @@ impl Endpoint {
"remotexact.connstring",
&format!("postgresql://{}", &self.env.xactserver.listen_pg_addr),
);
conf.append("remotexact.validate_index", "on");
conf.append("remotexact.validate_table", "on");
conf.append("remotexact.validate_tuple", "on");
conf.append("current_region", &self.region_id.to_string());
conf.append("multi_region", "on");

Expand Down
2 changes: 1 addition & 1 deletion pgxn/remotexact/funcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ validate_and_apply_xact(PG_FUNCTION_ARGS)
pg_qsort(rel->pages, rel->n_pages, sizeof(RWSetPage), page_comparator);
validate_index_scan(rel);
}
else
else
{
pg_qsort(rel->tuples, rel->n_tuples, sizeof(RWSetTuple), tuple_comparator);
validate_tuple_scan(rel);
Expand Down
33 changes: 30 additions & 3 deletions pgxn/remotexact/remotexact.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ void _PG_init(void);

/* GUCs */
char *remotexact_connstring;
bool remotexact_validate_index;
bool remotexact_validate_table;
bool remotexact_validate_tuple;

typedef struct CollectedRelationKey
{
Expand Down Expand Up @@ -595,9 +598,9 @@ check_for_rollback(StringInfo resp_buf)
initStringInfo(&s);
appendStringInfo(&s, "%s: %s.", severity, msg);
if (detail[0] != '\0')
appendStringInfo(&s, "DETAIL: %s", detail);
appendStringInfo(&s, " DETAIL: %s.", detail);
if (hint[0] != '\0')
appendStringInfo(&s, "HINT: %s", hint);
appendStringInfo(&s, " HINT: %s.", hint);

PQfreemem(resp_buf->data);
ereport(ERROR,
Expand Down Expand Up @@ -831,9 +834,33 @@ _PG_init(void)
NULL,
&remotexact_connstring,
"postgresql://127.0.0.1:10000",
PGC_POSTMASTER,
PGC_USERSET,
0, /* no flags required */
NULL, NULL, NULL);
DefineCustomBoolVariable("remotexact.validate_index",
"validate index scan during commit",
NULL,
&remotexact_validate_index,
true,
PGC_USERSET,
0, /* no flags required */
NULL, NULL, NULL);
DefineCustomBoolVariable("remotexact.validate_table",
"validate table scan during commit",
NULL,
&remotexact_validate_table,
true,
PGC_USERSET,
0, /* no flags required */
NULL, NULL, NULL);
DefineCustomBoolVariable("remotexact.validate_tuple",
"validate tuple scan during commit",
NULL,
&remotexact_validate_tuple,
true,
PGC_USERSET,
0, /* no flags required */
NULL, NULL, NULL);

if (remotexact_connstring && remotexact_connstring[0])
{
Expand Down
43 changes: 33 additions & 10 deletions pgxn/remotexact/validate.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ void validate_index_scan(RWSetRelation *rw_rel)
Page index_page;
XLogRecPtr page_lsn = InvalidXLogRecPtr;

if (!remotexact_validate_index)
return;

// This function must only be called for index scans in current_region.
Assert(rw_rel->region == current_region);
Assert(rw_rel->is_index && !rw_rel->is_table_scan);
Expand Down Expand Up @@ -74,9 +77,11 @@ void validate_index_scan(RWSetRelation *rw_rel)
if (page_lsn > read_csn) {
ereport(ERROR,
(errcode(ERRCODE_T_R_STATEMENT_COMPLETION_UNKNOWN),
errmsg("[remotexact] read out-of-date index data from a remote partition (relid: %u, blockno: %u)",
errmsg("[remotexact] read out-of-date index (relid: %u, blockno: %u, csn: %X/%X, readcsn: %X/%X)",
relid,
rw_rel->pages[i].blkno)));
rw_rel->pages[i].blkno,
LSN_FORMAT_ARGS(page_lsn),
LSN_FORMAT_ARGS(read_csn))));
}
}

Expand All @@ -91,6 +96,9 @@ validate_table_scan(RWSetRelation *rw_rel)
HeapTuple htup;
Snapshot snapshot = GetActiveSnapshot();

if (!remotexact_validate_table)
return;

// This function must only be called for table scans in current_region.
Assert(rw_rel->region == current_region);
Assert(rw_rel->is_table_scan && !rw_rel->is_index);
Expand All @@ -107,6 +115,7 @@ validate_table_scan(RWSetRelation *rw_rel)
{
HeapTupleHeader tuple = htup->t_data;
TransactionId checked_xid = InvalidTransactionId;
XLogRecPtr tuple_csn = InvalidXLogRecPtr;

/*
* Must lock the buffer before checking for visibility
Expand Down Expand Up @@ -176,11 +185,17 @@ validate_table_scan(RWSetRelation *rw_rel)
* Translate checked_xid into csn and compare it with csn used for the
* initial read.
*/
tuple_csn = CSNLogGetCSNByXid(current_region, checked_xid);
if (TransactionIdIsValid(checked_xid) &&
CSNLogGetCSNByXid(current_region, checked_xid) > read_csn)
tuple_csn > read_csn)
ereport(ERROR,
(errcode(ERRCODE_T_R_STATEMENT_COMPLETION_UNKNOWN),
errmsg("[remotexact] read out-of-date data from a remote partition (relid: %u)", relid)));
errmsg("[remotexact] read out-of-date table (relid: %u, blockno: %u, offset: %u, csn: %X/%X, readcsn: %X/%X)",
relid,
ItemPointerGetBlockNumber(&htup->t_self),
ItemPointerGetOffsetNumber(&htup->t_self),
LSN_FORMAT_ARGS(tuple_csn),
LSN_FORMAT_ARGS(read_csn))));

}

Expand All @@ -200,6 +215,9 @@ validate_tuple_scan(RWSetRelation *rw_rel)
Buffer buf = InvalidBuffer;
bool valid = false;

if (!remotexact_validate_tuple)
return;

// This function must only be called for table scans in current_region.
Assert(rw_rel->region == current_region);
Assert(!rw_rel->is_table_scan && !rw_rel->is_index);
Expand All @@ -208,6 +226,8 @@ validate_tuple_scan(RWSetRelation *rw_rel)

for (i = 0; i < rw_rel->n_tuples; i++)
{
XLogRecPtr tuple_csn = InvalidXLogRecPtr;

htup.t_self = rw_rel->tuples[i].tid;

/* By default, keep_buffer = false to ensure that we don't keep the
Expand All @@ -228,20 +248,23 @@ validate_tuple_scan(RWSetRelation *rw_rel)
* committed at or before the read_csn.
*/
TransactionId xmin = HeapTupleHeaderGetRawXmin(htup.t_data);
tuple_csn = CSNLogGetCSNByXid(current_region, xmin);
if (TransactionIdIsValid(xmin) &&
CSNLogGetCSNByXid(current_region, xmin) > read_csn)
tuple_csn > read_csn)
valid = false;

ReleaseBuffer(buf);
ReleaseBuffer(buf);
}

if (!valid) {
int blocknum = ItemPointerGetBlockNumber(&rw_rel->tuples[i].tid);
int offset = ItemPointerGetOffsetNumber(&rw_rel->tuples[i].tid);
ereport(ERROR,
(errcode(ERRCODE_T_R_STATEMENT_COMPLETION_UNKNOWN),
errmsg("[remotexact] read out-of-date tuple data from a remote partition (relid: %u, tid: (%u, %u))",
relid, blocknum, offset)));
errmsg("[remotexact] read out-of-date tuple (relid: %u, blockno: %u, offset: %u, csn: %X/%X, readcsn: %X/%X)",
relid,
ItemPointerGetBlockNumber(&rw_rel->tuples[i].tid),
ItemPointerGetOffsetNumber(&rw_rel->tuples[i].tid),
LSN_FORMAT_ARGS(tuple_csn),
LSN_FORMAT_ARGS(read_csn))));
}
}

Expand Down
5 changes: 5 additions & 0 deletions pgxn/remotexact/validate.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@

#include "utils/snapshot.h"

/* GUC variables defined in remotexact.c */
extern bool remotexact_validate_index;
extern bool remotexact_validate_table;
extern bool remotexact_validate_tuple;

void validate_index_scan(RWSetRelation *rw_rel);
void validate_table_scan(RWSetRelation *rw_rel);
void validate_tuple_scan(RWSetRelation *rw_rel);
Expand Down

0 comments on commit 13d431b

Please sign in to comment.