Changeset: 2604482aed42 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/2604482aed42
Modified Files:
sql/storage/store.c
Branch: iso
Log Message:
Set the commit lock earlier, so the dependency checks are always done in order,
thus avoiding a race condition. The impact will be small for most cases
diffs (95 lines):
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -2245,12 +2245,17 @@ store_manager(sqlstore *store)
int res;
if (store->debug&128 && ATOMIC_GET(&store->nr_active) == 0) {
+ MT_lock_set(&store->commit);
store_lock(store);
if (ATOMIC_GET(&store->nr_active) == 0) {
ulng oldest = store_timestamp(store)+1;
+
+ id_hash_clear(store->dependencies);
+ id_hash_clear(store->depchanges);
store_pending_changes(store, oldest);
}
store_unlock(store);
+ MT_lock_unset(&store->commit);
store->logger_api.activate(store); /* rotate too new
log file */
}
@@ -3478,6 +3483,7 @@ sql_trans_rollback(sql_trans *tr)
list_prepend(nl, n->data);
/* rollback */
+ MT_lock_set(&store->commit);
store_lock(store);
ulng oldest = store_oldest(store);
ulng commit_ts = store_get_timestamp(store); /* use most recent
timestamp such that we can cleanup savely */
@@ -3503,12 +3509,14 @@ sql_trans_rollback(sql_trans *tr)
} else
_DELETE(c);
}
+ store_unlock(store);
+ MT_lock_unset(&store->commit);
list_destroy(nl);
list_destroy(tr->changes);
tr->changes = NULL;
tr->logchanges = 0;
- store_unlock(store);
} else if (ATOMIC_GET(&store->nr_active) == 1) { /* just me cleanup */
+ MT_lock_set(&store->commit);
store_lock(store);
if (ATOMIC_GET(&store->nr_active) == 1 && !tr->parent) {
id_hash_clear(store->dependencies);
@@ -3517,6 +3525,7 @@ sql_trans_rollback(sql_trans *tr)
ulng oldest = store_timestamp(store);
store_pending_changes(store, oldest);
store_unlock(store);
+ MT_lock_unset(&store->commit);
}
if (tr->localtmps.dset) {
list_destroy2(tr->localtmps.dset, tr->store);
@@ -3756,20 +3765,21 @@ sql_trans_commit(sql_trans *tr)
}
if (!list_empty(tr->changes)) {
- ulng commit_ts = tr->parent ? tr->parent->tid :
store_timestamp(store), oldest = 0;
int flush = 0;
+ ulng commit_ts, oldest = 0;
+
+ MT_lock_set(&store->commit);
+ commit_ts = tr->parent ? tr->parent->tid :
store_timestamp(store);
if (!tr->parent && (!list_empty(tr->dependencies) ||
!list_empty(tr->depchanges))) {
- store_lock(store);
ok = transaction_check_dependencies_and_removals(tr,
commit_ts);
- store_unlock(store);
if (ok != LOG_OK) {
+ MT_lock_unset(&store->commit);
sql_trans_rollback(tr);
return ok == LOG_CONFLICT ? SQL_CONFLICT :
SQL_ERR;
}
}
- MT_lock_set(&store->commit);
/* log changes should only be done if there is something to log
*/
if (!tr->parent && tr->logchanges > 0) {
int min_changes = GDKdebug & FORCEMITOMASK ? 5 :
1000000;
@@ -3845,6 +3855,7 @@ sql_trans_commit(sql_trans *tr)
tr->changes = NULL;
tr->ts = commit_ts;
} else if (ATOMIC_GET(&store->nr_active) == 1) { /* just me cleanup */
+ MT_lock_set(&store->commit);
store_lock(store);
if (ATOMIC_GET(&store->nr_active) == 1 && !tr->parent) {
id_hash_clear(store->dependencies);
@@ -3853,6 +3864,7 @@ sql_trans_commit(sql_trans *tr)
ulng oldest = store_timestamp(store);
store_pending_changes(store, oldest);
store_unlock(store);
+ MT_lock_unset(&store->commit);
}
/* drop local temp tables with commit action CA_DROP, after cleanup */
if (cs_size(&tr->localtmps)) {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list