Changeset: e9a9d667c7f9 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/e9a9d667c7f9
Modified Files:
sql/storage/bat/bat_storage.c
sql/storage/objectset.c
sql/storage/sql_storage.h
sql/storage/store.c
Branch: Jul2021
Log Message:
oldest is oldest mines your self
Cleanup object's once the oldest is young enough, cleanup
the objectversion/nodes later (when then possible transactions accessing
it are all gone).
diffs (238 lines):
diff --git a/sql/storage/bat/bat_storage.c b/sql/storage/bat/bat_storage.c
--- a/sql/storage/bat/bat_storage.c
+++ b/sql/storage/bat/bat_storage.c
@@ -3407,6 +3407,9 @@ commit_update_col( sql_trans *tr, sql_ch
sql_column *c = (sql_column*)change->obj;
sql_delta *delta = ATOMIC_PTR_GET(&c->data);
+ if (isDeleted(c->t))
+ return ok;
+
if (isTempTable(c->t))
return commit_update_col_(tr, c, commit_ts, oldest);
if (commit_ts)
@@ -3485,6 +3488,9 @@ commit_update_idx( sql_trans *tr, sql_ch
sql_idx *i = (sql_idx*)change->obj;
sql_delta *delta = ATOMIC_PTR_GET(&i->data);
+ if (isDeleted(i->t))
+ return ok;
+
if (isTempTable(i->t))
return commit_update_idx_( tr, i, commit_ts, oldest);
if (commit_ts)
@@ -3569,6 +3575,9 @@ commit_update_del( sql_trans *tr, sql_ch
sql_table *t = (sql_table*)change->obj;
storage *dbat = ATOMIC_PTR_GET(&t->data);
+ if (isDeleted(t))
+ return ok;
+
if (isTempTable(t)) {
if (!(dbat = temp_tab_timestamp_storage(tr, t)))
return LOG_ERR;
@@ -3799,7 +3808,7 @@ claim_segmentsV2(sql_trans *tr, sql_tabl
{
int in_transaction = segments_in_transaction(tr, t), ok = LOG_OK;
assert(s->segs);
- ulng oldest = store_oldest(tr->store);
+ ulng oldest = store_oldest(tr->store, NULL);
BUN slot = 0;
size_t total = cnt;
@@ -3885,7 +3894,7 @@ claim_segments(sql_trans *tr, sql_table
return claim_segmentsV2(tr, t, s, cnt, offset, offsets, locked);
int in_transaction = segments_in_transaction(tr, t), ok = LOG_OK;
assert(s->segs);
- ulng oldest = store_oldest(tr->store);
+ ulng oldest = store_oldest(tr->store, NULL);
BUN slot = 0;
int reused = 0;
diff --git a/sql/storage/objectset.c b/sql/storage/objectset.c
--- a/sql/storage/objectset.c
+++ b/sql/storage/objectset.c
@@ -399,7 +399,7 @@ objectversion_destroy(sqlstore *store, o
node_destroy(ov->os, store, ov->id_based_head);
}
- if (os->destroy)
+ if (os->destroy && ov->b)
os->destroy(store, ov->b);
_DELETE(ov);
@@ -496,6 +496,18 @@ os_rollback(objectversion *ov, sqlstore
return LOG_OK;
}
+static void
+ov_destroy_obj_recursive(sqlstore* store, objectversion *ov)
+{
+ if (ov->id_based_older && ov->id_based_older == ov->name_based_older) {
+ ov_destroy_obj_recursive(store, ov->id_based_older);
+ }
+ if (ov->os->destroy && ov->b) {
+ ov->os->destroy(store, ov->b);
+ ov->b = NULL;
+ }
+}
+
static inline void
try_to_mark_deleted_for_destruction(sqlstore* store, objectversion *ov)
{
@@ -521,6 +533,7 @@ try_to_mark_deleted_for_destruction(sqls
}
ov->ts = store_get_timestamp(store)+1;
+ ov_destroy_obj_recursive(store, ov);
}
}
@@ -573,6 +586,7 @@ os_cleanup(sqlstore* store, objectversio
if (ov->ts <= oldest) {
// the oldest relevant state is deleted so lets try to
mark it as destroyed
try_to_mark_deleted_for_destruction(store, ov);
+ return LOG_OK+1;
}
// Keep it inplace on the cleanup list, either because it is
now marked for destruction or
@@ -596,14 +610,14 @@ os_cleanup(sqlstore* store, objectversio
static int
tc_gc_objectversion(sql_store store, sql_change *change, ulng oldest)
{
- assert(!change->handled);
+// assert(!change->handled);
objectversion *ov = (objectversion*)change->data;
if (oldest && oldest >= TRANSACTION_ID_BASE)
return 0;
int res = os_cleanup( (sqlstore*) store, ov, oldest);
change->handled = (res)?true:false;
- return res;
+ return res>=0?LOG_OK:LOG_ERR;
}
static int
diff --git a/sql/storage/sql_storage.h b/sql/storage/sql_storage.h
--- a/sql/storage/sql_storage.h
+++ b/sql/storage/sql_storage.h
@@ -317,7 +317,7 @@ extern void store_resume_log(struct sqls
extern lng store_hot_snapshot(struct sqlstore *store, str tarfile);
extern lng store_hot_snapshot_to_stream(struct sqlstore *store, stream *s);
-extern ulng store_oldest(struct sqlstore *store);
+extern ulng store_oldest(struct sqlstore *store, sql_trans *tr);
extern ulng store_get_timestamp(struct sqlstore *store);
extern void store_manager(struct sqlstore *store);
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -45,8 +45,15 @@ store_transaction_id(sqlstore *store)
}
ulng
-store_oldest(sqlstore *store)
-{
+store_oldest(sqlstore *store, sql_trans *tr)
+{
+ if (tr && tr->ts == store->oldest) {
+ sql_session *s = store->active->h->data;
+ if (s->tr == tr && store->active->h->next) {
+ s = store->active->h->next->data;
+ return s->tr->ts;
+ }
+ }
return store->oldest;
}
@@ -2267,7 +2274,7 @@ id_hash_clear_older(sql_hash *h, ulng ol
}
static void
-store_pending_changes(sqlstore *store, ulng oldest)
+store_pending_changes(sqlstore *store, ulng oldest, sql_trans *tr)
{
ulng oldest_changes = store_get_timestamp(store);
if (!list_empty(store->changes)) { /* lets first cleanup old stuff */
@@ -2280,7 +2287,7 @@ store_pending_changes(sqlstore *store, u
} else if (c->cleanup && c->cleanup(store, c, oldest)) {
list_remove_node(store->changes, store, n);
_DELETE(c);
- } else if (c->ts < oldest_changes) {
+ } else if (!c->handled && c->ts < oldest_changes) {
oldest_changes = c->ts;
}
n = next;
@@ -2290,7 +2297,7 @@ store_pending_changes(sqlstore *store, u
dep_hash_clear(store->dependencies);
dep_hash_clear(store->depchanges);
} else {
- ulng stoldest = store_oldest(store);
+ ulng stoldest = store_oldest(store, tr);
id_hash_clear_older(store->dependencies, stoldest);
id_hash_clear_older(store->depchanges, stoldest);
}
@@ -2314,7 +2321,7 @@ store_manager(sqlstore *store)
store_lock(store);
if (ATOMIC_GET(&store->nr_active) == 0) {
ulng oldest = store_timestamp(store)+1;
- store_pending_changes(store, oldest);
+ store_pending_changes(store, oldest, NULL);
}
store_unlock(store);
MT_lock_set(&store->flush);
@@ -3500,7 +3507,7 @@ sql_trans_rollback(sql_trans *tr, bool c
if (!commit_lock)
MT_lock_set(&store->commit);
store_lock(store);
- ulng oldest = store_oldest(store);
+ ulng oldest = store_oldest(store, tr);
ulng commit_ts = store_get_timestamp(store); /* use most recent
timestamp such that we can cleanup savely */
for(node *n=nl->h; n; n = n->next) {
sql_change *c = n->data;
@@ -3509,7 +3516,7 @@ sql_trans_rollback(sql_trans *tr, bool c
c->commit(tr, c, 0 /* ie rollback */, oldest);
c->ts = commit_ts;
}
- store_pending_changes(store, oldest);
+ store_pending_changes(store, oldest, tr);
for(node *n=nl->h; n; n = n->next) {
sql_change *c = n->data;
@@ -3531,8 +3538,8 @@ sql_trans_rollback(sql_trans *tr, bool c
if (!commit_lock)
MT_lock_set(&store->commit);
store_lock(store);
- ulng oldest = store_oldest(store);
- store_pending_changes(store, oldest);
+ ulng oldest = store_oldest(store, tr);
+ store_pending_changes(store, oldest, tr);
store_unlock(store);
if (!commit_lock)
MT_lock_unset(&store->commit);
@@ -3834,13 +3841,13 @@ sql_trans_commit(sql_trans *tr)
if (tr->parent)
tr->parent->logchanges += tr->logchanges;
}
- oldest = tr->parent ? commit_ts : store_oldest(store);
+ oldest = tr->parent ? commit_ts : store_oldest(store, tr);
tr->logchanges = 0;
TRC_DEBUG(SQL_STORE, "Forwarding changes (" ULLFMT ", " ULLFMT
") -> " ULLFMT "\n", tr->tid, tr->ts, commit_ts);
/* apply committed changes */
if (ATOMIC_GET(&store->nr_active) == 1 && !tr->parent)
oldest = commit_ts;
- store_pending_changes(store, oldest);
+ store_pending_changes(store, oldest, tr);
for(node *n=tr->changes->h; n && ok == LOG_OK; n = n->next) {
sql_change *c = n->data;
@@ -3897,7 +3904,7 @@ sql_trans_commit(sql_trans *tr)
MT_lock_set(&store->commit);
store_lock(store);
ulng oldest = store_timestamp(store);
- store_pending_changes(store, oldest);
+ store_pending_changes(store, oldest, tr);
store_unlock(store);
MT_lock_unset(&store->commit);
}
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]