Commit 8dbeb009 authored by Dave Wells's avatar Dave Wells Committed by Yoni Fogel

fixes [t:2426], addresses [t:2444] in logger.c

git-svn-id: file:///svn/toku/tokudb@18323 c7de825b-a66e-492c-adef-691d508d4ae1
parent a1eb0c57
...@@ -169,7 +169,7 @@ static int lc_create(TOKULOGCURSOR *lc, const char *log_dir) { ...@@ -169,7 +169,7 @@ static int lc_create(TOKULOGCURSOR *lc, const char *log_dir) {
return failresult; return failresult;
} }
static int lc_scan_from_beginning_of_file_to_find_last(TOKULOGCURSOR lc); static int lc_fix_bad_logfile(TOKULOGCURSOR lc);
int toku_logcursor_create(TOKULOGCURSOR *lc, const char *log_dir) { int toku_logcursor_create(TOKULOGCURSOR *lc, const char *log_dir) {
TOKULOGCURSOR cursor; TOKULOGCURSOR cursor;
...@@ -405,8 +405,13 @@ int toku_logcursor_last(TOKULOGCURSOR lc, struct log_entry **le) { ...@@ -405,8 +405,13 @@ int toku_logcursor_last(TOKULOGCURSOR lc, struct log_entry **le) {
// got an error, // got an error,
// probably a corrupted last log entry due to a crash // probably a corrupted last log entry due to a crash
// try scanning forward from the beginning to find the last good entry // try scanning forward from the beginning to find the last good entry
r = lc_scan_from_beginning_of_file_to_find_last(lc); time_t tnow = time(NULL);
assert(r==0); fprintf(stderr, "%.24s Tokudb recovery repairing log\n", ctime(&tnow));
r = lc_fix_bad_logfile(lc);
if ( r != 0 ) {
fprintf(stderr, "%.24s Tokudb recovery repair unsuccessful\n", ctime(&tnow));
return DB_BADFORMAT;
}
// try reading again // try reading again
r = toku_log_fread_backward(lc->cur_fp, &(lc->entry)); r = toku_log_fread_backward(lc->cur_fp, &(lc->entry));
if (r==0) // got a good entry if (r==0) // got a good entry
...@@ -445,17 +450,18 @@ toku_logcursor_log_exists(const TOKULOGCURSOR lc) { ...@@ -445,17 +450,18 @@ toku_logcursor_log_exists(const TOKULOGCURSOR lc) {
return r; return r;
} }
// return a logcursor with the cur_fp pointing to the end of the last good entry // fix a logfile with a bad last entry
static int lc_scan_from_beginning_of_file_to_find_last(TOKULOGCURSOR lc) { // - return with fp pointing to end-of-file so that toku_logcursor_last can be retried
static int lc_fix_bad_logfile(TOKULOGCURSOR lc) {
struct log_entry le; struct log_entry le;
unsigned int version=0; unsigned int version=0;
int r = 0; int r = 0;
r = fseek(lc->cur_fp, 0, SEEK_SET); assert(r==0); r = fseek(lc->cur_fp, 0, SEEK_SET); if ( r!=0 ) return r;
r = toku_read_logmagic(lc->cur_fp, &version); assert(r==0); r = toku_read_logmagic(lc->cur_fp, &version); if ( r!=0 ) return r;
fpos_t last_good_pos; off_t last_good_pos;
r = fgetpos(lc->cur_fp, &last_good_pos); assert(r==0); last_good_pos = ftello(lc->cur_fp);
while (1) { while (1) {
if ( lc->entry_valid ) { if ( lc->entry_valid ) {
toku_log_free_log_entry_resources(&le); toku_log_free_log_entry_resources(&le);
...@@ -463,10 +469,16 @@ static int lc_scan_from_beginning_of_file_to_find_last(TOKULOGCURSOR lc) { ...@@ -463,10 +469,16 @@ static int lc_scan_from_beginning_of_file_to_find_last(TOKULOGCURSOR lc) {
} }
r = toku_log_fread(lc->cur_fp, &le); r = toku_log_fread(lc->cur_fp, &le);
if ( r!=0 ) break; if ( r!=0 ) break;
r = fgetpos(lc->cur_fp, &last_good_pos); assert(r==0); last_good_pos = ftello(lc->cur_fp);
} }
// now have position of last good entry - set cur_fp and return // now have position of last good entry
r = fsetpos(lc->cur_fp, &last_good_pos); assert(r==0); // 1) close the file
// 2) truncate the file to remove the error
// 3) reopen the file
// 4) set the pos to last
r = lc_close_cur_logfile(lc); if ( r!=0 ) return r;
r = truncate(lc->logfiles[lc->n_logfiles - 1], last_good_pos); if ( r!=0 ) return r;
r = lc_open_logfile(lc, lc->n_logfiles-1); if ( r!=0 ) return r;
r = fseek(lc->cur_fp, 0, SEEK_END); if ( r!=0 ) return r;
return 0; return 0;
} }
...@@ -124,7 +124,10 @@ int toku_logger_close(TOKULOGGER *loggerp) { ...@@ -124,7 +124,10 @@ int toku_logger_close(TOKULOGGER *loggerp) {
grab_output(logger, &fsynced_lsn); grab_output(logger, &fsynced_lsn);
r = toku_logger_write_buffer(logger, &fsynced_lsn); if (r!=0) goto panic; //Releases the input lock r = toku_logger_write_buffer(logger, &fsynced_lsn); if (r!=0) goto panic; //Releases the input lock
if (logger->fd!=-1) { if (logger->fd!=-1) {
r = close(logger->fd); if (r!=0) { r=errno; goto panic; } if ( logger->write_log_files ) {
r = toku_file_fsync_without_accounting(logger->fd); if (r!=0) { r=errno; goto panic; }
}
r = close(logger->fd); if (r!=0) { r=errno; goto panic; }
} }
logger->fd=-1; logger->fd=-1;
release_output(logger, fsynced_lsn); release_output(logger, fsynced_lsn);
...@@ -629,11 +632,18 @@ int toku_logger_restart(TOKULOGGER logger, LSN lastlsn) ...@@ -629,11 +632,18 @@ int toku_logger_restart(TOKULOGGER logger, LSN lastlsn)
// flush out the log buffer // flush out the log buffer
LSN fsynced_lsn; LSN fsynced_lsn;
grab_output(logger, &fsynced_lsn); grab_output(logger, &fsynced_lsn);
r = ml_lock(&logger->input_lock); assert(r == 0); r = ml_lock(&logger->input_lock); assert(r == 0);
r = toku_logger_write_buffer(logger, &fsynced_lsn); assert(r == 0); r = toku_logger_write_buffer(logger, &fsynced_lsn); assert(r == 0);
// close the log file // close the log file
r = close(logger->fd); assert(r == 0); if ( logger->write_log_files) { // fsyncs don't work to /dev/null
r = toku_file_fsync_without_accounting(logger->fd);
if ( r!=0 ) {
toku_logger_panic(logger, r);
return r;
}
}
r = close(logger->fd); assert(r == 0);
logger->fd = -1; logger->fd = -1;
// reset the LSN's to the lastlsn when the logger was opened // reset the LSN's to the lastlsn when the logger was opened
......
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