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