Implemented "LOG_TO_MEMORY", which mostly works (linear hash NTA goes into an infinite loop....)

This commit is contained in:
Sears Russell 2006-04-07 03:40:40 +00:00
parent 1c979f3052
commit d3d7f2c788
12 changed files with 165 additions and 64 deletions

View file

@ -86,11 +86,15 @@ typedef struct {
#define LOG_TO_FILE 0
#define LOG_TO_MEMORY 1
extern int loggerType;
int LogInit(int logType);
int LogDeinit();
void LogForce(lsn_t lsn);
void LogTruncate(lsn_t lsn);
lsn_t LogTruncationPoint();
@ -140,4 +144,9 @@ lsn_t LogCLR(int xid, lsn_t LSN, recordid rid, lsn_t prevLSN);
*/
void LogEnd (TransactionLog * l);
/**
(For internal use only..)
*/
void genericLogWrite(LogEntry * e);
#endif

View file

@ -6,7 +6,7 @@ lib_LIBRARIES=liblladd.a
liblladd_a_SOURCES=crc32.c common.c stats.c io.c bufferManager.c linkedlist.c operations.c \
pageFile.c pageCache.c page.c blobManager.c recovery2.c transactional2.c \
lockManager.c iterator.c consumer.c arrayCollection.c ringbuffer.c fifo.c multiplexer.c graph.c\
logger/logEntry.c logger/logWriter.c logger/logHandle.c logger/logger2.c \
logger/logEntry.c logger/logWriter.c logger/inMemoryLog.c logger/logHandle.c logger/logger2.c \
logger/logMemory.c \
page/slotted.c page/header.c page/fixed.c compensations.c \
operations/pageOperations.c page/indirect.c operations/decrement.c \

View file

@ -122,7 +122,14 @@ LogEntry * previousInTransaction(LogHandle * h) {
readLSNEntry return it explicitly.)
*/
static void set_offsets(LogHandle * h, LogEntry * e, lsn_t lastRead) {
h->next_offset = lastRead + sizeofLogEntry(e)+sizeof(lsn_t);
if(loggerType == LOG_TO_FILE) {
h->next_offset = lastRead + sizeofLogEntry(e)+sizeof(lsn_t);
} else if(loggerType == LOG_TO_MEMORY) {
h->next_offset = lastRead + 1;
} else {
abort();
}
h->prev_offset = (e->type==CLRLOG) ? e->contents.clr.undoNextLSN : e->prevLSN ;
}

View file

@ -45,23 +45,28 @@ terms specified in this license.
#include <lladd/logger/logger2.h>
#include "logWriter.h"
#include "inMemoryLog.h"
#include "page.h"
/*#include <lladd/bufferManager.h>*/
#include <stdio.h>
#include <assert.h>
static int loggerType = -1;
int loggerType = LOG_TO_FILE; //MEMORY;
static void genericLogWrite(LogEntry * e) {
void genericLogWrite(LogEntry * e) {
assert(loggerType != -1); // Otherwise, we haven't been initialized.
if(loggerType == LOG_TO_FILE) {
writeLogEntry(e);
} else if (loggerType == LOG_TO_MEMORY) {
writeLogEntry_InMemoryLog(e);
}
}
int LogInit(int logType) {
if(LOG_TO_FILE == logType) {
openLogWriter();
} else if(LOG_TO_MEMORY == logType) {
open_InMemoryLog();
} else {
return -1;
}
@ -73,6 +78,8 @@ int LogDeinit() {
assert(loggerType != -1);
if(LOG_TO_FILE == loggerType) {
closeLogWriter();
} else if(LOG_TO_MEMORY == loggerType) {
close_InMemoryLog();
}
return 0;
}
@ -83,13 +90,21 @@ void LogForce(lsn_t lsn) {
if(flushedLSN() < lsn) {
syncLog();
}
assert(flushedLSN() >= lsn);
} else if(LOG_TO_MEMORY == loggerType) {
assert(flushedLSN_InMemoryLog() >= lsn);
}
}
void LogTruncate(lsn_t lsn) {
truncateLog(lsn);
}
lsn_t LogTruncationPoint() {
assert(loggerType != -1);
if(LOG_TO_FILE == loggerType) {
return firstLogEntry();
} else if(LOG_TO_MEMORY == loggerType) {
return firstLogEntry_InMemoryLog();
}
abort();
}
@ -97,7 +112,9 @@ LogEntry * LogReadLSN(lsn_t lsn) {
assert(loggerType != -1);
if(LOG_TO_FILE == loggerType) {
return readLSNEntry(lsn);
}
} else if(LOG_TO_MEMORY == loggerType) {
return readLSNEntry_InMemoryLog(lsn);
}
abort();
}
@ -190,6 +207,8 @@ lsn_t LogTransCommit(TransactionLog * l) {
assert(loggerType != -1);
if(LOG_TO_FILE == loggerType) {
return LogTransBundledCommit(l);
} else if(LOG_TO_MEMORY == loggerType) {
return LogTransCommon(l, XCOMMIT);
}
abort();
}

View file

@ -99,7 +99,7 @@ int Tinit() {
bufInit();
LogInit(LOG_TO_FILE);
LogInit(loggerType);
try_ret(compensation_error()) {
pageOperationsInit();

View file

@ -44,6 +44,7 @@ terms specified in this license.
/*#include <assert.h> */
#include <lladd/transactional.h>
#include <lladd/logger/logger2.h>
#include "../../src/lladd/logger/logWriter.h"
#include "../check_includes.h"
#include <assert.h>
@ -552,7 +553,7 @@ Suite * check_suite(void) {
TCase *tc = tcase_create("recovery");
tcase_set_timeout(tc, 0); // disable timeouts
if(LOG_TO_MEMORY != loggerType) {
/* void * foobar; */ /* used to supress warnings. */
/* Sub tests are added, one per line, here */
tcase_add_test(tc, recoverBlob__idempotent);
@ -569,7 +570,7 @@ Suite * check_suite(void) {
tcase_add_test(tc, recoverBlob__crash);
tcase_add_test(tc, recoverBlob__multiple_xacts);
/*foobar = (void*)&recoverBlob__multiple_xacts; */
}
/* --------------------------------------------- */
tcase_add_checked_fixture(tc, setup, teardown);
suite_add_tcase(s, tc);

View file

@ -42,6 +42,8 @@ void initializePages() {
writeRecord(1, p, 1, rid, &i);
p->LSN = 0;
*lsn_ptr(p) = 0;
releasePage(p);
}
@ -72,6 +74,8 @@ void * workerThread(void * p) {
assert(rid.page == k);
p->LSN = 0;
*lsn_ptr(p) = 0;
releasePage(p);
assert(k == j);
@ -90,6 +94,8 @@ void * workerThreadWriting(void * q) {
pthread_mutex_lock(&ralloc_mutex);
rids[i] = slottedPreRalloc(1, sizeof(int), &tmp);
slottedPostRalloc(-1, tmp, 1, rids[i]);
tmp->LSN = 0;
*lsn_ptr(tmp) = 0;
releasePage(tmp);
pthread_mutex_unlock(&ralloc_mutex);
@ -122,6 +128,8 @@ void * workerThreadWriting(void * q) {
writeRecord(1, p, 0, rids[i], &val);
assert(p->id == rids[i].page);
p->LSN = 0;
*lsn_ptr(p) = 0;
releasePage(p);
if(! (i % 100) ) {
@ -139,6 +147,8 @@ void * workerThreadWriting(void * q) {
readRecord(1, p, rids[i], &val);
p->LSN = 0;
*lsn_ptr(p) = 0;
releasePage(p);
if(! (i % 100) ) {

View file

@ -46,7 +46,8 @@ terms specified in this license.
#include <lladd/transactional.h>
/*#include <lladd/logger/logEntry.h> */
#include "../../src/lladd/logger/logHandle.h"
#include "../../src/lladd/logger/logWriter.h"
#include <lladd/logger/logger2.h>
//#include "../../src/lladd/logger/logWriter.h"
#include "../../src/lladd/latches.h"
#include <sched.h>
@ -57,15 +58,20 @@ terms specified in this license.
#define LOG_NAME "check_logWriter.log"
static int logType = LOG_TO_MEMORY;
static void setup_log() {
int i;
lsn_t prevLSN = -1;
int xid = 100;
int xid = 42;
Tinit();
LogDeinit();
deleteLogWriter();
openLogWriter();
// openLogWriter();
LogInit(logType);
for(i = 0 ; i < 1000; i++) {
LogEntry * e = allocCommonLogEntry(prevLSN, xid, XBEGIN);
@ -79,10 +85,11 @@ static void setup_log() {
rid.slot = 0;
rid.size = sizeof(unsigned long);
writeLogEntry(e);
genericLogWrite(e);
prevLSN = e->LSN;
f = readLSNEntry(prevLSN);
f = LogReadLSN(prevLSN);
fail_unless(sizeofLogEntry(e) == sizeofLogEntry(f), "Log entry changed size!!");
fail_unless(0 == memcmp(e,f,sizeofLogEntry(e)), "Log entries did not agree!!");
@ -90,16 +97,20 @@ static void setup_log() {
free (f);
e = allocUpdateLogEntry(prevLSN, xid, 1, rid, args, args_size, (byte*) &preImage);
writeLogEntry(e);
prevLSN = e->prevLSN;
f = allocCLRLogEntry(100, 1, 200, rid, prevLSN);
prevLSN = f->prevLSN;
writeLogEntry(f);
genericLogWrite(e);
prevLSN = e->prevLSN;
f = allocCLRLogEntry(100, 1, 200, rid, 0); //prevLSN);
genericLogWrite(f);
assert (f->type == CLRLOG);
prevLSN = f->LSN;
free (e);
free (f);
}
}
/**
@test
@ -113,7 +124,7 @@ static void setup_log() {
In particular, logWriter checks to make sure that each log entry's
size matches the size that it recorded before the logEntry. Also,
when checking the 1000 of 3000 entries, this test uses
readLSNEntry, which tests the logWriter's ability to succesfully
LogReadLSN, which tests the logWriter's ability to succesfully
manipulate LSN's.
@todo Test logHandle more thoroughly. (Still need to test the guard mechanism.)
@ -127,16 +138,17 @@ START_TEST(logWriterTest)
setup_log();
syncLog();
closeLogWriter();
openLogWriter();
// syncLog();
//closeLogWriter();
LogDeinit();
// openLogWriter();
LogInit(logType);
h = getLogHandle();
/* readLSNEntry(sizeof(lsn_t)); */
/* LogReadLSN(sizeof(lsn_t)); */
while((e = nextInLog(&h))) {
free(e);
i++;
}
@ -144,6 +156,7 @@ START_TEST(logWriterTest)
fail_unless(i = 3000, "Wrong number of log entries!");
deleteLogWriter();
LogDeinit();
}
@ -163,19 +176,23 @@ START_TEST(logHandleColdReverseIterator) {
while(((e = nextInLog(&lh)) && (i < 100)) ) {
free(e);
i++;
}
i = 0;
lh = getLogHandle(e->LSN);
// printf("getLogHandle(%ld)\n", e->LSN);
lh = getLSNHandle(e->LSN); // was 'getLogHandle...'
while((e = previousInTransaction(&lh))) {
i++;
free(e);
}
/* printf("i = %d\n", i); */
fail_unless( i == 1 , NULL); /* The 1 is because we immediately hit a clr that goes to the beginning of the log... */
deleteLogWriter();
// assert(i == 1);
assert(i < 4); /* We should almost immediately hit a clr that goes to the beginning of the log... */
// fail_unless( i == 1 , NULL);
LogDeinit();
deleteLogWriter();
}
END_TEST
@ -208,35 +225,46 @@ START_TEST(logWriterTruncate) {
}
truncateLog(le->LSN);
// truncateLog(le->LSN);
LogTruncate(le->LSN);
tmp = readLSNEntry(le->LSN);
tmp = LogReadLSN(le->LSN);
fail_unless(NULL != tmp, NULL);
fail_unless(tmp->LSN == le->LSN, NULL);
tmp = readLSNEntry(le2->LSN);
free(tmp);
tmp = LogReadLSN(le2->LSN);
fail_unless(NULL != tmp, NULL);
fail_unless(tmp->LSN == le2->LSN, NULL);
tmp = readLSNEntry(le3->LSN);
free(tmp);
tmp = LogReadLSN(le3->LSN);
fail_unless(NULL != tmp, NULL);
fail_unless(tmp->LSN == le3->LSN, NULL);
free(tmp);
lh = getLogHandle();
i = 0;
free(le);
free(le2);
free(le3);
while((le = nextInLog(&lh))) {
i++;
free(le);
}
fail_unless(i == (3000 - 234 + 1), NULL);
assert(i == (3000 - 234 + 1));
// fail_unless(i == (3000 - 234 + 1), NULL);
LogDeinit();
} END_TEST
@ -293,7 +321,7 @@ static void* worker_thread(void * arg) {
/* DEBUG("i = %d, le = %x\n", i, (unsigned int)le); */
/* fail_unless(1, NULL); */
le->xid = i+key;
writeLogEntry(le);
genericLogWrite(le);
//printf("reportedLSN: %ld\n", le->LSN);
lsns[i] = le->LSN;
i++;
@ -302,9 +330,11 @@ static void* worker_thread(void * arg) {
pthread_mutex_lock(&random_mutex);
if(lsns[entry] > truncated_to && entry < i) {
pthread_mutex_unlock(&random_mutex);
/*printf("X %d\n", (readLSNEntry(lsns[entry])->xid == entry+key)); fflush(stdout); */
assert(readLSNEntry(lsns[entry])->xid == entry+key);
/* fail_unless(readLSNEntry(lsns[entry])->xid == entry+key, NULL); */
/*printf("X %d\n", (LogReadLSN(lsns[entry])->xid == entry+key)); fflush(stdout); */
LogEntry * e = LogReadLSN(lsns[entry]);
assert(e->xid == entry+key);
free(e);
/* fail_unless(LogReadLSN(lsns[entry])->xid == entry+key, NULL); */
} else {
pthread_mutex_unlock(&random_mutex);
}
@ -362,10 +392,10 @@ Suite * check_suite(void) {
tcase_set_timeout(tc, 0);
/* Sub tests are added, one per line, here */
/* tcase_add_test(tc, logWriterTest);*/
/*tcase_add_test(tc, logHandleColdReverseIterator);*/
tcase_add_test(tc, logWriterTest);
tcase_add_test(tc, logHandleColdReverseIterator);
/*tcase_add_test(tc, logWriterTruncate);*/
/*tcase_add_test(tc, logWriterCheckWorker); */
tcase_add_test(tc, logWriterCheckWorker);
tcase_add_test(tc, logWriterCheckThreaded);
/* --------------------------------------------- */

View file

@ -44,7 +44,7 @@ terms specified in this license.
#include <lladd/transactional.h>
#include "../../src/lladd/logger/logWriter.h"
#include <lladd/logger/logger2.h>
#include <lladd/bufferManager.h>
#include "../check_includes.h"
@ -239,7 +239,8 @@ START_TEST(operation_prepare) {
Tcommit(winner);
simulateBufferManagerCrash();
closeLogWriter();
// closeLogWriter();
LogDeinit();
numActiveXactions = 0;
@ -296,7 +297,8 @@ START_TEST(operation_prepare) {
Tcommit(winner);
simulateBufferManagerCrash();
closeLogWriter();
// closeLogWriter();
LogDeinit();
numActiveXactions = 0;
@ -527,7 +529,7 @@ START_TEST(operation_alloc_test) {
recordid rid2 = Talloc(xid, 100);
Tcommit(xid);
printf("rid1={%d,%d,%ld} rid2={%d,%d,%ld}\n",
printf("rid1={%d,%d,%lld} rid2={%d,%d,%lld}\n",
rid1.page, rid1.slot, rid1.size,
rid2.page, rid2.slot, rid2.size);
@ -634,7 +636,9 @@ Suite * check_suite(void) {
tcase_add_test(tc, operation_nestedTopAction);
tcase_add_test(tc, operation_instant_set);
tcase_add_test(tc, operation_set_range);
tcase_add_test(tc, operation_prepare);
if(loggerType != LOG_TO_MEMORY) {
tcase_add_test(tc, operation_prepare);
}
tcase_add_test(tc, operation_alloc_test);
tcase_add_test(tc, operation_array_list);
/* --------------------------------------------- */

View file

@ -215,6 +215,8 @@ START_TEST(pageNoThreadTest)
worker_thread(p);
unlock(p->loadlatch);
p->LSN = 0;
*lsn_ptr(p) = p->LSN;
Tdeinit();
@ -302,9 +304,17 @@ START_TEST(pageNoThreadMultPageTest)
p = loadPage(-1, 1);
slottedPageInitialize(p);
multiple_simultaneous_pages(p);
// Normally, you would call pageWriteLSN() to update the LSN. This
// is a hack, since Tdeinit() will crash if it detects page updates
// that are off the end of the log..
p->LSN = 0;
*lsn_ptr(p) = p->LSN;
releasePage(p);
/* unlock(p->loadlatch); */
Tdeinit();
}
@ -341,6 +351,8 @@ START_TEST(pageThreadTest) {
}
/* unlock(p->loadlatch); */
p->LSN = 0;
*lsn_ptr(p) = p->LSN;
releasePage(p);
Tdeinit();
@ -368,7 +380,10 @@ START_TEST(fixedPageThreadTest) {
pthread_join(workers[i], NULL);
}
p->LSN = 0;
*lsn_ptr(p) = p->LSN;
releasePage(p);
Tdeinit();
} END_TEST
START_TEST(pageCheckSlotTypeTest) {
@ -416,7 +431,8 @@ START_TEST(pageCheckSlotTypeTest) {
/** getRecordType now ignores the size field, so this (correctly) returns SLOTTED_RECORD */
bad.slot = slot.slot;
assert(getRecordType(xid, p, bad) == SLOTTED_RECORD);
p->LSN = 0;
*lsn_ptr(p) = p->LSN;
releasePage(p);
Tcommit(xid);

View file

@ -48,6 +48,7 @@ terms specified in this license.
#include "../../src/lladd/page/slotted.h"
#include <lladd/bufferManager.h>
#include <lladd/transactional.h>
#include <lladd/logger/logger2.h>
#include "../../src/lladd/latches.h"
#include <sched.h>
@ -185,8 +186,9 @@ Suite * check_suite(void) {
/* Sub tests are added, one per line, here */
tcase_add_test(tc, pageOpCheckAllocDealloc);
tcase_add_test(tc, pageOpCheckRecovery);
if(LOG_TO_MEMORY != loggerType) {
tcase_add_test(tc, pageOpCheckRecovery);
}
/* --------------------------------------------- */
tcase_add_checked_fixture(tc, setup, teardown);

View file

@ -44,6 +44,7 @@ terms specified in this license.
#include <assert.h>
#include <lladd/transactional.h>
#include <lladd/logger/logger2.h>
#include "../../src/lladd/logger/logWriter.h"
#include "../check_includes.h"
@ -497,17 +498,19 @@ Suite * check_suite(void) {
tcase_set_timeout(tc, 0); // disable timeouts
/* Sub tests are added, one per line, here */
tcase_add_test(tc, recovery_idempotent);
tcase_add_test(tc, recovery_exactlyOnce);
tcase_add_test(tc, recovery_idempotentAbort);
tcase_add_test(tc, recovery_exactlyOnceAbort);
tcase_add_test(tc, recovery_clr);
tcase_add_test(tc, recovery_crash);
tcase_add_test(tc, recovery_multiple_xacts);
if(LOG_TO_MEMORY != loggerType) {
/* Sub tests are added, one per line, here */
tcase_add_test(tc, recovery_idempotent);
tcase_add_test(tc, recovery_exactlyOnce);
tcase_add_test(tc, recovery_idempotentAbort);
tcase_add_test(tc, recovery_exactlyOnceAbort);
tcase_add_test(tc, recovery_clr);
tcase_add_test(tc, recovery_crash);
tcase_add_test(tc, recovery_multiple_xacts);
}
/* --------------------------------------------- */
tcase_add_checked_fixture(tc, setup, teardown);
suite_add_tcase(s, tc);