Changeset: 92fece8ebda9 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=92fece8ebda9
Modified Files:
sql/storage/store.c
sql/test/2-phase-commit/Tests/TwoPrecommits.SQL.py
Branch: 2PC
Log Message:
keep a 'inflight' precommit_id in the global transaction. This
is the only precommit which can continue. And during that
phase no other transactions can start a precommit.
diffs (87 lines):
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -3157,6 +3157,22 @@ rollforward_trans(sql_trans *tr, int mod
return ok;
}
+/* 2PC
+ * Concurrent precommit's can currently not be handled. This because we use
+ * the per column, table, schema, transaction timestamps for the apply (in
memory
+ * update of all structures including the BATS). Therefor we now have a global
+ * flag indicating that a pre-commit has happend and we are waiting until
+ * the persistcommit.
+ *
+ * Improvements over this (too) simple scheme are
+ * 1) Add a timeout after which we will again failback to allowing new
+ * pre-commits etc. Problem is we cannot ever apply the pending pre-commit.
+ *
+ * 2) Have a list of in-flight precommits, each with a non overlapping
+ * set of updated tables. This would (at least) allow for concurrent
+ * different table updates and inserts.
+ * 2PC
+ */
static int
validate_tables(sql_schema *s, sql_schema *os)
{
@@ -3475,8 +3491,11 @@ sql_trans_validate(sql_trans *tr)
{
node *n;
+ /* We cannot handle other outstanding precommits */
+ if (tr->parent == gtrans && gtrans->precommit_id)
+ return 0;
+
/* depends on the iso level */
-
if (tr->schema_number != store_schema_number())
return 0;
@@ -3574,6 +3593,8 @@ sql_trans_precommit(sql_trans *tr)
if (result == LOG_OK)
result = logger_funcs.log_tend();
tr->schema_number = store_schema_number();
+ /* Mark current precommit in flight */
+ gtrans->precommit_id = tr->precommit_id;
return (result==LOG_OK)?SQL_OK:SQL_ERR;
}
return (result==LOG_OK)?SQL_OK:SQL_ERR;
@@ -3595,8 +3616,10 @@ sql_trans_persistcommit(sql_trans *tr)
if (result == LOG_OK) {
/* Mark the transaction as globally persisted as well */
result = logger_funcs.log_persist_precommit(tr->precommit_id);
+ assert(tr->precommit_id == gtrans->precommit_id);
+ gtrans->precommit_id = 0;
}
- return (result==LOG_OK)?SQL_OK:SQL_ERR;
+ return (result==LOG_OK)?SQL_OK:SQL_ERR;
}
int
diff --git a/sql/test/2-phase-commit/Tests/TwoPrecommits.SQL.py
b/sql/test/2-phase-commit/Tests/TwoPrecommits.SQL.py
--- a/sql/test/2-phase-commit/Tests/TwoPrecommits.SQL.py
+++ b/sql/test/2-phase-commit/Tests/TwoPrecommits.SQL.py
@@ -38,11 +38,20 @@ run(c2, 'INSERT INTO htmtest VALUES (5,
#run(c3, 'INSERT INTO htmtest VALUES (6, 60)')
run(c2, 'CALL precommit(2)')
-run(c1, 'CALL precommit(1)')
+try:
+ run(c1, 'CALL precommit(1)')
+except:
+ print "precommit failed\n"
#run(c3, 'CALL precommit(3)')
-run(c1, 'CALL persistcommit(1)')
+try:
+ run(c1, 'CALL persistcommit(1)')
+except:
+ print "persistcommit failed\n"
run(c2, 'CALL persistcommit(2)')
-query(c1, 'SELECT * FROM htmtest')
+try:
+ query(c1, 'SELECT * FROM htmtest')
+except:
+ print "select fails on aborted transaction\n"
query(c2, 'SELECT * FROM htmtest')
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list