hatoku_hton.cc 38.5 KB
Newer Older
1
/* -*- mode: C; c-basic-offset: 4 -*- */
Zardosht Kasheff's avatar
Zardosht Kasheff committed
2 3
#define MYSQL_SERVER 1
#include "mysql_priv.h"
Zardosht Kasheff's avatar
Zardosht Kasheff committed
4 5 6 7 8 9

extern "C" {
#include "stdint.h"
#if defined(_WIN32)
#include "misc.h"
#endif
Barry Perlman's avatar
Barry Perlman committed
10
#define __STDC_FORMAT_MACROS
Zardosht Kasheff's avatar
Zardosht Kasheff committed
11
#include <inttypes.h>
Zardosht Kasheff's avatar
Zardosht Kasheff committed
12 13 14 15
#include "toku_os.h"
}


Zardosht Kasheff's avatar
Zardosht Kasheff committed
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
/* We define DTRACE after mysql_priv.h in case it disabled dtrace in the main server */
#ifdef HAVE_DTRACE
#define _DTRACE_VERSION 1
#else
#endif


#include <mysql/plugin.h>
#include "hatoku_hton.h"
#include "hatoku_defines.h"
#include "ha_tokudb.h"


#undef PACKAGE
#undef VERSION
#undef HAVE_DTRACE
#undef _DTRACE_VERSION

34
#define TOKU_METADB_NAME "tokudb_meta"
Zardosht Kasheff's avatar
Zardosht Kasheff committed
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

static inline void *thd_data_get(THD *thd, int slot) {
    return thd->ha_data[slot].ha_ptr;
}

static inline void thd_data_set(THD *thd, int slot, void *data) {
    thd->ha_data[slot].ha_ptr = data;
}



static uchar *tokudb_get_key(TOKUDB_SHARE * share, size_t * length, my_bool not_used __attribute__ ((unused))) {
    *length = share->table_name_length;
    return (uchar *) share->table_name;
}

static handler *tokudb_create_handler(handlerton * hton, TABLE_SHARE * table, MEM_ROOT * mem_root);
static MYSQL_THDVAR_BOOL(commit_sync, PLUGIN_VAR_THDLOCAL, "sync on txn commit", 
                         /* check */ NULL, /* update */ NULL, /* default*/ TRUE);

static void tokudb_print_error(const DB_ENV * db_env, const char *db_errpfx, const char *buffer);
static void tokudb_cleanup_log_files(void);
static int tokudb_end(handlerton * hton, ha_panic_function type);
static bool tokudb_flush_logs(handlerton * hton);
static bool tokudb_show_status(handlerton * hton, THD * thd, stat_print_fn * print, enum ha_stat_type);
static int tokudb_close_connection(handlerton * hton, THD * thd);
static int tokudb_commit(handlerton * hton, THD * thd, bool all);
static int tokudb_rollback(handlerton * hton, THD * thd, bool all);
static uint tokudb_alter_table_flags(uint flags);
#if 0
static int tokudb_rollback_to_savepoint(handlerton * hton, THD * thd, void *savepoint);
static int tokudb_savepoint(handlerton * hton, THD * thd, void *savepoint);
static int tokudb_release_savepoint(handlerton * hton, THD * thd, void *savepoint);
#endif
static bool tokudb_show_logs(THD * thd, stat_print_fn * stat_print);
handlerton *tokudb_hton;

const char *ha_tokudb_ext = ".tokudb";
char *tokudb_data_dir;
ulong tokudb_debug;
DB_ENV *db_env;
76
DB* metadata_db;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
77 78
HASH tokudb_open_tables;
pthread_mutex_t tokudb_mutex;
79
pthread_mutex_t tokudb_meta_mutex;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
80 81 82 83 84 85 86 87 88


//my_bool tokudb_shared_data = FALSE;
static u_int32_t tokudb_init_flags = 
    DB_CREATE | DB_THREAD | DB_PRIVATE | 
    DB_INIT_LOCK | 
    DB_INIT_MPOOL |
    DB_INIT_TXN | 
    0 | // disabled for 1.0.2 DB_INIT_LOG |
Zardosht Kasheff's avatar
Zardosht Kasheff committed
89
    DB_RECOVER;
90
static u_int32_t tokudb_env_flags = 0;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
91 92 93 94 95 96 97 98 99 100 101 102 103
// static u_int32_t tokudb_lock_type = DB_LOCK_DEFAULT;
// static ulong tokudb_log_buffer_size = 0;
// static ulong tokudb_log_file_size = 0;
static ulonglong tokudb_cache_size = 0;
static char *tokudb_home;
// static char *tokudb_tmpdir;
static char *tokudb_log_dir;
// static long tokudb_lock_scan_time = 0;
// static ulong tokudb_region_size = 0;
// static ulong tokudb_cache_parts = 1;
static ulong tokudb_max_lock;
static const char tokudb_hton_name[] = "TokuDB";
static const int tokudb_hton_name_length = sizeof(tokudb_hton_name) - 1;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
104
static u_int32_t tokudb_checkpointing_period;
105 106
u_int32_t tokudb_write_status_frequency;
u_int32_t tokudb_read_status_frequency;
107
my_bool tokudb_prelock_empty;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
108 109 110 111 112 113 114
#ifdef TOKUDB_VERSION
 char *tokudb_version = TOKUDB_VERSION;
#else
 char *tokudb_version;
#endif
struct st_mysql_storage_engine storage_engine_structure = { MYSQL_HANDLERTON_INTERFACE_VERSION };

Zardosht Kasheff's avatar
Zardosht Kasheff committed
115 116 117
extern "C" {
#include "ydb.h"
}
Zardosht Kasheff's avatar
Zardosht Kasheff committed
118 119 120

static int tokudb_init_func(void *p) {
    TOKUDB_DBUG_ENTER("tokudb_init_func");
Zardosht Kasheff's avatar
Zardosht Kasheff committed
121
    int r;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
122
#if defined(_WIN32)
Zardosht Kasheff's avatar
Zardosht Kasheff committed
123 124 125 126
    r = toku_ydb_init();
    if (r) {
        goto error;
    }
Zardosht Kasheff's avatar
Zardosht Kasheff committed
127
#endif
128 129
    db_env = NULL;
    metadata_db = NULL;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
130 131 132 133

    tokudb_hton = (handlerton *) p;

    VOID(pthread_mutex_init(&tokudb_mutex, MY_MUTEX_INIT_FAST));
134
    VOID(pthread_mutex_init(&tokudb_meta_mutex, MY_MUTEX_INIT_FAST));
Zardosht Kasheff's avatar
Zardosht Kasheff committed
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
    (void) hash_init(&tokudb_open_tables, system_charset_info, 32, 0, 0, (hash_get_key) tokudb_get_key, 0, 0);

    tokudb_hton->state = SHOW_OPTION_YES;
    // tokudb_hton->flags= HTON_CAN_RECREATE;  // QQQ this came from skeleton
    tokudb_hton->flags = HTON_CLOSE_CURSORS_AT_COMMIT | HTON_FLUSH_AFTER_RENAME;
#ifdef DB_TYPE_TOKUDB
    tokudb_hton->db_type = DB_TYPE_TOKUDB;
#else
    tokudb_hton->db_type = DB_TYPE_UNKNOWN;
#endif

    tokudb_hton->create = tokudb_create_handler;
    tokudb_hton->close_connection = tokudb_close_connection;
#if 0
    tokudb_hton->savepoint_offset = sizeof(DB_TXN *);
    tokudb_hton->savepoint_set = tokudb_savepoint;
    tokudb_hton->savepoint_rollback = tokudb_rollback_to_savepoint;
    tokudb_hton->savepoint_release = tokudb_release_savepoint;
#endif
    tokudb_hton->commit = tokudb_commit;
    tokudb_hton->rollback = tokudb_rollback;
    tokudb_hton->panic = tokudb_end;
    tokudb_hton->flush_logs = tokudb_flush_logs;
    tokudb_hton->show_status = tokudb_show_status;
    tokudb_hton->alter_table_flags = tokudb_alter_table_flags;
#if 0
    if (!tokudb_tmpdir)
        tokudb_tmpdir = mysql_tmpdir;
    DBUG_PRINT("info", ("tokudb_tmpdir: %s", tokudb_tmpdir));
#endif
    if (!tokudb_home)
        tokudb_home = mysql_real_data_home;
    DBUG_PRINT("info", ("tokudb_home: %s", tokudb_home));
#if 0
    if (!tokudb_log_buffer_size) { // QQQ
        tokudb_log_buffer_size = max(table_cache_size * 512, 32 * 1024);
        DBUG_PRINT("info", ("computing tokudb_log_buffer_size %ld\n", tokudb_log_buffer_size));
    }
    tokudb_log_file_size = tokudb_log_buffer_size * 4;
    tokudb_log_file_size = MY_ALIGN(tokudb_log_file_size, 1024 * 1024L);
    tokudb_log_file_size = max(tokudb_log_file_size, 10 * 1024 * 1024L);
    DBUG_PRINT("info", ("computing tokudb_log_file_size: %ld\n", tokudb_log_file_size));
#endif
    if ((r = db_env_create(&db_env, 0))) {
        DBUG_PRINT("info", ("db_env_create %d\n", r));
        goto error;
    }

    DBUG_PRINT("info", ("tokudb_env_flags: 0x%x\n", tokudb_env_flags));
    r = db_env->set_flags(db_env, tokudb_env_flags, 1);
    if (r) { // QQQ
        if (tokudb_debug & TOKUDB_DEBUG_INIT) 
            TOKUDB_TRACE("%s:WARNING: flags=%x r=%d\n", __FUNCTION__, tokudb_env_flags, r); 
        // goto error;
    }

    // config error handling
    db_env->set_errcall(db_env, tokudb_print_error);
    db_env->set_errpfx(db_env, "TokuDB");

195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
    //
    // set default comparison functions
    //
    r = db_env->set_default_bt_compare(db_env, tokudb_cmp_dbt_key);
    if (r) {
        DBUG_PRINT("info", ("set_default_bt_compare%d\n", r));
        goto error; 
    }
    r = db_env->set_default_dup_compare(db_env, tokudb_cmp_dbt_data);
    if (r) {
        DBUG_PRINT("info", ("set_default_dup_compare%d\n", r));
        goto error; 
    }


Zardosht Kasheff's avatar
Zardosht Kasheff committed
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
    // config directories
#if 0
    DBUG_PRINT("info", ("tokudb_tmpdir: %s\n", tokudb_tmpdir));
    db_env->set_tmp_dir(db_env, tokudb_tmpdir);
#endif

    {
    char *data_dir = tokudb_data_dir;
    if (data_dir == 0) 
        data_dir = mysql_data_home;
    DBUG_PRINT("info", ("tokudb_data_dir: %s\n", data_dir));
    db_env->set_data_dir(db_env, data_dir);
    }

    if (tokudb_log_dir) {
        DBUG_PRINT("info", ("tokudb_log_dir: %s\n", tokudb_log_dir));
        db_env->set_lg_dir(db_env, tokudb_log_dir);
    }

229
    // config the cache table size to min(1/2 of physical memory, 1/8 of the process address space)
Zardosht Kasheff's avatar
Zardosht Kasheff committed
230
    if (tokudb_cache_size == 0) {
231 232 233 234 235 236 237 238
        uint64_t physmem, maxdata;
        physmem = toku_os_get_phys_memory_size();
        tokudb_cache_size = physmem / 2;
        r = toku_os_get_max_process_data_size(&maxdata);
        if (r == 0) {
            if (tokudb_cache_size > maxdata / 8)
                tokudb_cache_size = maxdata / 8;
        }
Zardosht Kasheff's avatar
Zardosht Kasheff committed
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
    }
    if (tokudb_cache_size) {
        DBUG_PRINT("info", ("tokudb_cache_size: %lld\n", tokudb_cache_size));
        r = db_env->set_cachesize(db_env, (u_int32_t)(tokudb_cache_size >> 30), (u_int32_t)(tokudb_cache_size % (1024L * 1024L * 1024L)), 1);
        if (r) {
            DBUG_PRINT("info", ("set_cachesize %d\n", r));
            goto error; 
        }
    }
    u_int32_t gbytes, bytes; int parts;
    r = db_env->get_cachesize(db_env, &gbytes, &bytes, &parts);
    if (r == 0) 
        if (tokudb_debug & TOKUDB_DEBUG_INIT) 
            TOKUDB_TRACE("%s:tokudb_cache_size=%lld\n", __FUNCTION__, ((unsigned long long) gbytes << 30) + bytes);

#if 0
    // QQQ config the logs
    DBUG_PRINT("info", ("tokudb_log_file_size: %ld\n", tokudb_log_file_size));
    db_env->set_lg_max(db_env, tokudb_log_file_size);
    DBUG_PRINT("info", ("tokudb_log_buffer_size: %ld\n", tokudb_log_buffer_size));
    db_env->set_lg_bsize(db_env, tokudb_log_buffer_size);
    // DBUG_PRINT("info",("tokudb_region_size: %ld\n", tokudb_region_size));
    // db_env->set_lg_regionmax(db_env, tokudb_region_size);
#endif

    // config the locks
#if 0 // QQQ no lock types yet
    DBUG_PRINT("info", ("tokudb_lock_type: 0x%lx\n", tokudb_lock_type));
    db_env->set_lk_detect(db_env, tokudb_lock_type);
#endif
    if (tokudb_max_lock) {
        DBUG_PRINT("info",("tokudb_max_lock: %ld\n", tokudb_max_lock));
        r = db_env->set_lk_max_locks(db_env, tokudb_max_lock);
        if (r) {
            DBUG_PRINT("info", ("tokudb_set_max_locks %d\n", r));
            goto error;
        }
    }

    if (tokudb_debug & TOKUDB_DEBUG_INIT) TOKUDB_TRACE("%s:env open:flags=%x\n", __FUNCTION__, tokudb_init_flags);

Zardosht Kasheff's avatar
Zardosht Kasheff committed
280
    r = db_env->open(db_env, tokudb_home, tokudb_init_flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
Zardosht Kasheff's avatar
Zardosht Kasheff committed
281 282 283 284 285 286 287 288

    if (tokudb_debug & TOKUDB_DEBUG_INIT) TOKUDB_TRACE("%s:env opened:return=%d\n", __FUNCTION__, r);

    if (r) {
        DBUG_PRINT("info", ("env->open %d\n", r));
        goto error;
    }

Zardosht Kasheff's avatar
Zardosht Kasheff committed
289 290 291
    r = db_env->checkpointing_set_period(db_env, tokudb_checkpointing_period);
    assert(!r);

Zardosht Kasheff's avatar
Zardosht Kasheff committed
292

293 294 295 296 297 298 299 300 301 302
    r = db_create(&metadata_db, db_env, 0);
    if (r) {
        DBUG_PRINT("info", ("failed to create metadata db %d\n", r));
        goto error;
    }
    
    metadata_db->set_bt_compare(metadata_db, tokudb_cmp_dbt_key);    

    r= metadata_db->open(metadata_db, 0, TOKU_METADB_NAME, NULL, DB_BTREE, DB_THREAD|DB_AUTO_COMMIT, 0);
    if (r) {
303 304 305 306 307
        if (r != ENOENT) {
            sql_print_error("Got error %d when trying to open metadata_db", r);
            goto error;
        }
        sql_print_warning("No metadata table exists, so creating it");
308 309 310 311
        r= metadata_db->open(metadata_db, NULL, TOKU_METADB_NAME, NULL, DB_BTREE, DB_THREAD | DB_CREATE, my_umask);
        if (r) {
            goto error;
        }
312 313
        r = metadata_db->close(metadata_db,0);
        assert(r == 0);
314 315 316 317 318 319 320 321 322 323 324 325 326
        r = db_create(&metadata_db, db_env, 0);
        if (r) {
            DBUG_PRINT("info", ("failed to create metadata db %d\n", r));
            goto error;
        }
        metadata_db->set_bt_compare(metadata_db, tokudb_cmp_dbt_key);    
        r= metadata_db->open(metadata_db, 0, TOKU_METADB_NAME, NULL, DB_BTREE, DB_THREAD|DB_AUTO_COMMIT, 0);
        if (r) {
            goto error;
        }
    }


Zardosht Kasheff's avatar
Zardosht Kasheff committed
327 328 329
    DBUG_RETURN(FALSE);

error:
330 331 332
    if (metadata_db) {
        metadata_db->close(metadata_db, 0);
    }
Zardosht Kasheff's avatar
Zardosht Kasheff committed
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
    if (db_env) {
        db_env->close(db_env, 0);
        db_env = 0;
    }
    DBUG_RETURN(TRUE);
}

static int tokudb_done_func(void *p) {
    TOKUDB_DBUG_ENTER("tokudb_done_func");
    int error = 0;

    if (tokudb_open_tables.records)
        error = 1;
    hash_free(&tokudb_open_tables);
    pthread_mutex_destroy(&tokudb_mutex);
348
    pthread_mutex_destroy(&tokudb_meta_mutex);
Zardosht Kasheff's avatar
Zardosht Kasheff committed
349 350 351
#if defined(_WIN32)
    toku_ydb_destroy();
#endif
Zardosht Kasheff's avatar
Zardosht Kasheff committed
352 353 354 355 356 357 358 359 360 361 362 363
    TOKUDB_DBUG_RETURN(0);
}



static handler *tokudb_create_handler(handlerton * hton, TABLE_SHARE * table, MEM_ROOT * mem_root) {
    return new(mem_root) ha_tokudb(hton, table);
}

int tokudb_end(handlerton * hton, ha_panic_function type) {
    TOKUDB_DBUG_ENTER("tokudb_end");
    int error = 0;
364 365 366
    if (metadata_db) {
        metadata_db->close(metadata_db, 0);
    }
Zardosht Kasheff's avatar
Zardosht Kasheff committed
367 368 369 370 371 372 373 374 375 376
    if (db_env) {
        if (tokudb_init_flags & DB_INIT_LOG)
            tokudb_cleanup_log_files();
        error = db_env->close(db_env, 0);       // Error is logged
        db_env = NULL;
    }
    TOKUDB_DBUG_RETURN(error);
}

static int tokudb_close_connection(handlerton * hton, THD * thd) {
377 378 379 380 381 382 383 384
    int error = 0;
    tokudb_trx_data* trx = NULL;
    trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
    if (trx && trx->checkpoint_lock_taken) {
        error = db_env->checkpointing_resume(db_env);
    }
    my_free(trx, MYF(0));
    return error;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
385 386 387 388 389 390
}

bool tokudb_flush_logs(handlerton * hton) {
    TOKUDB_DBUG_ENTER("tokudb_flush_logs");
    int error;
    bool result = 0;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
391 392 393 394 395 396 397 398 399 400 401 402 403 404
    u_int32_t curr_tokudb_checkpointing_period = 0;

    //
    // get the current checkpointing period
    //
    error = db_env->checkpointing_get_period(
        db_env, 
        &curr_tokudb_checkpointing_period
        );
    if (error) {
        my_error(ER_ERROR_DURING_CHECKPOINT, MYF(0), error);
        result = 1;
        goto exit;
    }
Zardosht Kasheff's avatar
Zardosht Kasheff committed
405

Zardosht Kasheff's avatar
Zardosht Kasheff committed
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
    //
    // if the current period is not the same as the variable, that means
    // the user has changed the period and now we need to update it
    //
    if (tokudb_checkpointing_period != curr_tokudb_checkpointing_period) {
        error = db_env->checkpointing_set_period(
            db_env, 
            tokudb_checkpointing_period
            );
        if (error) {
            my_error(ER_ERROR_DURING_CHECKPOINT, MYF(0), error);
            result = 1;
            goto exit;
        }
    }
    
    //
    // take the checkpoint
    //
Zardosht Kasheff's avatar
Zardosht Kasheff committed
425 426 427 428
    error = db_env->txn_checkpoint(db_env, 0, 0, 0);
    if (error) {
        my_error(ER_ERROR_DURING_CHECKPOINT, MYF(0), error);
        result = 1;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
429
        goto exit;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
430
    }
Zardosht Kasheff's avatar
Zardosht Kasheff committed
431 432 433

    result = 0;
exit:
Zardosht Kasheff's avatar
Zardosht Kasheff committed
434 435 436 437 438 439 440 441 442 443
    TOKUDB_DBUG_RETURN(result);
}

static int tokudb_commit(handlerton * hton, THD * thd, bool all) {
    TOKUDB_DBUG_ENTER("tokudb_commit");
    DBUG_PRINT("trans", ("ending transaction %s", all ? "all" : "stmt"));
    u_int32_t syncflag = THDVAR(thd, commit_sync) ? 0 : DB_TXN_NOSYNC;
    tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, hton->slot);
    DB_TXN **txn = all ? &trx->all : &trx->stmt;
    if (*txn) {
444
        if (tokudb_debug & TOKUDB_DEBUG_TXN) {
Zardosht Kasheff's avatar
Zardosht Kasheff committed
445
            TOKUDB_TRACE("commit:%d:%p\n", all, *txn);
446 447 448
        }
        commit_txn(*txn, syncflag);
        if (*txn == trx->sp_level) {
Zardosht Kasheff's avatar
Zardosht Kasheff committed
449
            trx->sp_level = 0;
450
        }
Zardosht Kasheff's avatar
Zardosht Kasheff committed
451 452 453 454 455 456 457 458
        *txn = 0;
    } 
    else if (tokudb_debug & TOKUDB_DEBUG_TXN) {
        TOKUDB_TRACE("commit0\n");
    }
    if (all) {
        trx->iso_level = hatoku_iso_not_set;
    }
459
    reset_stmt_progress(&trx->stmt_progress);
460
    TOKUDB_DBUG_RETURN(0);
Zardosht Kasheff's avatar
Zardosht Kasheff committed
461 462 463 464 465 466 467 468
}

static int tokudb_rollback(handlerton * hton, THD * thd, bool all) {
    TOKUDB_DBUG_ENTER("tokudb_rollback");
    DBUG_PRINT("trans", ("aborting transaction %s", all ? "all" : "stmt"));
    tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, hton->slot);
    DB_TXN **txn = all ? &trx->all : &trx->stmt;
    if (*txn) {
469
        if (tokudb_debug & TOKUDB_DEBUG_TXN) {
Zardosht Kasheff's avatar
Zardosht Kasheff committed
470
            TOKUDB_TRACE("rollback:%p\n", *txn);
471 472 473 474 475 476
        }
        abort_txn(*txn);
        if (*txn == trx->sp_level) {
            trx->sp_level = 0;
        }
        *txn = 0;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
477 478 479
    } 
    else {
        if (tokudb_debug & TOKUDB_DEBUG_TXN) {
Zardosht Kasheff's avatar
Zardosht Kasheff committed
480
            TOKUDB_TRACE("abort0\n");
Zardosht Kasheff's avatar
Zardosht Kasheff committed
481 482 483 484 485
        }
    }
    if (all) {
        trx->iso_level = hatoku_iso_not_set;
    }
486
    reset_stmt_progress(&trx->stmt_progress);
487
    TOKUDB_DBUG_RETURN(0);
Zardosht Kasheff's avatar
Zardosht Kasheff committed
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
}

#if 0

static int tokudb_savepoint(handlerton * hton, THD * thd, void *savepoint) {
    TOKUDB_DBUG_ENTER("tokudb_savepoint");
    int error;
    DB_TXN **save_txn = (DB_TXN **) savepoint;
    tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, hton->slot);
    if (!(error = db_env->txn_begin(db_env, trx->sp_level, save_txn, 0))) {
        trx->sp_level = *save_txn;
    }
    TOKUDB_DBUG_RETURN(error);
}

static int tokudb_rollback_to_savepoint(handlerton * hton, THD * thd, void *savepoint) {
    TOKUDB_DBUG_ENTER("tokudb_rollback_to_savepoint");
    int error;
    DB_TXN *parent, **save_txn = (DB_TXN **) savepoint;
    tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, hton->slot);
    parent = (*save_txn)->parent;
    if (!(error = (*save_txn)->abort(*save_txn))) {
        trx->sp_level = parent;
        error = tokudb_savepoint(hton, thd, savepoint);
    }
    TOKUDB_DBUG_RETURN(error);
}

static int tokudb_release_savepoint(handlerton * hton, THD * thd, void *savepoint) {
    TOKUDB_DBUG_ENTER("tokudb_release_savepoint");
    int error;
    DB_TXN *parent, **save_txn = (DB_TXN **) savepoint;
    tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, hton->slot);
    parent = (*save_txn)->parent;
    if (!(error = (*save_txn)->commit(*save_txn, 0))) {
        trx->sp_level = parent;
        *save_txn = 0;
    }
    TOKUDB_DBUG_RETURN(error);
}

#endif

531 532 533 534
static int smart_dbt_do_nothing (DBT const *key, DBT  const *row, void *context) {
  return 0;
}

535

536
static bool tokudb_show_data_size(THD * thd, stat_print_fn * stat_print, bool exact) {
537
    TOKUDB_DBUG_ENTER("tokudb_show_data_size");
538
    int error;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
539
    u_int64_t num_bytes_in_db = 0;
540 541 542
    DB* curr_db = NULL;
    DB_TXN* txn = NULL;
    DBC* tmp_cursor = NULL;
543
    DBC* tmp_table_cursor = NULL;
544 545 546 547 548 549 550
    DBT curr_key;
    DBT curr_val;
    char data_amount_msg[50] = {0};
    memset(&curr_key, 0, sizeof curr_key); 
    memset(&curr_val, 0, sizeof curr_val);
    pthread_mutex_lock(&tokudb_meta_mutex);

551
    error = db_env->txn_begin(db_env, 0, &txn, DB_READ_UNCOMMITTED);
552 553 554 555 556 557 558 559
    if (error) {
        goto cleanup;
    }
    error = metadata_db->cursor(metadata_db, txn, &tmp_cursor, 0);
    if (error) {
        goto cleanup;
    }
    while (error == 0) {
560 561 562 563 564 565 566 567
        //
        // here, and in other places, check if process has been killed
        // if so, get out of function so user is not stalled
        //
        if (thd->killed) {
            break;
        }
        
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
        //
        // do not need this to be super fast, so use old simple API
        //
        error = tmp_cursor->c_get(
            tmp_cursor, 
            &curr_key, 
            &curr_val, 
            DB_NEXT
            );
        if (!error) {
            char* name = (char *)curr_key.data;
            char* newname = NULL;
            u_int64_t curr_num_bytes = 0;
            DB_BTREE_STAT64 dict_stats;

            newname = (char *)my_malloc(
                get_max_dict_name_path_length(name),
                MYF(MY_WME|MY_ZEROFILL)
                );
            if (newname == NULL) { 
                error = ENOMEM;
                goto cleanup;
            }

            make_name(newname, name, "main");

            error = db_create(&curr_db, db_env, 0);
            if (error) { goto cleanup; }
            
597
            error = curr_db->open(curr_db, 0, newname, NULL, DB_BTREE, DB_THREAD, 0);
598
            if (error == ENOENT) { error = 0; continue; }
599 600
            if (error) { goto cleanup; }

601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
            if (exact) {
                //
                // flatten if exact is required
                //
                uint curr_num_items = 0;                
                error = curr_db->cursor(curr_db, txn, &tmp_table_cursor, 0);
                if (error) {
                    tmp_table_cursor = NULL;
                    goto cleanup;
                }
                while (error != DB_NOTFOUND) {
                    error = tmp_table_cursor->c_getf_next(tmp_table_cursor, 0, smart_dbt_do_nothing, NULL);
                    if (error && error != DB_NOTFOUND) {
                        goto cleanup;
                    }
                    curr_num_items++;
                    //
                    // allow early exit if command has been killed
                    //
                    if ( (curr_num_items % 1000) == 0 && thd->killed) {
                        goto cleanup;
                    }
                }                
                tmp_table_cursor->c_close(tmp_table_cursor);
                tmp_table_cursor = NULL;
            }

628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
            error = curr_db->stat64(
                curr_db, 
                txn, 
                &dict_stats
                );
            if (error) { goto cleanup; }

            curr_num_bytes = dict_stats.bt_dsize;
            if (*(uchar *)curr_val.data) {
                //
                // in this case, we have a hidden primary key, do not
                // want to report space taken up by the hidden primary key to the user
                //
                u_int64_t hpk_space = TOKUDB_HIDDEN_PRIMARY_KEY_LENGTH*dict_stats.bt_ndata;
                curr_num_bytes = (hpk_space > curr_num_bytes) ? 0 : curr_num_bytes - hpk_space;
            }
            else {
645 646 647
                //
                // one infinity byte per key needs to be subtracted
                //
648 649 650 651 652 653 654 655 656 657 658 659 660
                u_int64_t inf_byte_space = dict_stats.bt_ndata;
                curr_num_bytes = (inf_byte_space > curr_num_bytes) ? 0 : curr_num_bytes - inf_byte_space;
            }

            num_bytes_in_db += curr_num_bytes;

            curr_db->close(curr_db, 0);
            curr_db = NULL;
            
            my_free(newname,MYF(MY_ALLOW_ZERO_PTR));
        }
    }

Barry Perlman's avatar
Barry Perlman committed
661
    sprintf(data_amount_msg, "Number of bytes in database: %" PRIu64, num_bytes_in_db);
662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
    stat_print(
        thd, 
        tokudb_hton_name, 
        tokudb_hton_name_length, 
        "Data in tables", 
        strlen("Data in tables"), 
        data_amount_msg,
        strlen(data_amount_msg)
        );

    error = 0;

cleanup:
    if (curr_db) {
        curr_db->close(curr_db, 0);
    }
    if (tmp_cursor) {
        tmp_cursor->c_close(tmp_cursor);
    }
681 682 683
    if (tmp_table_cursor) {
        tmp_table_cursor->c_close(tmp_table_cursor);
    }
684
    if (txn) {
685
        commit_txn(txn, 0);
686 687
    }
    if (error) {
688
        sql_print_error("got an error %d in show_data_size\n", error);
689 690
    }
    pthread_mutex_unlock(&tokudb_meta_mutex);
691
    if (error) { my_errno = error; }
692 693 694
    TOKUDB_DBUG_RETURN(error);
}

695

Zardosht Kasheff's avatar
Zardosht Kasheff committed
696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729
static bool tokudb_show_logs(THD * thd, stat_print_fn * stat_print) {
    TOKUDB_DBUG_ENTER("tokudb_show_logs");
    char **all_logs, **free_logs, **a, **f;
    int error = 1;
    MEM_ROOT **root_ptr = my_pthread_getspecific_ptr(MEM_ROOT **, THR_MALLOC);
    MEM_ROOT show_logs_root, *old_mem_root = *root_ptr;

    init_sql_alloc(&show_logs_root, BDB_LOG_ALLOC_BLOCK_SIZE, BDB_LOG_ALLOC_BLOCK_SIZE);
    *root_ptr = &show_logs_root;
    all_logs = free_logs = 0;

    error = db_env->log_archive(db_env, &all_logs, 0);
    if (error) {
        DBUG_PRINT("error", ("log_archive failed (error %d)", error));
        db_env->err(db_env, error, "log_archive");
        if (error == DB_NOTFOUND)
            error = 0;          // No log files
        goto err;
    }
    /* Error is 0 here */
    if (all_logs) {
        for (a = all_logs, f = free_logs; *a; ++a) {
            if (f && *f && strcmp(*a, *f) == 0) {
                f++;
                if ((error = stat_print(thd, tokudb_hton_name, tokudb_hton_name_length, *a, strlen(*a), STRING_WITH_LEN(SHOW_LOG_STATUS_FREE))))
                    break;
            } else {
                if ((error = stat_print(thd, tokudb_hton_name, tokudb_hton_name_length, *a, strlen(*a), STRING_WITH_LEN(SHOW_LOG_STATUS_INUSE))))
                    break;
            }
        }
    }
  err:
    if (all_logs)
730
        free(all_logs);
Zardosht Kasheff's avatar
Zardosht Kasheff committed
731
    if (free_logs)
732
        free(free_logs);
Zardosht Kasheff's avatar
Zardosht Kasheff committed
733 734
    free_root(&show_logs_root, MYF(0));
    *root_ptr = old_mem_root;
735
    if (error) { my_errno = error; }
Zardosht Kasheff's avatar
Zardosht Kasheff committed
736 737 738
    TOKUDB_DBUG_RETURN(error);
}

739 740 741 742 743 744 745 746
#define STATPRINT(legend, val) stat_print(thd, \
                                          tokudb_hton_name, \
                                          tokudb_hton_name_length, \
                                          legend, \
                                          strlen(legend), \
                                          val, \
                                          strlen(val))

747 748 749
static bool tokudb_show_engine_status(THD * thd, stat_print_fn * stat_print) {
    TOKUDB_DBUG_ENTER("tokudb_show_engine_status");
    int error;
750 751
    const int bufsiz = 1024;
    char buf[bufsiz] = {'\0'};
752 753 754 755 756 757

    ENGINE_STATUS engstat;

    error = db_env->get_engine_status(db_env, &engstat);
    if (error == 0) {
      STATPRINT("time now", engstat.now);
758

759
      const char * lockstat = (engstat.ydb_lock_ctr & 0x01) ? "Locked" : "Unlocked";
760 761
      u_int64_t lockctr     =  engstat.ydb_lock_ctr >> 1;   // lsb indicates if locked
      snprintf(buf, bufsiz, "%" PRIu64, lockctr);  
762 763 764
      STATPRINT("ydb lock", lockstat);
      STATPRINT("ydb lock counter", buf);

765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789
      snprintf(buf, bufsiz, "%" PRIu64, engstat.max_possible_sleep);  
      STATPRINT("max_possible_sleep (microseconds)", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.processor_freq_mhz);  
      STATPRINT("processor_freq_mhz", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.max_requested_sleep);  
      STATPRINT("max_requested_sleep", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.times_max_sleep_used);  
      STATPRINT("times_max_sleep_used", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.total_sleepers);  
      STATPRINT("total_sleepers", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.total_sleep_time);  
      STATPRINT("total_sleep_time", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.max_waiters);  
      STATPRINT("max_waiters", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.total_waiters);  
      STATPRINT("total_waiters", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.total_clients);  
      STATPRINT("total_clients", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.time_ydb_lock_held_unavailable);  
      STATPRINT("time_ydb_lock_held_unavailable", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.max_time_ydb_lock_held);  
      STATPRINT("max_time_ydb_lock_held", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.total_time_ydb_lock_held);  
      STATPRINT("total_time_ydb_lock_held", buf);

790 791
      lockstat = (engstat.logger_lock_ctr & 0x01) ? "Locked" : "Unlocked";
      lockctr =  engstat.logger_lock_ctr >> 1;   // lsb indicates if locked
792
      snprintf(buf, bufsiz, "%" PRIu64, lockctr);  
793 794 795
      STATPRINT("logger lock", lockstat);
      STATPRINT("logger lock counter", buf);

796 797 798 799 800 801 802
      snprintf(buf, bufsiz, "%" PRIu32, engstat.checkpoint_period);
      STATPRINT("checkpoint period", buf);
      snprintf(buf, bufsiz, "%" PRIu32, engstat.checkpoint_footprint);
      STATPRINT("checkpoint status code (0 = idle)", buf);
      STATPRINT("last checkpoint began ", engstat.checkpoint_time_begin);
      STATPRINT("last complete checkpoint began ", engstat.checkpoint_time_begin_complete);
      STATPRINT("last complete checkpoint ended ", engstat.checkpoint_time_end);
803

804 805 806 807 808
      snprintf(buf, bufsiz, "%" PRIu64, engstat.cachetable_lock_taken);  
      STATPRINT("cachetable lock taken", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.cachetable_lock_released);  
      STATPRINT("cachetable lock released", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.cachetable_hit);  
809
      STATPRINT("cachetable hit", buf);
810
      snprintf(buf, bufsiz, "%" PRIu64, engstat.cachetable_miss);  
811
      STATPRINT("cachetable miss", buf);
812 813 814 815 816
      snprintf(buf, bufsiz, "%" PRIu64, engstat.cachetable_misstime);  
      STATPRINT("cachetable misstime", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.cachetable_waittime);  
      STATPRINT("cachetable waittime", buf);
      snprintf(buf, bufsiz, "%" PRIu64, engstat.cachetable_wait_reading);  
817
      STATPRINT("cachetable wait reading", buf);
818
      snprintf(buf, bufsiz, "%" PRIu64, engstat.cachetable_wait_writing);  
819
      STATPRINT("cachetable wait writing", buf);
820
      snprintf(buf, bufsiz, "%" PRIu64, engstat.puts);  
821
      STATPRINT("cachetable puts (new node)", buf);
822
      snprintf(buf, bufsiz, "%" PRIu64, engstat.prefetches);  
823
      STATPRINT("cachetable prefetches", buf);
824
      snprintf(buf, bufsiz, "%" PRIu64, engstat.maybe_get_and_pins);  
825
      STATPRINT("cachetable maybe_get_and_pins", buf);
826
      snprintf(buf, bufsiz, "%" PRIu64, engstat.maybe_get_and_pin_hits);  
827
      STATPRINT("cachetable maybe_get_and_pin_hits", buf);
828
      snprintf(buf, bufsiz, "%" PRIu64, engstat.cachetable_size_current);  
829
      STATPRINT("cachetable size_current", buf);
830
      snprintf(buf, bufsiz, "%" PRIu64, engstat.cachetable_size_limit);  
831
      STATPRINT("cachetable size_limit", buf);
832
      snprintf(buf, bufsiz, "%" PRIu64, engstat.cachetable_size_writing);  
833
      STATPRINT("cachetable size_writing", buf);
834 835
      snprintf(buf, bufsiz, "%" PRIu64, engstat.get_and_pin_footprint);  
      STATPRINT("cachetable get_and_pin_footprint", buf);
836

837
      snprintf(buf, bufsiz, "%" PRIu32, engstat.range_locks_max);
838
      STATPRINT("max range locks", buf);
839
      snprintf(buf, bufsiz, "%" PRIu32, engstat.range_locks_max_per_db);
840
      STATPRINT("max range locks per db", buf);
841
      snprintf(buf, bufsiz, "%" PRIu32, engstat.range_locks_curr);
842 843
      STATPRINT("range locks in use", buf);

844
      snprintf(buf, bufsiz, "%" PRIu64, engstat.inserts);
845
      STATPRINT("dictionary inserts", buf);
846
      snprintf(buf, bufsiz, "%" PRIu64, engstat.deletes);
847
      STATPRINT("dictionary deletes", buf);
848
      snprintf(buf, bufsiz, "%" PRIu64, engstat.point_queries);
849
      STATPRINT("dictionary point queries", buf);
850
      snprintf(buf, bufsiz, "%" PRIu64, engstat.sequential_queries);
851
      STATPRINT("dictionary sequential queries", buf);
852
      snprintf(buf, bufsiz, "%" PRIu64, engstat.commits);
853
      STATPRINT("txn commits", buf);
854
      snprintf(buf, bufsiz, "%" PRIu64, engstat.aborts);
855 856 857 858 859 860 861
      STATPRINT("txn aborts", buf);
    }
    if (error) { my_errno = error; }
    TOKUDB_DBUG_RETURN(error);
}


862
int tokudb_checkpoint_lock(THD * thd, stat_print_fn * stat_print) {
863 864 865 866
    int error;
    tokudb_trx_data* trx = NULL;
    trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
    if (!trx) {
867 868
        error = create_tokudb_trx_data_instance(&trx);
        if (error) { goto cleanup; }
869 870 871 872
        thd_data_set(thd, tokudb_hton->slot, trx);
    }
    
    if (trx->checkpoint_lock_taken) {
873
        STATPRINT("checkpoint lock", "Lock already taken");
874 875 876 877 878 879 880
        error = 0;
        goto cleanup;
    }
    error = db_env->checkpointing_postpone(db_env);
    if (error) { goto cleanup; }

    trx->checkpoint_lock_taken = true;
881
    STATPRINT("checkpoint lock", "Lock successfully taken");
882 883 884 885 886 887 888
    error = 0;
    
cleanup:
    if (error) { my_errno = error; }
    return error;
}

889
int tokudb_checkpoint_unlock(THD * thd, stat_print_fn * stat_print) {
890 891 892 893 894
    int error;
    tokudb_trx_data* trx = NULL;
    trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
    if (!trx) {
        error = 0;
895
        STATPRINT("checkpoint unlock", "Lock never taken");
896 897 898 899
        goto  cleanup;
    }
    if (!trx->checkpoint_lock_taken) {
        error = 0;
900
        STATPRINT("checkpoint unlock", "Lock never taken");
901 902 903 904 905 906 907 908 909
        goto  cleanup;
    }
    //
    // at this point, we know the checkpoint lock has been taken
    //
    error = db_env->checkpointing_resume(db_env);
    if (error) {goto cleanup;}

    trx->checkpoint_lock_taken = false;
910
    STATPRINT("checkpoint unlock", "Successfully unlocked");
911 912 913 914 915 916
    
cleanup:
    if (error) { my_errno = error; }
    return error;
}

917 918 919



Zardosht Kasheff's avatar
Zardosht Kasheff committed
920 921
bool tokudb_show_status(handlerton * hton, THD * thd, stat_print_fn * stat_print, enum ha_stat_type stat_type) {
    switch (stat_type) {
922
    case HA_ENGINE_DATA_AMOUNT:
923
        return tokudb_show_data_size(thd, stat_print, false);
924
        break;
925 926 927
    case HA_ENGINE_DATA_EXACT_AMOUNT:
        return tokudb_show_data_size(thd, stat_print, true);
        break;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
928 929
    case HA_ENGINE_LOGS:
        return tokudb_show_logs(thd, stat_print);
930
        break;
931 932 933
    case HA_ENGINE_STATUS:
        return tokudb_show_engine_status(thd, stat_print);
        break;
934
    case HA_ENGINE_CHECKPOINT_LOCK:
935
        return tokudb_checkpoint_lock(thd, stat_print);
936 937
        break;
    case HA_ENGINE_CHECKPOINT_UNLOCK:
938
        return tokudb_checkpoint_unlock(thd, stat_print);
939
        break;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
940
    default:
941
        break;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
942
    }
943
    return FALSE;
Zardosht Kasheff's avatar
Zardosht Kasheff committed
944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974
}

static void tokudb_print_error(const DB_ENV * db_env, const char *db_errpfx, const char *buffer) {
    sql_print_error("%s:  %s", db_errpfx, buffer);
}

void tokudb_cleanup_log_files(void) {
    TOKUDB_DBUG_ENTER("tokudb_cleanup_log_files");
    char **names;
    int error;

    if ((error = db_env->txn_checkpoint(db_env, 0, 0, 0)))
        my_error(ER_ERROR_DURING_CHECKPOINT, MYF(0), error);

    if ((error = db_env->log_archive(db_env, &names, 0)) != 0) {
        DBUG_PRINT("error", ("log_archive failed (error %d)", error));
        db_env->err(db_env, error, "log_archive");
        DBUG_VOID_RETURN;
    }

    if (names) {
        char **np;
        for (np = names; *np; ++np) {
#if 1
            if (tokudb_debug)
                TOKUDB_TRACE("%s:cleanup:%s\n", __FUNCTION__, *np);
#else
            my_delete(*np, MYF(MY_WME));
#endif
        }

975
        free(names);
Zardosht Kasheff's avatar
Zardosht Kasheff committed
976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022
    }

    DBUG_VOID_RETURN;
}

//
// *******NOTE*****
// If the flags HA_ONLINE_DROP_INDEX and HA_ONLINE_DROP_UNIQUE_INDEX
// are ever added, prepare_drop_index and final_drop_index will need to be modified
// so that the actual deletion of DB's is done in final_drop_index and not prepare_drop_index
//
static uint tokudb_alter_table_flags(uint flags)
{
    return (HA_ONLINE_ADD_INDEX_NO_WRITES| HA_ONLINE_DROP_INDEX_NO_WRITES |
            HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES| HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES);

}



// options flags
//   PLUGIN_VAR_THDLOCAL  Variable is per-connection
//   PLUGIN_VAR_READONLY  Server variable is read only
//   PLUGIN_VAR_NOSYSVAR  Not a server variable
//   PLUGIN_VAR_NOCMDOPT  Not a command line option
//   PLUGIN_VAR_NOCMDARG  No argument for cmd line
//   PLUGIN_VAR_RQCMDARG  Argument required for cmd line
//   PLUGIN_VAR_OPCMDARG  Argument optional for cmd line
//   PLUGIN_VAR_MEMALLOC  String needs memory allocated


// system variables

static MYSQL_SYSVAR_ULONGLONG(cache_size, tokudb_cache_size, PLUGIN_VAR_READONLY, "TokuDB cache table size", NULL, NULL, 0, 0, ~0LL, 0);

static MYSQL_SYSVAR_ULONG(max_lock, tokudb_max_lock, PLUGIN_VAR_READONLY, "TokuDB Max Locks", NULL, NULL, 8 * 1024, 0, ~0L, 0);

static MYSQL_SYSVAR_ULONG(debug, tokudb_debug, PLUGIN_VAR_READONLY, "TokuDB Debug", NULL, NULL, 0, 0, ~0L, 0);

static MYSQL_SYSVAR_STR(log_dir, tokudb_log_dir, PLUGIN_VAR_READONLY, "TokuDB Log Directory", NULL, NULL, NULL);

static MYSQL_SYSVAR_STR(data_dir, tokudb_data_dir, PLUGIN_VAR_READONLY, "TokuDB Data Directory", NULL, NULL, NULL);

static MYSQL_SYSVAR_STR(version, tokudb_version, PLUGIN_VAR_READONLY, "TokuDB Version", NULL, NULL, NULL);

static MYSQL_SYSVAR_UINT(init_flags, tokudb_init_flags, PLUGIN_VAR_READONLY, "Sets TokuDB DB_ENV->open flags", NULL, NULL, tokudb_init_flags, 0, ~0, 0);

Zardosht Kasheff's avatar
Zardosht Kasheff committed
1023
static MYSQL_SYSVAR_UINT(checkpointing_period, tokudb_checkpointing_period, 0, "TokuDB Checkpointing period", NULL, NULL, 60, 0, ~0L, 0);
1024
static MYSQL_SYSVAR_BOOL(prelock_empty, tokudb_prelock_empty, 0, "Tokudb Prelock Empty Table", NULL, NULL, TRUE);
1025 1026
static MYSQL_SYSVAR_UINT(write_status_frequency, tokudb_write_status_frequency, 0, "TokuDB frequency that show processlist updates status of writes", NULL, NULL, 1000, 0, ~0L, 0);
static MYSQL_SYSVAR_UINT(read_status_frequency, tokudb_read_status_frequency, 0, "TokuDB frequency that show processlist updates status of reads", NULL, NULL, 10000, 0, ~0L, 0);
Zardosht Kasheff's avatar
Zardosht Kasheff committed
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064
#if 0

static MYSQL_SYSVAR_ULONG(cache_parts, tokudb_cache_parts, PLUGIN_VAR_READONLY, "Sets TokuDB set_cache_parts", NULL, NULL, 0, 0, ~0L, 0);

// this is really a u_int32_t
// ? use MYSQL_SYSVAR_SET
static MYSQL_SYSVAR_UINT(env_flags, tokudb_env_flags, PLUGIN_VAR_READONLY, "Sets TokuDB env_flags", NULL, NULL, DB_LOG_AUTOREMOVE, 0, ~0, 0);

static MYSQL_SYSVAR_STR(home, tokudb_home, PLUGIN_VAR_READONLY, "Sets TokuDB env->open home", NULL, NULL, NULL);

// this is really a u_int32_t
//? use MYSQL_SYSVAR_SET

// this looks to be unused
static MYSQL_SYSVAR_LONG(lock_scan_time, tokudb_lock_scan_time, PLUGIN_VAR_READONLY, "Tokudb Lock Scan Time (UNUSED)", NULL, NULL, 0, 0, ~0L, 0);

// this is really a u_int32_t
//? use MYSQL_SYSVAR_ENUM
static MYSQL_SYSVAR_UINT(lock_type, tokudb_lock_type, PLUGIN_VAR_READONLY, "Sets set_lk_detect", NULL, NULL, DB_LOCK_DEFAULT, 0, ~0, 0);

static MYSQL_SYSVAR_ULONG(log_buffer_size, tokudb_log_buffer_size, PLUGIN_VAR_READONLY, "Tokudb Log Buffer Size", NULL, NULL, 0, 0, ~0L, 0);

static MYSQL_SYSVAR_ULONG(region_size, tokudb_region_size, PLUGIN_VAR_READONLY, "Tokudb Region Size", NULL, NULL, 128 * 1024, 0, ~0L, 0);

static MYSQL_SYSVAR_BOOL(shared_data, tokudb_shared_data, PLUGIN_VAR_READONLY, "Tokudb Shared Data", NULL, NULL, FALSE);

static MYSQL_SYSVAR_STR(tmpdir, tokudb_tmpdir, PLUGIN_VAR_READONLY, "Tokudb Tmp Dir", NULL, NULL, NULL);
#endif

static struct st_mysql_sys_var *tokudb_system_variables[] = {
    MYSQL_SYSVAR(cache_size),
    MYSQL_SYSVAR(max_lock),
    MYSQL_SYSVAR(data_dir),
    MYSQL_SYSVAR(log_dir),
    MYSQL_SYSVAR(debug),
    MYSQL_SYSVAR(commit_sync),
    MYSQL_SYSVAR(version),
    MYSQL_SYSVAR(init_flags),
Zardosht Kasheff's avatar
Zardosht Kasheff committed
1065
    MYSQL_SYSVAR(checkpointing_period),
1066
    MYSQL_SYSVAR(prelock_empty),
1067 1068
    MYSQL_SYSVAR(write_status_frequency),
    MYSQL_SYSVAR(read_status_frequency),
Zardosht Kasheff's avatar
Zardosht Kasheff committed
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087
#if 0
    MYSQL_SYSVAR(cache_parts),
    MYSQL_SYSVAR(env_flags),
    MYSQL_SYSVAR(home),
    MYSQL_SYSVAR(lock_scan_time),
    MYSQL_SYSVAR(lock_type),
    MYSQL_SYSVAR(log_buffer_size),
    MYSQL_SYSVAR(region_size),
    MYSQL_SYSVAR(shared_data),
    MYSQL_SYSVAR(tmpdir),
#endif
    NULL
};

mysql_declare_plugin(tokudb) {
    MYSQL_STORAGE_ENGINE_PLUGIN, 
    &storage_engine_structure, 
    "TokuDB", 
    "Tokutek Inc", 
1088
    "Tokutek TokuDB Storage Engine",
1089
    PLUGIN_LICENSE_GPL,
Zardosht Kasheff's avatar
Zardosht Kasheff committed
1090 1091
    tokudb_init_func,          /* plugin init */
    tokudb_done_func,          /* plugin deinit */
1092
    0x0210,                    /* 2.1.0 */
Zardosht Kasheff's avatar
Zardosht Kasheff committed
1093 1094 1095 1096 1097 1098
    NULL,                      /* status variables */
    tokudb_system_variables,   /* system variables */
    NULL                       /* config options */
}
mysql_declare_plugin_end;