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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list