From 092c9505692748b5ed6c8cf9f7a51f2affd15f8f Mon Sep 17 00:00:00 2001 From: kishoramballi Date: Fri, 8 May 2009 09:29:49 +0000 Subject: [PATCH] HashIndex undo logs when client got killed before commit or rollback fixed. Updates from enterprise --- include/Database.h | 1 + include/Transaction.h | 6 +++--- src/storage/HashIndex.cxx | 32 ++++++++++++++++++-------------- src/storage/Transaction.cxx | 38 ++++++++++++++++++++++++++++---------- 4 files changed, 50 insertions(+), 27 deletions(-) diff --git a/include/Database.h b/include/Database.h index 89eb1623..cd5adef7 100644 --- a/include/Database.h +++ b/include/Database.h @@ -157,6 +157,7 @@ class Database bool isValidAddress(void *ptr); friend class DatabaseManagerImpl; friend class Table; + friend class HashIndex; }; diff --git a/include/Transaction.h b/include/Transaction.h index f28edb66..f68048d0 100644 --- a/include/Transaction.h +++ b/include/Transaction.h @@ -61,13 +61,13 @@ class UndoLogInfo class HashUndoLogInfo { public: - void *tblPtr_; + void *metaData_; void *tuple_; void *keyPtr_; - void *indexPtr_; + void *hChunk_; void *bucket_; HashUndoLogInfo() - { tblPtr_ = tuple_ = keyPtr_ = indexPtr_ = bucket_ = NULL; } + { metaData_ = tuple_ = keyPtr_ = hChunk_ = bucket_ = NULL; } }; class Transaction diff --git a/src/storage/HashIndex.cxx b/src/storage/HashIndex.cxx index a74b9cd4..09dd7274 100644 --- a/src/storage/HashIndex.cxx +++ b/src/storage/HashIndex.cxx @@ -139,10 +139,10 @@ DbRetVal HashIndex::insert(TableImpl *tbl, Transaction *tr, void *indexPtr, Inde printDebug(DM_HashIndex, "HashIndex insert bucketno %d", bucketNo); Bucket *bucket = &(buckets[bucketNo]); HashUndoLogInfo *hInfo = new HashUndoLogInfo(); - hInfo->tblPtr_ = tbl; + hInfo->metaData_ = tbl->db_->getMetaDataPtr(); hInfo->bucket_ = bucket; hInfo->tuple_ = tuple; - hInfo->indexPtr_ = indexPtr; + hInfo->hChunk_ = ((CINDEX *)indexPtr)->hashNodeChunk_; hInfo->keyPtr_ = keyPtr; int ret = bucket->mutex_.getLock(tbl->db_->procSlot); if (ret != 0) @@ -265,10 +265,10 @@ DbRetVal HashIndex::remove(TableImpl *tbl, Transaction *tr, void *indexPtr, Inde Bucket *bucket1 = &buckets[bucket]; HashUndoLogInfo *hInfo = new HashUndoLogInfo(); - hInfo->tblPtr_ = tbl; + hInfo->metaData_ = tbl->db_->getMetaDataPtr(); hInfo->bucket_ = bucket1; hInfo->tuple_ = tuple; - hInfo->indexPtr_ = indexPtr; + hInfo->hChunk_ = ((CINDEX *)indexPtr)->hashNodeChunk_; hInfo->keyPtr_ = keyPtr; int ret = bucket1->mutex_.getLock(tbl->db_->procSlot); @@ -412,10 +412,10 @@ DbRetVal HashIndex::update(TableImpl *tbl, Transaction *tr, void *indexPtr, Inde Bucket *bucket = &buckets[bucketNo]; HashUndoLogInfo *hInfo1 = new HashUndoLogInfo(); - hInfo1->tblPtr_ = tbl; + hInfo1->metaData_ = tbl->db_->getMetaDataPtr(); hInfo1->bucket_ = bucket; hInfo1->tuple_ = tuple; - hInfo1->indexPtr_ = indexPtr; + hInfo1->hChunk_ = indexPtr; hInfo1->keyPtr_ = keyPtr; //it may run into deadlock, when two threads updates tuples which falls in @@ -437,10 +437,10 @@ DbRetVal HashIndex::update(TableImpl *tbl, Transaction *tr, void *indexPtr, Inde Bucket *bucket1 = &buckets[newBucketNo]; HashUndoLogInfo *hInfo2 = new HashUndoLogInfo(); - hInfo2->tblPtr_ = tbl; + hInfo2->metaData_ = tbl->db_->getMetaDataPtr(); hInfo2->bucket_ = bucket; hInfo2->tuple_ = tuple; - hInfo2->indexPtr_ = indexPtr; + hInfo2->hChunk_ = ((CINDEX *)indexPtr)->hashNodeChunk_; hInfo2->keyPtr_ = keyPtr; bucket1->mutex_.getLock(tbl->db_->procSlot); if (ret != 0) @@ -554,11 +554,13 @@ DbRetVal HashIndex::update(TableImpl *tbl, Transaction *tr, void *indexPtr, Inde DbRetVal HashIndex::insertLogicalUndoLog(Database *sysdb, void *data) { HashUndoLogInfo *info = (HashUndoLogInfo *) data; - TableImpl * tbl = (TableImpl *)info->tblPtr_; - Chunk *hChunk = (Chunk *) ((CINDEX *)info->indexPtr_)->hashNodeChunk_; + Chunk *hChunk = (Chunk *) info->hChunk_; + Database *db = new Database(); + db->setMetaDataPtr((DatabaseMetaData *) info->metaData_); + db->setProcSlot(sysdb->procSlot); HashIndexNode *head = (HashIndexNode *)((Bucket *)info->bucket_)->bucketList_; BucketList list(head); - list.insert(hChunk, tbl->db_, info->keyPtr_, info->tuple_); + list.insert(hChunk, db, info->keyPtr_, info->tuple_); ((Bucket *)info->bucket_)->bucketList_ = list.getBucketListHead(); return OK; } @@ -566,11 +568,13 @@ DbRetVal HashIndex::insertLogicalUndoLog(Database *sysdb, void *data) DbRetVal HashIndex::deleteLogicalUndoLog(Database *sysdb, void *data) { HashUndoLogInfo *info = (HashUndoLogInfo *) data; - TableImpl * tbl = (TableImpl *)info->tblPtr_; - Chunk *hChunk = (Chunk *) ((CINDEX *)info->indexPtr_)->hashNodeChunk_; + Chunk *hChunk = (Chunk *) info->hChunk_; + Database *db = new Database(); + db->setMetaDataPtr((DatabaseMetaData *)info->metaData_); + db->setProcSlot(sysdb->procSlot); HashIndexNode *head = (HashIndexNode *)((Bucket *)info->bucket_)->bucketList_; BucketList list(head); - DbRetVal rc = list.remove(hChunk, tbl->db_, info->keyPtr_); + DbRetVal rc = list.remove(hChunk, db, info->keyPtr_); if (SplCase == rc) { ((Bucket *)info->bucket_)->bucketList_ = list.getBucketListHead(); } diff --git a/src/storage/Transaction.cxx b/src/storage/Transaction.cxx index baf56bf9..296d420e 100644 --- a/src/storage/Transaction.cxx +++ b/src/storage/Transaction.cxx @@ -252,22 +252,40 @@ DbRetVal Transaction::applyUndoLogs(Database *sysdb) switch(logInfo->opType_) { case InsertOperation: - *((int*)(logInfo->ptrToTuple_) - 1) = 0; - //May memcpy is not needed as no one will update this - //as lock is taken on this tuple - os::memcpy(logInfo->ptrToTuple_, (char*) logInfo + + { + int *isUsed = ((int*)(logInfo->ptrToTuple_) - 1); + if (*isUsed == 0) { + printError(ErrSysFatal, "Fatal: Row is already not in use"); + } + *isUsed = 0; + //May memcpy is not needed as no one will update this + //as lock is taken on this tuple + os::memcpy(logInfo->ptrToTuple_, (char*) logInfo + sizeof(UndoLogInfo), logInfo->size_); + break; + } break; case DeleteOperation: - *((int*)(logInfo->ptrToTuple_) - 1) = 1; - os::memcpy(logInfo->ptrToTuple_, (char*) logInfo + + { + int *isUsed = ((int*)(logInfo->ptrToTuple_) - 1); + if (*isUsed == 1) { + printError(ErrSysFatal, "Fatal: Row is already in use"); + } + *isUsed = 1; + os::memcpy(logInfo->ptrToTuple_, (char*) logInfo + sizeof(UndoLogInfo), logInfo->size_); - break; + break; + } case UpdateOperation: - os::memcpy(logInfo->ptrToTuple_, (char*) logInfo + + { + int *isUsed = ((int*)(logInfo->ptrToTuple_) - 1); + if (*isUsed == 0) { + printError(ErrSysFatal, "Fatal: Row is not in use"); + } + os::memcpy(logInfo->ptrToTuple_, (char*) logInfo + sizeof(UndoLogInfo), logInfo->size_); - break; - + break; + } case InsertHashIndexOperation: HashIndex::deleteLogicalUndoLog(sysdb, (char *)logInfo + sizeof(UndoLogInfo)); -- 2.11.4.GIT