mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 13:02:28 +01:00
78bd0d25bb
git-svn-id: file:///svn/mysql/tokudb-engine/tokudb-engine@45132 c7de825b-a66e-492c-adef-691d508d4ae1
218 lines
7.3 KiB
C++
218 lines
7.3 KiB
C++
#if TOKU_INCLUDE_ANALYZE
|
|
//
|
|
// This function will probably need to be redone from scratch
|
|
// if we ever choose to implement it
|
|
//
|
|
int
|
|
ha_tokudb::analyze(THD * thd, HA_CHECK_OPT * check_opt) {
|
|
uint i;
|
|
DB_BTREE_STAT *stat = 0;
|
|
DB_TXN_STAT *txn_stat_ptr = 0;
|
|
tokudb_trx_data *trx = (tokudb_trx_data *) thd->ha_data[tokudb_hton->slot];
|
|
DBUG_ASSERT(trx);
|
|
|
|
for (i = 0; i < table_share->keys; i++) {
|
|
if (stat) {
|
|
free(stat);
|
|
stat = 0;
|
|
}
|
|
if ((key_file[i]->stat) (key_file[i], trx->all, (void *) &stat, 0))
|
|
goto err;
|
|
share->rec_per_key[i] = (stat->bt_ndata / (stat->bt_nkeys ? stat->bt_nkeys : 1));
|
|
}
|
|
/* A hidden primary key is not in key_file[] */
|
|
if (hidden_primary_key) {
|
|
if (stat) {
|
|
free(stat);
|
|
stat = 0;
|
|
}
|
|
if ((file->stat) (file, trx->all, (void *) &stat, 0))
|
|
goto err;
|
|
}
|
|
pthread_mutex_lock(&share->mutex);
|
|
share->status |= STATUS_TOKUDB_ANALYZE; // Save status on close
|
|
share->version++; // Update stat in table
|
|
pthread_mutex_unlock(&share->mutex);
|
|
update_status(share, table); // Write status to file
|
|
if (stat)
|
|
free(stat);
|
|
return ((share->status & STATUS_TOKUDB_ANALYZE) ? HA_ADMIN_FAILED : HA_ADMIN_OK);
|
|
|
|
err:
|
|
if (stat)
|
|
free(stat);
|
|
return HA_ADMIN_FAILED;
|
|
}
|
|
#endif
|
|
|
|
static int
|
|
hot_poll_fun(void *extra, float progress) {
|
|
HOT_OPTIMIZE_CONTEXT context = (HOT_OPTIMIZE_CONTEXT)extra;
|
|
if (context->thd->killed) {
|
|
sprintf(context->write_status_msg, "The process has been killed, aborting hot optimize.");
|
|
return ER_ABORTING_CONNECTION;
|
|
}
|
|
float percentage = progress * 100;
|
|
sprintf(context->write_status_msg, "Optimization of index %u of %u about %.lf%% done", context->current_table + 1, context->num_tables, percentage);
|
|
thd_proc_info(context->thd, context->write_status_msg);
|
|
#ifdef HA_TOKUDB_HAS_THD_PROGRESS
|
|
if (context->progress_stage < context->current_table) {
|
|
// the progress stage is behind the current table, so move up
|
|
// to the next stage and set the progress stage to current.
|
|
thd_progress_next_stage(context->thd);
|
|
context->progress_stage = context->current_table;
|
|
}
|
|
// the percentage we report here is for the current stage/db
|
|
thd_progress_report(context->thd, (unsigned long long) percentage, 100);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
volatile int ha_tokudb_optimize_wait = 0; // debug
|
|
|
|
// flatten all DB's in this table, to do so, peform hot optimize on each db
|
|
int
|
|
ha_tokudb::optimize(THD * thd, HA_CHECK_OPT * check_opt) {
|
|
TOKUDB_DBUG_ENTER("ha_tokudb::optimize");
|
|
while (ha_tokudb_optimize_wait) sleep(1); // debug
|
|
|
|
int error;
|
|
uint curr_num_DBs = table->s->keys + test(hidden_primary_key);
|
|
|
|
#ifdef HA_TOKUDB_HAS_THD_PROGRESS
|
|
// each DB is its own stage. as HOT goes through each db, we'll
|
|
// move on to the next stage.
|
|
thd_progress_init(thd, curr_num_DBs);
|
|
#endif
|
|
|
|
//
|
|
// for each DB, run optimize and hot_optimize
|
|
//
|
|
for (uint i = 0; i < curr_num_DBs; i++) {
|
|
DB* db = share->key_file[i];
|
|
error = db->optimize(db);
|
|
if (error) {
|
|
goto cleanup;
|
|
}
|
|
struct hot_optimize_context hc;
|
|
memset(&hc, 0, sizeof hc);
|
|
hc.thd = thd;
|
|
hc.write_status_msg = this->write_status_msg;
|
|
hc.ha = this;
|
|
hc.current_table = i;
|
|
hc.num_tables = curr_num_DBs;
|
|
error = db->hot_optimize(db, hot_poll_fun, &hc);
|
|
if (error) {
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
error = 0;
|
|
cleanup:
|
|
|
|
#ifdef HA_TOKUDB_HAS_THD_PROGRESS
|
|
thd_progress_end(thd);
|
|
#endif
|
|
|
|
TOKUDB_DBUG_RETURN(error);
|
|
}
|
|
|
|
|
|
struct check_context {
|
|
THD *thd;
|
|
};
|
|
|
|
static int
|
|
ha_tokudb_check_progress(void *extra, float progress) {
|
|
struct check_context *context = (struct check_context *) extra;
|
|
int result = 0;
|
|
if (context->thd->killed)
|
|
result = ER_ABORTING_CONNECTION;
|
|
return result;
|
|
}
|
|
|
|
static void
|
|
ha_tokudb_check_info(THD *thd, TABLE *table, const char *msg) {
|
|
if (thd->vio_ok()) {
|
|
char tablename[256];
|
|
snprintf(tablename, sizeof tablename, "%s.%s", table->s->db.str, table->s->table_name.str);
|
|
thd->protocol->prepare_for_resend();
|
|
thd->protocol->store(tablename, strlen(tablename), system_charset_info);
|
|
thd->protocol->store("check", 5, system_charset_info);
|
|
thd->protocol->store("info", 4, system_charset_info);
|
|
thd->protocol->store(msg, strlen(msg), system_charset_info);
|
|
thd->protocol->write();
|
|
}
|
|
}
|
|
|
|
volatile int ha_tokudb_check_verbose = 0; // debug
|
|
volatile int ha_tokudb_check_wait = 0; // debug
|
|
|
|
int
|
|
ha_tokudb::check(THD *thd, HA_CHECK_OPT *check_opt) {
|
|
TOKUDB_DBUG_ENTER("check");
|
|
while (ha_tokudb_check_wait) sleep(1); // debug
|
|
|
|
const char *old_proc_info = thd->proc_info;
|
|
thd_proc_info(thd, "tokudb::check");
|
|
|
|
int result = HA_ADMIN_OK;
|
|
int r;
|
|
|
|
int keep_going = 1;
|
|
if (check_opt->flags & T_QUICK) {
|
|
keep_going = 0;
|
|
}
|
|
if (check_opt->flags & T_EXTEND) {
|
|
keep_going = 1;
|
|
}
|
|
|
|
r = acquire_table_lock(transaction, lock_write);
|
|
if (r != 0)
|
|
result = HA_ADMIN_INTERNAL_ERROR;
|
|
if (result == HA_ADMIN_OK) {
|
|
uint32_t num_DBs = table_share->keys + test(hidden_primary_key);
|
|
time_t now;
|
|
char timebuf[32];
|
|
snprintf(write_status_msg, sizeof write_status_msg, "%s primary=%d num=%d", share->table_name, primary_key, num_DBs);
|
|
if (ha_tokudb_check_verbose) {
|
|
ha_tokudb_check_info(thd, table, write_status_msg);
|
|
now = time(0);
|
|
fprintf(stderr, "%.24s ha_tokudb::check %s\n", ctime_r(&now, timebuf), write_status_msg);
|
|
}
|
|
for (uint i = 0; i < num_DBs; i++) {
|
|
time_t now;
|
|
DB *db = share->key_file[i];
|
|
const char *kname = NULL;
|
|
if (i == primary_key) {
|
|
kname = "primary"; // hidden primary key does not set name
|
|
}
|
|
else {
|
|
kname = table_share->key_info[i].name;
|
|
}
|
|
snprintf(write_status_msg, sizeof write_status_msg, "%s key=%s %u", share->table_name, kname, i);
|
|
thd_proc_info(thd, write_status_msg);
|
|
if (ha_tokudb_check_verbose) {
|
|
ha_tokudb_check_info(thd, table, write_status_msg);
|
|
now = time(0);
|
|
fprintf(stderr, "%.24s ha_tokudb::check %s\n", ctime_r(&now, timebuf), write_status_msg);
|
|
}
|
|
struct check_context check_context = { thd };
|
|
r = db->verify_with_progress(db, ha_tokudb_check_progress, &check_context, ha_tokudb_check_verbose, keep_going);
|
|
snprintf(write_status_msg, sizeof write_status_msg, "%s key=%s %u result=%d", share->table_name, kname, i, r);
|
|
thd_proc_info(thd, write_status_msg);
|
|
if (ha_tokudb_check_verbose) {
|
|
ha_tokudb_check_info(thd, table, write_status_msg);
|
|
now = time(0);
|
|
fprintf(stderr, "%.24s ha_tokudb::check %s\n", ctime_r(&now, timebuf), write_status_msg);
|
|
}
|
|
if (result == HA_ADMIN_OK && r != 0) {
|
|
result = HA_ADMIN_CORRUPT;
|
|
if (!keep_going)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
thd_proc_info(thd, old_proc_info);
|
|
TOKUDB_DBUG_RETURN(result);
|
|
}
|