2007-11-29 14:18:54 +00:00
|
|
|
/* -*- mode: C; c-basic-offset: 4 -*- */
|
2008-01-24 15:10:32 +00:00
|
|
|
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
|
2007-11-29 14:18:54 +00:00
|
|
|
|
2007-11-23 18:27:50 +00:00
|
|
|
/* Recover an env. The logs are in argv[1]. The new database is created in the cwd. */
|
|
|
|
|
|
|
|
// Test:
|
|
|
|
// cd ../src/tests/tmpdir
|
|
|
|
// ../../../newbrt/recover ../dir.test_log2.c.tdb
|
|
|
|
|
2007-11-23 20:36:03 +00:00
|
|
|
#include "cachetable.h"
|
|
|
|
#include "key.h"
|
2008-02-08 03:17:38 +00:00
|
|
|
#include "log-internal.h"
|
|
|
|
#include "log_header.h"
|
|
|
|
#include "toku_assert.h"
|
2008-03-12 19:40:38 +00:00
|
|
|
|
2008-02-08 03:17:38 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <stdlib.h>
|
2008-03-12 19:40:38 +00:00
|
|
|
#include <sys/file.h>
|
|
|
|
#include <sys/stat.h>
|
2008-02-08 03:17:38 +00:00
|
|
|
#include <unistd.h>
|
2007-11-23 20:36:03 +00:00
|
|
|
|
2008-03-12 19:40:38 +00:00
|
|
|
int tokudb_recover(const char *data_dir, const char *log_dir) {
|
2007-11-23 18:27:50 +00:00
|
|
|
int r;
|
2007-12-26 16:52:55 +00:00
|
|
|
int entrycount=0;
|
2007-11-23 18:27:50 +00:00
|
|
|
int n_logfiles;
|
|
|
|
char **logfiles;
|
2008-03-12 19:40:38 +00:00
|
|
|
|
|
|
|
int lockfd;
|
|
|
|
|
|
|
|
{
|
|
|
|
int namelen=strlen(data_dir);
|
|
|
|
char lockfname[namelen+20];
|
|
|
|
|
|
|
|
snprintf(lockfname, sizeof(lockfname), "%s/__recoverylock_dont_delete_me", data_dir);
|
|
|
|
lockfd = open(lockfname, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR);
|
|
|
|
if (lockfd<0) {
|
|
|
|
printf("Couldn't open %s\n", lockfname);
|
2008-03-14 11:02:28 +00:00
|
|
|
return errno;
|
2008-03-12 19:40:38 +00:00
|
|
|
}
|
|
|
|
r=flock(lockfd, LOCK_EX | LOCK_NB);
|
|
|
|
if (r!=0) {
|
|
|
|
printf("Couldn't run recovery because some other process holds the recovery lock %s\n", lockfname);
|
2008-03-14 11:02:28 +00:00
|
|
|
return errno;
|
2008-03-12 19:40:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
r = toku_logger_find_logfiles(log_dir, &n_logfiles, &logfiles);
|
2008-03-14 11:02:28 +00:00
|
|
|
if (r!=0) return r;
|
2007-11-23 18:27:50 +00:00
|
|
|
int i;
|
2008-01-11 03:09:14 +00:00
|
|
|
toku_recover_init();
|
2008-03-12 19:40:38 +00:00
|
|
|
char org_wd[1000];
|
|
|
|
{
|
|
|
|
char *wd=getcwd(org_wd, sizeof(org_wd));
|
|
|
|
assert(wd!=0);
|
|
|
|
//printf("%s:%d org_wd=\"%s\"\n", __FILE__, __LINE__, org_wd);
|
|
|
|
}
|
|
|
|
char data_wd[1000];
|
|
|
|
{
|
|
|
|
r=chdir(data_dir); assert(r==0);
|
|
|
|
char *wd=getcwd(data_wd, sizeof(data_wd));
|
|
|
|
assert(wd!=0);
|
|
|
|
//printf("%s:%d data_wd=\"%s\"\n", __FILE__, __LINE__, data_wd);
|
|
|
|
}
|
2007-11-23 18:27:50 +00:00
|
|
|
for (i=0; i<n_logfiles; i++) {
|
2007-12-22 20:56:20 +00:00
|
|
|
//fprintf(stderr, "Opening %s\n", logfiles[i]);
|
2008-03-12 19:40:38 +00:00
|
|
|
r=chdir(org_wd);
|
|
|
|
assert(r==0);
|
2007-11-23 18:27:50 +00:00
|
|
|
FILE *f = fopen(logfiles[i], "r");
|
|
|
|
struct log_entry le;
|
|
|
|
u_int32_t version;
|
2007-11-28 19:09:24 +00:00
|
|
|
r=toku_read_and_print_logmagic(f, &version);
|
2007-11-23 18:27:50 +00:00
|
|
|
assert(r==0 && version==0);
|
2008-03-12 19:40:38 +00:00
|
|
|
r=chdir(data_wd);
|
|
|
|
assert(r==0);
|
2007-11-29 18:14:40 +00:00
|
|
|
while ((r = toku_log_fread(f, &le))==0) {
|
2007-12-05 20:28:33 +00:00
|
|
|
//printf("%lld: Got cmd %c\n", le.u.commit.lsn.lsn, le.cmd);
|
2008-02-08 22:16:02 +00:00
|
|
|
logtype_dispatch_args(&le, toku_recover_);
|
2007-12-29 19:27:01 +00:00
|
|
|
entrycount++;
|
2007-11-23 18:27:50 +00:00
|
|
|
}
|
|
|
|
if (r!=EOF) {
|
|
|
|
if (r==DB_BADFORMAT) {
|
2008-01-25 21:50:07 +00:00
|
|
|
fprintf(stderr, "Bad log format at record %d\n", entrycount);
|
2008-03-14 11:02:28 +00:00
|
|
|
return r;
|
2007-11-23 18:27:50 +00:00
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Huh? %s\n", strerror(r));
|
2008-03-14 11:02:28 +00:00
|
|
|
return r;
|
2007-11-23 18:27:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(f);
|
|
|
|
}
|
2008-01-11 03:09:14 +00:00
|
|
|
toku_recover_cleanup();
|
2007-11-23 18:27:50 +00:00
|
|
|
for (i=0; i<n_logfiles; i++) {
|
|
|
|
toku_free(logfiles[i]);
|
|
|
|
}
|
|
|
|
toku_free(logfiles);
|
2008-03-12 19:40:38 +00:00
|
|
|
|
|
|
|
r=flock(lockfd, LOCK_UN);
|
2008-03-14 11:02:28 +00:00
|
|
|
if (r!=0) return errno;
|
|
|
|
|
|
|
|
r=chdir(org_wd);
|
|
|
|
if (r!=0) return errno;
|
2008-03-12 19:40:38 +00:00
|
|
|
|
|
|
|
//printf("%s:%d recovery successful! ls -l says\n", __FILE__, __LINE__);
|
|
|
|
//system("ls -l");
|
2007-11-23 18:27:50 +00:00
|
|
|
return 0;
|
|
|
|
}
|