Commit f44c0b8a authored by Rich Prohaska's avatar Rich Prohaska Committed by Yoni Fogel

merge tokudb.1960.recovery to main close[t:1950]

git-svn-id: file:///svn/toku/tokudb@14160 c7de825b-a66e-492c-adef-691d508d4ae1
parent 52b0848d
......@@ -173,12 +173,10 @@ int toku_logger_close(TOKULOGGER *loggerp) {
int toku_logger_shutdown(TOKULOGGER logger) {
int r = 0;
// TODO: checkpoint?
// log a shutdown
if (logger->is_open)
r = toku_log_shutdown(logger, NULL, TRUE, 0);
if (logger->is_open) {
if (toku_omt_size(logger->live_txns) == 0)
r = toku_log_shutdown(logger, NULL, TRUE, 0);
}
return r;
}
......
......@@ -493,9 +493,9 @@ static int toku_delete_rolltmp_files (const char *log_dir) {
}
// Does this log environment need recovery?
// Effects: If there are no log files, or if there is a "null" checkpoint at the end of the log,
// or if there is a shutdown at the end of the log, then we don't need recovery to run.
// Returns: TRUE if it does, FALSE if it does not
// Effects: If there are no log files, or if there is a "null" checkpoint at the end of the log,
// then we don't need recovery to run. We skip the optional shutdown log entry.
// Returns: TRUE if we need recovery, FALSE if we do not need recovery.
static int tokudb_needs_recovery(const char *log_dir) {
int needs_recovery;
int r;
......@@ -515,7 +515,10 @@ static int tokudb_needs_recovery(const char *log_dir) {
needs_recovery = TRUE; goto exit;
}
if (le->cmd == LT_shutdown) {
needs_recovery = FALSE; goto exit;
r = toku_logcursor_prev(logcursor, &le);
if (r != 0) {
needs_recovery = TRUE; goto exit;
}
}
if (le->cmd != LT_end_checkpoint) {
needs_recovery = TRUE; goto exit;
......
/* Transaction consistency:
* fork a process:
* Open two tables, T1 and T2
* begin transaction
* store A in T1
* Open two tables, A and B
* begin transaction U
* begin transaction V
* store U.A into A using U
* store V.B into B using V
* checkpoint
* store B in T2
* commit (or abort)
* signal to end the process abruptly
* store U.C into A using U
* store V.D into B using V
* commit U
* maybe commit V
* abort the process abruptly
* wait for the process to finish
* open the environment doing recovery
* check to see if both A and B are present (or absent)
* check to see if both rows are present in A and maybe present in B
*/
#include <sys/stat.h>
#include <sys/wait.h>
......@@ -19,7 +23,6 @@ const int envflags = DB_INIT_MPOOL|DB_CREATE|DB_THREAD |DB_INIT_LOCK|DB_INIT_LOG
char *namea="a.db";
char *nameb="b.db";
static void
put (DB_TXN *txn, DB *db, char *key, char *data) {
DBT k = {.data = key, .size=1+strlen(key) };
......@@ -28,10 +31,8 @@ put (DB_TXN *txn, DB *db, char *key, char *data) {
CKERR(r);
}
static void
do_x2_shutdown (BOOL do_commit)
{
do_x2_shutdown (BOOL do_commit) {
int r;
system("rm -rf " ENVDIR);
toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
......@@ -74,8 +75,7 @@ checkcurs (DBC *curs, int cursflags, char *key, char *val, BOOL expect_it) {
}
static void
do_x1_recover (BOOL did_commit)
{
do_x2_recover (BOOL did_commit) {
DB_ENV *env;
int r;
r = db_env_create(&env, 0); CKERR(r);
......@@ -115,8 +115,7 @@ do_x1_recover (BOOL did_commit)
const char *cmd;
static void
do_test_internal (BOOL commit)
{
do_test_internal (BOOL commit) {
pid_t pid;
if (0 == (pid=fork())) {
int r=execl(cmd, verbose ? "-v" : "-q", commit ? "--commit" : "--abort", NULL);
......@@ -157,7 +156,7 @@ do_test (void) {
BOOL do_commit=FALSE, do_abort=FALSE, do_recover_committed=FALSE, do_recover_aborted=FALSE;
static void
x1_parse_args (int argc, char *argv[]) {
x2_parse_args (int argc, char *argv[]) {
int resultcode;
cmd = argv[0];
argc--; argv++;
......@@ -192,7 +191,7 @@ x1_parse_args (int argc, char *argv[]) {
int n_specified=0;
if (do_commit) n_specified++;
if (do_abort) n_specified++;
if (do_recover_committed) n_specified++;
if (do_recover_committed) n_specified++;
if (do_recover_aborted) n_specified++;
if (n_specified>1) {
printf("Specify only one of --commit or --abort or --recover-committed or --recover-aborted\n");
......@@ -203,17 +202,16 @@ x1_parse_args (int argc, char *argv[]) {
}
int
test_main (int argc, char *argv[])
{
x1_parse_args(argc, argv);
test_main (int argc, char *argv[]) {
x2_parse_args(argc, argv);
if (do_commit) {
do_x2_shutdown (TRUE);
} else if (do_abort) {
do_x2_shutdown (FALSE);
} else if (do_recover_committed) {
do_x1_recover(TRUE);
do_x2_recover(TRUE);
} else if (do_recover_aborted) {
do_x1_recover(FALSE);
do_x2_recover(FALSE);
} else {
do_test();
}
......
......@@ -451,6 +451,20 @@ static int toku_env_close(DB_ENV * env, u_int32_t flags) {
if (env->i->cachetable) {
toku_ydb_unlock(); // ydb lock must not be held when shutting down minicron
toku_cachetable_minicron_shutdown(env->i->cachetable);
if (env->i->logger) {
#if 0
// TODO lock problems (see test_db_remove.c). may want to require an environment.
r0 = toku_checkpoint(env->i->cachetable, env->i->logger, NULL, NULL, NULL);
assert(r0 == 0);
#else
// TODO locks?
r0 = toku_cachetable_begin_checkpoint(env->i->cachetable, env->i->logger);
if (r0 == 0)
toku_cachetable_end_checkpoint(env->i->cachetable, env->i->logger, NULL);
assert(r0 == 0);
#endif
r0 = toku_logger_shutdown(env->i->logger); assert(r0 == 0);
}
toku_ydb_lock();
r0=toku_cachetable_close(&env->i->cachetable);
if (r0) {
......@@ -458,8 +472,6 @@ static int toku_env_close(DB_ENV * env, u_int32_t flags) {
}
}
if (env->i->logger) {
r1=toku_logger_shutdown(env->i->logger);
// TODO: check return
r1=toku_logger_close(&env->i->logger);
if (r0==0 && r1) {
toku_ydb_do_error(env, r0, "Cannot close environment (logger close error)\n");
......
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