Commit ee8724e7 authored by Barry Perlman's avatar Barry Perlman Committed by Yoni Fogel

[t:3028] Merge from tokudb.3028 with command svn merge -r25427:HEAD ../tokudb.3028 .

Add engine status on failed assert.  Also add panic info to log status in preparation for making available via engine status.

git-svn-id: file:///svn/toku/tokudb@25469 c7de825b-a66e-492c-adef-691d508d4ae1
parent ab102ae7
......@@ -1355,11 +1355,15 @@ toku_logger_get_status(TOKULOGGER logger, LOGGER_STATUS s) {
s->ilock_ctr = logger->input_lock_ctr;
s->olock_ctr = logger->output_condition_lock_ctr;
s->swap_ctr = logger->swap_ctr;
s->panicked = logger->is_panicked;
s->panic_errno = logger->panic_errno;
}
else {
s->ilock_ctr = 0;
s->olock_ctr = 0;
s->swap_ctr = 0;
s->panicked = 0;
s->panic_errno = 0;
}
}
......
......@@ -168,6 +168,8 @@ typedef struct logger_status {
u_int64_t ilock_ctr;
u_int64_t olock_ctr;
u_int64_t swap_ctr;
u_int64_t panicked;
u_int64_t panic_errno;
} LOGGER_STATUS_S, *LOGGER_STATUS;
void toku_logger_get_status(TOKULOGGER logger, LOGGER_STATUS s);
......
......@@ -55,7 +55,20 @@ static u_int64_t num_sequential_queries;
static u_int64_t logsuppress; // number of times logs are suppressed for empty table (2440)
static u_int64_t logsuppressfail; // number of times unable to suppress logs for empty table (2440)
static time_t startuptime; // timestamp of system startup
static DB_ENV * most_recent_env; // most recently opened env, used for engine status on crash
static void
init_status_info(void) {
num_inserts = 0;
num_inserts_fail = 0;
num_deletes = 0;
num_deletes_fail = 0;
num_point_queries = 0;
num_sequential_queries = 0;
logsuppress = 0;
logsuppressfail = 0;
startuptime = time(NULL);
}
const char * environmentdictionary = "tokudb.environment";
const char * fileopsdirectory = "tokudb.directory";
......@@ -114,7 +127,6 @@ ydb_set_brt(DB *db, BRT brt) {
int
toku_ydb_init(void) {
int r = 0;
startuptime = time(NULL);
//Lower level must be initialized first.
if (r==0)
r = toku_brt_init(toku_ydb_lock, toku_ydb_unlock, ydb_set_brt);
......@@ -759,6 +771,8 @@ toku_env_open(DB_ENV * env, const char *home, u_int32_t flags, int mode) {
need_rollback_cachefile = TRUE;
}
init_status_info(); // do this before possibly upgrading, so upgrade work is counted in status counters
LSN last_lsn_of_clean_shutdown_read_from_log = ZERO_LSN;
BOOL upgrade_in_progress = FALSE;
r = ydb_maybe_upgrade_env(env, &last_lsn_of_clean_shutdown_read_from_log, &upgrade_in_progress);
......@@ -911,8 +925,10 @@ toku_env_open(DB_ENV * env, const char *home, u_int32_t flags, int mode) {
unlock_single_process(env);
}
}
if (r == 0)
if (r == 0) {
errno = 0; // tabula rasa
most_recent_env = env;
}
return r;
}
......@@ -1624,11 +1640,14 @@ format_time(const time_t *timer, char *buf) {
// can help diagnose the problem.
// This function only collects information, and it does not matter if something gets garbled
// because of a race condition.
// Note, engine status is still collected even if the environment or logger is panicked
static int
env_get_engine_status(DB_ENV * env, ENGINE_STATUS * engstat) {
HANDLE_PANICKED_ENV(env);
int r = 0;
if (!env_opened(env)) r = EINVAL;
if ( !(env) ||
!(env->i) ||
!(env_opened(env)) )
r = EINVAL;
else {
format_time(&persistent_creation_time, engstat->creationtime);
time_t now = time(NULL);
......@@ -1794,14 +1813,29 @@ env_get_engine_status(DB_ENV * env, ENGINE_STATUS * engstat) {
return r;
}
// Fill buff with text description of engine status up to bufsiz bytes.
// Intended for use by test programs that do not have the handlerton available.
// Intended for use by test programs that do not have the handlerton available,
// and for use by toku_assert logic to print diagnostic info on crash.
static int
env_get_engine_status_text(DB_ENV * env, char * buff, int bufsiz) {
ENGINE_STATUS engstat;
int r = env_get_engine_status(env, &engstat);
int n = 0; // number of characters printed so far
if (r) {
n += snprintf(buff + n, bufsiz - n, "Engine status not available: ");
if (!env) {
n += snprintf(buff + n, bufsiz - n, "no environment\n");
}
else if (!(env->i)) {
n += snprintf(buff + n, bufsiz - n, "environment internal struct is null\n");
}
else if (!env_opened(env)) {
n += snprintf(buff + n, bufsiz - n, "environment is not open\n");
}
}
else {
n += snprintf(buff + n, bufsiz - n, "creationtime %s \n", engstat.creationtime);
n += snprintf(buff + n, bufsiz - n, "startuptime %s \n", engstat.startuptime);
n += snprintf(buff + n, bufsiz - n, "now %s \n", engstat.now);
......@@ -1897,7 +1931,7 @@ env_get_engine_status_text(DB_ENV * env, char * buff, int bufsiz) {
n += snprintf(buff + n, bufsiz - n, "ver_at_startup %"PRIu64"\n", engstat.ver_at_startup);
n += snprintf(buff + n, bufsiz - n, "last_lsn_v12 %"PRIu64"\n", engstat.last_lsn_v12);
n += snprintf(buff + n, bufsiz - n, "upgrade_v13_time %s \n", engstat.upgrade_v13_time);
}
if (n > bufsiz) {
char * errmsg = "BUFFER TOO SMALL\n";
int len = strlen(errmsg) + 1;
......@@ -1907,6 +1941,21 @@ env_get_engine_status_text(DB_ENV * env, char * buff, int bufsiz) {
return r;
}
static int toku_maybe_get_engine_status_text (char* buff, int buffsize);
// assign value to global pointer so that other files can access via tentative definition if linked to this library (.so)
int (*toku_maybe_get_engine_status_text_p)(char* buff, int buffsize) = toku_maybe_get_engine_status_text;
// intended for use by toku_assert logic, when env is not known
static int
toku_maybe_get_engine_status_text (char * buff, int buffsize) {
DB_ENV * env = most_recent_env;
int r = env_get_engine_status_text(env, buff, buffsize);
return r;
}
static int locked_txn_begin(DB_ENV * env, DB_TXN * stxn, DB_TXN ** txn, u_int32_t flags);
static int toku_db_lt_panic(DB* db, int r);
......
......@@ -17,6 +17,8 @@
static void *backtrace_pointers[N_POINTERS];
#endif
int (*toku_maybe_get_engine_status_text_p)(char* buff, int buffsize); // tentative definition: if linked to ydb, will have non-zero value
void (*do_assert_hook)(void) = NULL;
static void toku_do_backtrace_abort(void) __attribute__((noreturn));
......@@ -33,6 +35,19 @@ toku_do_backtrace_abort(void) {
fflush(stderr);
if (toku_maybe_get_engine_status_text_p) {
int r;
int buffsize = 1024 * 32;
char buff[buffsize];
r = toku_maybe_get_engine_status_text_p(buff, buffsize);
fprintf(stderr, "Engine status:\n%s\n", buff);
}
else
fprintf(stderr, "Engine status function not available\n");
fflush(stderr);
#if TOKU_WINDOWS
//Following commented methods will not always end the process (could hang).
//They could be unacceptable for other reasons as well (popups,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment