Changeset: 8f3ba20b071e for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=8f3ba20b071e
Modified Files:
        sql/backends/monet5/sql_scenario.c
        sql/server/sql_mvc.c
        sql/server/sql_mvc.h
        sql/storage/bat/bat_storage.c
        sql/storage/bat/bat_table.c
        sql/storage/sql_storage.h
        sql/storage/store.c
Branch: Dec2016
Log Message:

vacuum catalog tables when db is idle.


diffs (truncated from 310 to 300 lines):

diff --git a/sql/backends/monet5/sql_scenario.c 
b/sql/backends/monet5/sql_scenario.c
--- a/sql/backends/monet5/sql_scenario.c
+++ b/sql/backends/monet5/sql_scenario.c
@@ -203,7 +203,7 @@ SQLepilogue(void *ret)
        return res;
 }
 
-MT_Id sqllogthread, minmaxthread;
+MT_Id sqllogthread, idlethread;
 
 static str
 SQLinit(void)
@@ -251,12 +251,10 @@ SQLinit(void)
                throw(SQL, "SQLinit", "Starting log manager failed");
        }
        GDKregister(sqllogthread);
-#if 0
-       if (MT_create_thread(&minmaxthread, (void (*)(void *)) 
mvc_minmaxmanager, NULL, MT_THR_JOINABLE) != 0) {
-               throw(SQL, "SQLinit", "Starting minmax manager failed");
+       if (MT_create_thread(&idlethread, (void (*)(void *)) mvc_idlemanager, 
NULL, MT_THR_JOINABLE) != 0) {
+               throw(SQL, "SQLinit", "Starting idle manager failed");
        }
-       GDKregister(minmaxthread);
-#endif
+       GDKregister(idlethread);
        return MAL_SUCCEED;
 }
 
diff --git a/sql/server/sql_mvc.c b/sql/server/sql_mvc.c
--- a/sql/server/sql_mvc.c
+++ b/sql/server/sql_mvc.c
@@ -179,11 +179,11 @@ mvc_logmanager(void)
 }
 
 void
-mvc_minmaxmanager(void)
+mvc_idlemanager(void)
 {
-       Thread thr = THRnew("minmaxmanager");
+       Thread thr = THRnew("idlemanager");
 
-       minmax_manager();
+       idle_manager();
        THRdel(thr);
 }
 
diff --git a/sql/server/sql_mvc.h b/sql/server/sql_mvc.h
--- a/sql/server/sql_mvc.h
+++ b/sql/server/sql_mvc.h
@@ -131,7 +131,7 @@ typedef struct mvc {
 extern int mvc_init(int debug, store_type store, int ro, int su, backend_stack 
stk);
 extern void mvc_exit(void);
 extern void mvc_logmanager(void);
-extern void mvc_minmaxmanager(void);
+extern void mvc_idlemanager(void);
 
 extern mvc *mvc_create(int clientid, backend_stack stk, int debug, bstream 
*rs, stream *ws);
 extern void mvc_reset(mvc *m, bstream *rs, stream *ws, int debug, int 
globalvars);
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
@@ -902,6 +902,62 @@ count_del(sql_trans *tr, sql_table *t)
        return d->cnt;
 }
 
+static size_t
+count_col_upd(sql_trans *tr, sql_column *c)
+{
+       sql_delta *b;
+
+       assert (isTable(c->t)) ;
+       if (!c->data) {
+               sql_column *oc = tr_find_column(tr->parent, c);
+               c->data = timestamp_delta(oc->data, tr->stime);
+       }
+        b = c->data;
+       if (!b)
+               return 1;
+       return b->ucnt;
+}
+
+static size_t
+count_idx_upd(sql_trans *tr, sql_idx *i)
+{
+       sql_delta *b;
+
+       assert (isTable(i->t)) ;
+       if (!i->data) {
+               sql_idx *oi = tr_find_idx(tr->parent, i);
+               i->data = timestamp_delta(oi->data, tr->stime);
+       }
+       b = i->data;
+       if (!b)
+               return 0;
+       return b->ucnt;
+}
+
+static size_t
+count_upd(sql_trans *tr, sql_table *t)
+{
+       node *n;
+
+       if (!isTable(t)) 
+               return 0;
+
+       for( n = t->columns.set->h; n; n = n->next) {
+               sql_column *c = n->data;
+
+               if (count_col_upd(tr, c))
+                       return 1;
+       }
+       if (t->idxs.set)
+       for( n = t->idxs.set->h; n; n = n->next) {
+               sql_idx *i = n->data;
+
+               if (count_idx_upd(tr, i))
+                       return 1;
+       }
+       return 0;
+}
+
 static int
 sorted_col(sql_trans *tr, sql_column *col)
 {
@@ -2466,6 +2522,7 @@ bat_storage_init( store_functions *sf)
        sf->delete_tab = (delete_tab_fptr)&delete_tab;
 
        sf->count_del = (count_del_fptr)&count_del;
+       sf->count_upd = (count_upd_fptr)&count_upd;
        sf->count_col = (count_col_fptr)&count_col;
        sf->count_idx = (count_idx_fptr)&count_idx;
        sf->dcount_col = (dcount_col_fptr)&dcount_col;
diff --git a/sql/storage/bat/bat_table.c b/sql/storage/bat/bat_table.c
--- a/sql/storage/bat/bat_table.c
+++ b/sql/storage/bat/bat_table.c
@@ -470,6 +470,32 @@ rids_diff(sql_trans *tr, rids *l, sql_co
        return l;
 }
 
+static int
+table_vacuum(sql_trans *tr, sql_table *t)
+{
+       BAT *tids = delta_cands(tr, t);
+       BAT **cols;
+       node *n;
+
+       cols = NEW_ARRAY(BAT*, cs_size(&t->columns));
+       for (n = t->columns.set->h; n; n = n->next) {
+               sql_column *c = n->data;
+               BAT *v = store_funcs.bind_col(tr, c, RDONLY);
+
+               cols[c->colnr] = BATproject(tids, v);
+               BBPunfix(v->batCacheid);
+       }
+       sql_trans_clear_table(tr, t);
+       for (n = t->columns.set->h; n; n = n->next) {
+               sql_column *c = n->data;
+
+               store_funcs.append_col(tr, c, cols[c->colnr], TYPE_bat);
+               BBPunfix(cols[c->colnr]->batCacheid);
+       }
+       _DELETE(cols);
+       return SQL_OK;
+}
+
 int 
 bat_table_init( table_functions *tf )
 {
@@ -479,6 +505,7 @@ bat_table_init( table_functions *tf )
        tf->column_update_value = column_update_value;
        tf->table_insert = table_insert;
        tf->table_delete = table_delete;
+       tf->table_vacuum = table_vacuum;
        
        tf->rids_select = rids_select;
        tf->rids_orderby = rids_orderby;
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
@@ -47,6 +47,7 @@ typedef void *(*column_find_value_fptr)(
 typedef int (*column_update_value_fptr)(sql_trans *tr, sql_column *c, oid rid, 
void *value);
 typedef int (*table_insert_fptr)(sql_trans *tr, sql_table *t, ...);
 typedef int (*table_delete_fptr)(sql_trans *tr, sql_table *t, oid rid);
+typedef int (*table_vacuum_fptr)(sql_trans *tr, sql_table *t);
 
 typedef struct rids {
        BUN cur;
@@ -92,6 +93,7 @@ typedef struct table_functions {
        column_update_value_fptr column_update_value;
        table_insert_fptr table_insert;
        table_delete_fptr table_delete;
+       table_vacuum_fptr table_vacuum;
 
        rids_select_fptr rids_select;
        rids_orderby_fptr rids_orderby;
@@ -130,6 +132,7 @@ typedef int (*delete_tab_fptr) (sql_tran
 -- check for sortedness
  */
 typedef size_t (*count_del_fptr) (sql_trans *tr, sql_table *t);
+typedef size_t (*count_upd_fptr) (sql_trans *tr, sql_table *t);
 typedef size_t (*count_col_fptr) (sql_trans *tr, sql_column *c, int all /* all 
or new only */);
 typedef size_t (*count_idx_fptr) (sql_trans *tr, sql_idx *i, int all /* all or 
new only */);
 typedef size_t (*dcount_col_fptr) (sql_trans *tr, sql_column *c);
@@ -207,6 +210,7 @@ typedef struct store_functions {
        delete_tab_fptr delete_tab;
 
        count_del_fptr count_del;
+       count_upd_fptr count_upd;
        count_col_fptr count_col;
        count_idx_fptr count_idx;
        dcount_col_fptr dcount_col;
@@ -323,7 +327,7 @@ extern void store_exit(void);
 extern void store_apply_deltas(void);
 extern void store_flush_log(void);
 extern void store_manager(void);
-extern void minmax_manager(void);
+extern void idle_manager(void);
 
 extern void store_lock(void);
 extern void store_unlock(void);
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -1700,6 +1700,46 @@ store_flush_log(void)
        need_flush = 1;
 }
 
+static int
+store_needs_vacuum( sql_trans *tr )
+{
+       sql_schema *s = find_sql_schema(tr, "sys");
+       node *n;
+
+       for( n = s->tables.set->h; n; n = n->next) {
+               sql_table *t = n->data;
+               sql_column *c = t->columns.set->h->data;
+
+               /* no inserts, updates and enough deletes ? */
+               if (!store_funcs.count_col(tr, c, 0) && 
+                   !store_funcs.count_upd(tr, t) && 
+                   store_funcs.count_del(tr, t) > 128) 
+                       return 1;
+       }
+       return 0;
+}
+
+static void
+store_vacuum( sql_trans *tr )
+{
+       /* tables */
+       sql_schema *s = find_sql_schema(tr, "sys");
+       node *n;
+
+       for( n = s->tables.set->h; n; n = n->next) {
+               sql_table *t = n->data;
+               sql_column *c = t->columns.set->h->data;
+               int cnt = 0;
+
+               if (!store_funcs.count_col(tr, c, 0) && 
+                   !store_funcs.count_upd(tr, t) && 
+                   (cnt = store_funcs.count_del(tr, t)) > 128) {
+                       /*printf("vacuum (%d) %s\n", cnt, t->base.name);*/
+                       table_funcs.table_vacuum(tr, t);
+               }
+       }
+}
+
 void
 store_manager(void)
 {
@@ -1791,23 +1831,32 @@ store_manager(void)
 }
 
 void
-minmax_manager(void)
-{
+idle_manager(void)
+{
+       const int timeout = GDKdebug & FORCEMITOMASK ? 10 : 50;
+
        while (!GDKexiting()) {
+               sql_session *s;
                int t;
 
-               for (t = 30000; t > 0; t -= 50) {
-                       MT_sleep_ms(50);
+               for (t = 5000; t > 0; t -= timeout) {
+                       MT_sleep_ms(timeout);
                        if (GDKexiting())
                                return;
                }
                MT_lock_set(&bs_lock);
-               if (store_nr_active || GDKexiting()) {
+               if (store_nr_active || GDKexiting() || 
!store_needs_vacuum(gtrans)) {
                        MT_lock_unset(&bs_lock);
                        continue;
                }
-               if (store_funcs.gtrans_minmax)
-                       store_funcs.gtrans_minmax(gtrans);
+
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to