summaryrefslogtreecommitdiff
path: root/storage/tokudb/ft-index/src/ydb.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/tokudb/ft-index/src/ydb.cc')
-rw-r--r--storage/tokudb/ft-index/src/ydb.cc244
1 files changed, 169 insertions, 75 deletions
diff --git a/storage/tokudb/ft-index/src/ydb.cc b/storage/tokudb/ft-index/src/ydb.cc
index d1c09f8cc10..a2bb221a40b 100644
--- a/storage/tokudb/ft-index/src/ydb.cc
+++ b/storage/tokudb/ft-index/src/ydb.cc
@@ -233,6 +233,7 @@ static DB_ENV * volatile most_recent_env; // most recently opened env, used fo
static int env_get_iname(DB_ENV* env, DBT* dname_dbt, DBT* iname_dbt);
static int toku_maybe_get_engine_status_text (char* buff, int buffsize); // for use by toku_assert
+static int toku_maybe_err_engine_status (void);
static void toku_maybe_set_env_panic(int code, const char * msg); // for use by toku_assert
int
@@ -476,7 +477,7 @@ needs_recovery (DB_ENV *env) {
static int toku_env_txn_checkpoint(DB_ENV * env, uint32_t kbyte, uint32_t min, uint32_t flags);
// Instruct db to use the default (built-in) key comparison function
-// by setting the flag bits in the db and brt structs
+// by setting the flag bits in the db and ft structs
static int
db_use_builtin_key_cmp(DB *db) {
HANDLE_PANICKED_DB(db);
@@ -852,6 +853,12 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
goto cleanup;
}
+ if (toku_os_huge_pages_enabled()) {
+ r = toku_ydb_do_error(env, TOKUDB_HUGE_PAGES_ENABLED,
+ "Huge pages are enabled, disable them before continuing\n");
+ goto cleanup;
+ }
+
most_recent_env = NULL;
assert(sizeof(time_t) == sizeof(uint64_t));
@@ -1108,7 +1115,7 @@ cleanup:
most_recent_env = env;
uint64_t num_rows;
env_get_engine_status_num_rows(env, &num_rows);
- toku_assert_set_fpointers(toku_maybe_get_engine_status_text, toku_maybe_set_env_panic, num_rows);
+ toku_assert_set_fpointers(toku_maybe_get_engine_status_text, toku_maybe_err_engine_status, toku_maybe_set_env_panic, num_rows);
}
return r;
}
@@ -1131,7 +1138,7 @@ env_close(DB_ENV * env, uint32_t flags) {
goto panic_and_quit_early;
}
if (env->i->open_dbs_by_dname) { //Verify that there are no open dbs.
- if (toku_omt_size(env->i->open_dbs_by_dname) > 0) {
+ if (env->i->open_dbs_by_dname->size() > 0) {
err_msg = "Cannot close environment due to open DBs\n";
r = toku_ydb_do_error(env, EINVAL, "%s", err_msg);
goto panic_and_quit_early;
@@ -1207,10 +1214,14 @@ env_close(DB_ENV * env, uint32_t flags) {
toku_free(env->i->real_log_dir);
if (env->i->real_tmp_dir)
toku_free(env->i->real_tmp_dir);
- if (env->i->open_dbs_by_dname)
- toku_omt_destroy(&env->i->open_dbs_by_dname);
- if (env->i->open_dbs_by_dict_id)
- toku_omt_destroy(&env->i->open_dbs_by_dict_id);
+ if (env->i->open_dbs_by_dname) {
+ env->i->open_dbs_by_dname->destroy();
+ toku_free(env->i->open_dbs_by_dname);
+ }
+ if (env->i->open_dbs_by_dict_id) {
+ env->i->open_dbs_by_dict_id->destroy();
+ toku_free(env->i->open_dbs_by_dict_id);
+ }
if (env->i->dir)
toku_free(env->i->dir);
toku_pthread_rwlock_destroy(&env->i->open_dbs_rwlock);
@@ -1834,13 +1845,15 @@ fs_get_status(DB_ENV * env, fs_redzone_state * redzone_state) {
// Local status struct used to get information from memory.c
typedef enum {
MEMORY_MALLOC_COUNT = 0,
- MEMORY_FREE_COUNT,
+ MEMORY_FREE_COUNT,
MEMORY_REALLOC_COUNT,
- MEMORY_MALLOC_FAIL,
- MEMORY_REALLOC_FAIL,
- MEMORY_REQUESTED,
- MEMORY_USED,
- MEMORY_FREED,
+ MEMORY_MALLOC_FAIL,
+ MEMORY_REALLOC_FAIL,
+ MEMORY_REQUESTED,
+ MEMORY_USED,
+ MEMORY_FREED,
+ MEMORY_MAX_REQUESTED_SIZE,
+ MEMORY_LAST_FAILED_SIZE,
MEMORY_MAX_IN_USE,
MEMORY_MALLOCATOR_VERSION,
MEMORY_MMAP_THRESHOLD,
@@ -1868,6 +1881,8 @@ memory_status_init(void) {
STATUS_INIT(MEMORY_REQUESTED, nullptr, UINT64, "number of bytes requested", TOKU_ENGINE_STATUS);
STATUS_INIT(MEMORY_USED, nullptr, UINT64, "number of bytes used (requested + overhead)", TOKU_ENGINE_STATUS);
STATUS_INIT(MEMORY_FREED, nullptr, UINT64, "number of bytes freed", TOKU_ENGINE_STATUS);
+ STATUS_INIT(MEMORY_MAX_REQUESTED_SIZE, nullptr, UINT64, "largest attempted allocation size", TOKU_ENGINE_STATUS);
+ STATUS_INIT(MEMORY_LAST_FAILED_SIZE, nullptr, UINT64, "size of the last failed allocation attempt", TOKU_ENGINE_STATUS);
STATUS_INIT(MEMORY_MAX_IN_USE, MEM_ESTIMATED_MAXIMUM_MEMORY_FOOTPRINT, UINT64, "estimated maximum memory footprint", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
STATUS_INIT(MEMORY_MALLOCATOR_VERSION, nullptr, CHARSTR, "mallocator version", TOKU_ENGINE_STATUS);
STATUS_INIT(MEMORY_MMAP_THRESHOLD, nullptr, UINT64, "mmap threshold", TOKU_ENGINE_STATUS);
@@ -2225,6 +2240,83 @@ env_get_engine_status_text(DB_ENV * env, char * buff, int bufsiz) {
return r;
}
+// prints engine status using toku_env_err line-by-line
+static int
+env_err_engine_status(DB_ENV * env) {
+ uint32_t stringsize = 1024;
+ uint64_t panic;
+ char panicstring[stringsize];
+ uint64_t num_rows;
+ uint64_t max_rows;
+ fs_redzone_state redzone_state;
+
+ toku_env_err(env, 0, "BUILD_ID = %d", BUILD_ID);
+
+ (void) env_get_engine_status_num_rows (env, &max_rows);
+ TOKU_ENGINE_STATUS_ROW_S mystat[max_rows];
+ int r = env->get_engine_status (env, mystat, max_rows, &num_rows, &redzone_state, &panic, panicstring, stringsize, TOKU_ENGINE_STATUS);
+
+ if (r) {
+ toku_env_err(env, 0, "Engine status not available: ");
+ if (!env) {
+ toku_env_err(env, 0, "no environment");
+ }
+ else if (!(env->i)) {
+ toku_env_err(env, 0, "environment internal struct is null");
+ }
+ else if (!env_opened(env)) {
+ toku_env_err(env, 0, "environment is not open");
+ }
+ }
+ else {
+ if (panic) {
+ toku_env_err(env, 0, "Env panic code: %" PRIu64, panic);
+ if (strlen(panicstring)) {
+ invariant(strlen(panicstring) <= stringsize);
+ toku_env_err(env, 0, "Env panic string: %s", panicstring);
+ }
+ }
+
+ for (uint64_t row = 0; row < num_rows; row++) {
+ switch (mystat[row].type) {
+ case FS_STATE:
+ toku_env_err(env, 0, "%s: %" PRIu64, mystat[row].legend, mystat[row].value.num);
+ break;
+ case UINT64:
+ toku_env_err(env, 0, "%s: %" PRIu64, mystat[row].legend, mystat[row].value.num);
+ break;
+ case CHARSTR:
+ toku_env_err(env, 0, "%s: %s", mystat[row].legend, mystat[row].value.str);
+ break;
+ case UNIXTIME:
+ {
+ char tbuf[26];
+ format_time((time_t*)&mystat[row].value.num, tbuf);
+ toku_env_err(env, 0, "%s: %s", mystat[row].legend, tbuf);
+ }
+ break;
+ case TOKUTIME:
+ {
+ double t = tokutime_to_seconds(mystat[row].value.num);
+ toku_env_err(env, 0, "%s: %.6f", mystat[row].legend, t);
+ }
+ break;
+ case PARCOUNT:
+ {
+ uint64_t v = read_partitioned_counter(mystat[row].value.parcount);
+ toku_env_err(env, 0, "%s: %" PRIu64, mystat[row].legend, v);
+ }
+ break;
+ default:
+ toku_env_err(env, 0, "%s: UNKNOWN STATUS TYPE: %d", mystat[row].legend, mystat[row].type);
+ break;
+ }
+ }
+ }
+
+ return r;
+}
+
// intended for use by toku_assert logic, when env is not known
static int
toku_maybe_get_engine_status_text (char * buff, int buffsize) {
@@ -2240,6 +2332,19 @@ toku_maybe_get_engine_status_text (char * buff, int buffsize) {
return r;
}
+static int
+toku_maybe_err_engine_status (void) {
+ DB_ENV * env = most_recent_env;
+ int r;
+ if (engine_status_enable && env != NULL) {
+ r = env_err_engine_status(env);
+ }
+ else {
+ r = EOPNOTSUPP;
+ }
+ return r;
+}
+
// Set panic code and panic string if not already panicked,
// intended for use by toku_assert when about to abort().
static void
@@ -2292,10 +2397,8 @@ struct ltm_iterate_requests_callback_extra {
};
static int
-find_db_by_dict_id(OMTVALUE v, void *dict_id_v) {
- DB *db = (DB *) v;
+find_db_by_dict_id(DB *const &db, const DICTIONARY_ID &dict_id_find) {
DICTIONARY_ID dict_id = db->i->dict_id;
- DICTIONARY_ID dict_id_find = *(DICTIONARY_ID *) dict_id_v;
if (dict_id.dictid < dict_id_find.dictid) {
return -1;
} else if (dict_id.dictid > dict_id_find.dictid) {
@@ -2307,10 +2410,9 @@ find_db_by_dict_id(OMTVALUE v, void *dict_id_v) {
static DB *
locked_get_db_by_dict_id(DB_ENV *env, DICTIONARY_ID dict_id) {
- OMTVALUE dbv;
- int r = toku_omt_find_zero(env->i->open_dbs_by_dict_id, find_db_by_dict_id,
- (void *) &dict_id, &dbv, nullptr);
- return r == 0 ? (DB *) dbv : nullptr;
+ DB *db;
+ int r = env->i->open_dbs_by_dict_id->find_zero<DICTIONARY_ID, find_db_by_dict_id>(dict_id, &db, nullptr);
+ return r == 0 ? db : nullptr;
}
static int ltm_iterate_requests_callback(DICTIONARY_ID dict_id, TXNID txnid,
@@ -2341,7 +2443,7 @@ env_iterate_pending_lock_requests(DB_ENV *env,
return EINVAL;
}
- toku::locktree::manager *mgr = &env->i->ltm;
+ toku::locktree_manager *mgr = &env->i->ltm;
ltm_iterate_requests_callback_extra e(env, callback, extra);
return mgr->iterate_pending_lock_requests(ltm_iterate_requests_callback, &e);
}
@@ -2460,6 +2562,17 @@ static void env_set_killed_callback(DB_ENV *env, uint64_t default_killed_time_ms
env->i->killed_callback = killed_callback;
}
+static void env_do_backtrace(DB_ENV *env) {
+ if (env->i->errcall) {
+ db_env_do_backtrace_errfunc((toku_env_err_func) toku_env_err, (const void *) env);
+ }
+ if (env->i->errfile) {
+ db_env_do_backtrace((FILE *) env->i->errfile);
+ } else {
+ db_env_do_backtrace(stderr);
+ }
+}
+
static int
toku_env_create(DB_ENV ** envp, uint32_t flags) {
int r = ENOSYS;
@@ -2536,6 +2649,7 @@ toku_env_create(DB_ENV ** envp, uint32_t flags) {
USENV(set_loader_memory_size);
USENV(get_loader_memory_size);
USENV(set_killed_callback);
+ USENV(do_backtrace);
#undef USENV
// unlocked methods
@@ -2564,18 +2678,18 @@ toku_env_create(DB_ENV ** envp, uint32_t flags) {
result->i->bt_compare = toku_builtin_compare_fun;
r = toku_logger_create(&result->i->logger);
- if (r!=0) goto cleanup; // In particular, logger_create can return the huge page error.
- assert(result->i->logger);
+ invariant_zero(r);
+ invariant_notnull(result->i->logger);
// Create the locktree manager, passing in the create/destroy/escalate callbacks.
// The extra parameter for escalation is simply a pointer to this environment.
// The escalate callback will need it to translate txnids to DB_TXNs
result->i->ltm.create(toku_db_lt_on_create_callback, toku_db_lt_on_destroy_callback, toku_db_txn_escalate_callback, result);
- r = toku_omt_create(&result->i->open_dbs_by_dname);
- assert_zero(r);
- r = toku_omt_create(&result->i->open_dbs_by_dict_id);
- assert_zero(r);
+ XMALLOC(result->i->open_dbs_by_dname);
+ result->i->open_dbs_by_dname->create();
+ XMALLOC(result->i->open_dbs_by_dict_id);
+ result->i->open_dbs_by_dict_id->create();
toku_pthread_rwlock_init(&result->i->open_dbs_rwlock, NULL);
*envp = result;
@@ -2601,9 +2715,7 @@ DB_ENV_CREATE_FUN (DB_ENV ** envp, uint32_t flags) {
// return <0 if v is earlier in omt than dbv
// return >0 if v is later in omt than dbv
static int
-find_db_by_db_dname(OMTVALUE v, void *dbv) {
- DB *db = (DB *) v; // DB* that is stored in the omt
- DB *dbfind = (DB *) dbv; // extra, to be compared to v
+find_db_by_db_dname(DB *const &db, DB *const &dbfind) {
int cmp;
const char *dname = db->i->dname;
const char *dnamefind = dbfind->i->dname;
@@ -2615,9 +2727,7 @@ find_db_by_db_dname(OMTVALUE v, void *dbv) {
}
static int
-find_db_by_db_dict_id(OMTVALUE v, void *dbv) {
- DB *db = (DB *) v;
- DB *dbfind = (DB *) dbv;
+find_db_by_db_dict_id(DB *const &db, DB *const &dbfind) {
DICTIONARY_ID dict_id = db->i->dict_id;
DICTIONARY_ID dict_id_find = dbfind->i->dict_id;
if (dict_id.dictid < dict_id_find.dictid) {
@@ -2640,20 +2750,18 @@ env_note_db_opened(DB_ENV *env, DB *db) {
assert(db->i->dname); // internal (non-user) dictionary has no dname
int r;
- OMTVALUE v;
uint32_t idx;
- r = toku_omt_find_zero(env->i->open_dbs_by_dname, find_db_by_db_dname,
- db, &v, &idx);
+
+ r = env->i->open_dbs_by_dname->find_zero<DB *, find_db_by_db_dname>(db, nullptr, &idx);
assert(r == DB_NOTFOUND);
- r = toku_omt_insert_at(env->i->open_dbs_by_dname, db, idx);
+ r = env->i->open_dbs_by_dname->insert_at(db, idx);
assert_zero(r);
- r = toku_omt_find_zero(env->i->open_dbs_by_dict_id, find_db_by_db_dict_id,
- db, &v, &idx);
+ r = env->i->open_dbs_by_dict_id->find_zero<DB *, find_db_by_db_dict_id>(db, nullptr, &idx);
assert(r == DB_NOTFOUND);
- r = toku_omt_insert_at(env->i->open_dbs_by_dict_id, db, idx);
+ r = env->i->open_dbs_by_dict_id->insert_at(db, idx);
assert_zero(r);
- STATUS_VALUE(YDB_LAYER_NUM_OPEN_DBS) = toku_omt_size(env->i->open_dbs_by_dname);
+ STATUS_VALUE(YDB_LAYER_NUM_OPEN_DBS) = env->i->open_dbs_by_dname->size();
STATUS_VALUE(YDB_LAYER_NUM_DB_OPEN)++;
if (STATUS_VALUE(YDB_LAYER_NUM_OPEN_DBS) > STATUS_VALUE(YDB_LAYER_MAX_OPEN_DBS)) {
STATUS_VALUE(YDB_LAYER_MAX_OPEN_DBS) = STATUS_VALUE(YDB_LAYER_NUM_OPEN_DBS);
@@ -2666,58 +2774,44 @@ void
env_note_db_closed(DB_ENV *env, DB *db) {
toku_pthread_rwlock_wrlock(&env->i->open_dbs_rwlock);
assert(db->i->dname); // internal (non-user) dictionary has no dname
- assert(toku_omt_size(env->i->open_dbs_by_dname) > 0);
- assert(toku_omt_size(env->i->open_dbs_by_dict_id) > 0);
+ assert(env->i->open_dbs_by_dname->size() > 0);
+ assert(env->i->open_dbs_by_dict_id->size() > 0);
int r;
- OMTVALUE v;
uint32_t idx;
- r = toku_omt_find_zero(env->i->open_dbs_by_dname, find_db_by_db_dname,
- db, &v, &idx);
+
+ r = env->i->open_dbs_by_dname->find_zero<DB *, find_db_by_db_dname>(db, nullptr, &idx);
assert_zero(r);
- r = toku_omt_delete_at(env->i->open_dbs_by_dname, idx);
+ r = env->i->open_dbs_by_dname->delete_at(idx);
assert_zero(r);
- r = toku_omt_find_zero(env->i->open_dbs_by_dict_id, find_db_by_db_dict_id,
- db, &v, &idx);
+ r = env->i->open_dbs_by_dict_id->find_zero<DB *, find_db_by_db_dict_id>(db, nullptr, &idx);
assert_zero(r);
- r = toku_omt_delete_at(env->i->open_dbs_by_dict_id, idx);
+ r = env->i->open_dbs_by_dict_id->delete_at(idx);
assert_zero(r);
STATUS_VALUE(YDB_LAYER_NUM_DB_CLOSE)++;
- STATUS_VALUE(YDB_LAYER_NUM_OPEN_DBS) = toku_omt_size(env->i->open_dbs_by_dname);
+ STATUS_VALUE(YDB_LAYER_NUM_OPEN_DBS) = env->i->open_dbs_by_dname->size();
toku_pthread_rwlock_wrunlock(&env->i->open_dbs_rwlock);
}
static int
-find_open_db_by_dname (OMTVALUE v, void *dnamev) {
- DB *db = (DB *) v; // DB* that is stored in the omt
- int cmp;
- const char *dname = db->i->dname;
- const char *dnamefind = (char *) dnamev;
- cmp = strcmp(dname, dnamefind);
- return cmp;
+find_open_db_by_dname(DB *const &db, const char *const &dnamefind) {
+ return strcmp(db->i->dname, dnamefind);
}
// return true if there is any db open with the given dname
static bool
env_is_db_with_dname_open(DB_ENV *env, const char *dname) {
- int r;
- bool rval;
- OMTVALUE dbv;
- uint32_t idx;
+ DB *db;
toku_pthread_rwlock_rdlock(&env->i->open_dbs_rwlock);
- r = toku_omt_find_zero(env->i->open_dbs_by_dname, find_open_db_by_dname, (void*)dname, &dbv, &idx);
- if (r==0) {
- DB *db = (DB *) dbv;
- assert(strcmp(dname, db->i->dname) == 0);
- rval = true;
- }
- else {
- assert(r==DB_NOTFOUND);
- rval = false;
+ int r = env->i->open_dbs_by_dname->find_zero<const char *, find_open_db_by_dname>(dname, &db, nullptr);
+ if (r == 0) {
+ invariant(strcmp(dname, db->i->dname) == 0);
+ } else {
+ invariant(r == DB_NOTFOUND);
}
toku_pthread_rwlock_rdunlock(&env->i->open_dbs_rwlock);
- return rval;
+ return r == 0 ? true : false;
}
//We do not (yet?) support deleting subdbs by deleting the enclosing 'fname'
@@ -3029,7 +3123,7 @@ env_get_iname(DB_ENV* env, DBT* dname_dbt, DBT* iname_dbt) {
// TODO 2216: Patch out this (dangerous) function when loader is working and
// we don't need to test the low-level redirect anymore.
-// for use by test programs only, just a wrapper around brt call:
+// for use by test programs only, just a wrapper around ft call:
int
toku_test_db_redirect_dictionary(DB * db, const char * dname_of_new_file, DB_TXN *dbtxn) {
int r;
@@ -3037,7 +3131,7 @@ toku_test_db_redirect_dictionary(DB * db, const char * dname_of_new_file, DB_TXN
DBT iname_dbt;
char * new_iname_in_env;
- FT_HANDLE brt = db->i->ft_handle;
+ FT_HANDLE ft_handle = db->i->ft_handle;
TOKUTXN tokutxn = db_txn_struct_i(dbtxn)->tokutxn;
toku_fill_dbt(&dname_dbt, dname_of_new_file, strlen(dname_of_new_file)+1);
@@ -3047,7 +3141,7 @@ toku_test_db_redirect_dictionary(DB * db, const char * dname_of_new_file, DB_TXN
new_iname_in_env = (char *) iname_dbt.data;
toku_multi_operation_client_lock(); //Must hold MO lock for dictionary_redirect.
- r = toku_dictionary_redirect(new_iname_in_env, brt, tokutxn);
+ r = toku_dictionary_redirect(new_iname_in_env, ft_handle, tokutxn);
toku_multi_operation_client_unlock();
toku_free(new_iname_in_env);