From: Christopher Powers Date: October 24 2008 5:07am Subject: bzr commit into mysql-6.0-falcon-team branch (cpowers:2880) Bug#36631 Bug#38541 Bug#38567 Bug#38569 Bug#39694 Bug#39695 Bug#39696 List-Archive: http://lists.mysql.com/commits/56961 X-Bug: 36631,38541,38567,38569,39694,39695,39696 Message-Id: <20081024050704.B8AE51DB0720@xeno.mysql.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #At file:///home/cpowers/work/dev/dev-09/mysql/ 2880 Christopher Powers 2008-10-24 Bug#36631,"Assertion in SerialLogControl::nextRecord" Bug#38541,"Falcon RecordVersion::thaw assertion """"bytesRestored > 0 || data.record == NULL""" Bug#38567,"Falcon crash in Record::getEncodedRecord at Record.cpp:743" Bug#38569,"Falcon assertion in SRLUpdateIndex::thaw : type == srlUpdateIndex" Bug#39694,"Crash in StorageTable::setRecord during falcon_chill_thaw test" Bug#39695,"Crash in SRLUpdateRecords::thaw during falcon_chill_thaw test" Bug#39696,"Assertion in Table.cpp (dup->state == recDeleted) fails during falcon_chill_thaw" Fix 1 of 3 for chill/thaw bugs. Modified Record::hasRecord() to thaw if necessary, removed redundant record thaws, added exception handling modified: storage/falcon/Record.cpp storage/falcon/Record.h storage/falcon/RecordScavenge.cpp storage/falcon/RecordVersion.cpp storage/falcon/RecordVersion.h storage/falcon/SRLUpdateRecords.cpp storage/falcon/Table.cpp storage/falcon/Transaction.cpp per-file messages: storage/falcon/Record.cpp Record::getRecord() -- return true if successful, false if data buffer is null Record::getEncodedValue() -- removed thaw because no longer needed, added try/catch Record::thaw() -- added 'force' option storage/falcon/Record.h Record::thaw() -- added 'force' Record::getRecord() -- now returns boolean Record::hasRecord() -- thaws record if chilled storage/falcon/RecordScavenge.cpp RecordScavenge::inventoryRecord() -- Added 'false' to record->hasRecord() so that it won't thaw record storage/falcon/RecordVersion.cpp Added 'false' option to calls to hasRecord() in cases where a record thaw is not necessary RecordVersion::thaw() -- added 'force' option that will allow a thaw from the serial log even if Transaction::writePending == false RecordVersion::thaw() -- removed assert, only update record state if thaw successful storage/falcon/RecordVersion.h RecordVersion::thaw() -- added 'force' option storage/falcon/SRLUpdateRecords.cpp SRLUpdateRecords::chill() -- don't thaw records considered for chill SRLUpdateRecords::chill() -- ignore records for which getRecord(stream) fails storage/falcon/Table.cpp Table::fetchForUpdate() -- removed unnecessary thaw Table::fetchForUpdate() -- if record is chilled, thaw. If thaw fails, release and continue. storage/falcon/Transaction.cpp Transaction::backlogRecords() -- don't thaw records being backlogged === modified file 'storage/falcon/Record.cpp' --- a/storage/falcon/Record.cpp 2008-05-09 19:58:50 +0000 +++ b/storage/falcon/Record.cpp 2008-10-24 05:06:52 +0000 @@ -586,22 +586,27 @@ int Record::getSavePointId() return 0; } -void Record::getRecord(Stream *stream) +bool Record::getRecord(Stream *stream) { - switch (encoding) + if (data.record != NULL) { - case traditional: - stream->compress (format->length, data.record); - break; + switch (encoding) + { + case traditional: + stream->compress (format->length, data.record); + break; - case shortVector: - stream->putSegment(getEncodedSize(), - data.record + ((USHORT*) data.record)[0] - sizeof(short), false); - break; + case shortVector: + stream->putSegment(getEncodedSize(), + data.record + ((USHORT*) data.record)[0] - sizeof(short), false); + break; - default: - NOT_YET_IMPLEMENTED; + default: + NOT_YET_IMPLEMENTED; + } } + + return (data.record != NULL); } int Record::getEncodedSize() @@ -626,11 +631,8 @@ int Record::getEncodedSize() void Record::getEncodedValue(int fieldId, Value *value) { - // If chilled, restore the record data from the serial log - - if (state == recChilled) - thaw(); - + try + { switch (encoding) { case shortVector: @@ -663,6 +665,11 @@ void Record::getEncodedValue(int fieldId NOT_YET_IMPLEMENTED; } } + catch (SQLException& exception) + { + int code = exception.getSqlcode(); + } +} void Record::finalize(Transaction *transaction) { @@ -849,7 +856,7 @@ void Record::setPriorVersion(Record* rec ASSERT(false); } -int Record::thaw() +int Record::thaw(bool force) { return 0; } === modified file 'storage/falcon/Record.h' --- a/storage/falcon/Record.h 2008-05-09 19:58:50 +0000 +++ b/storage/falcon/Record.h 2008-10-24 05:06:52 +0000 @@ -88,7 +88,7 @@ public: virtual Record* getPriorVersion(); virtual Record* getGCPriorVersion(void); virtual void print(void); - virtual int thaw(); + virtual int thaw(bool force = false); virtual const char* getEncodedRecord(); virtual int setRecordData(const UCHAR *dataIn, int dataLength); virtual void serialize(Serialize* stream); @@ -107,7 +107,7 @@ public: int getBlobId(int fieldId); void finalize(Transaction *transaction); void getEncodedValue (int fieldId, Value *value); - void getRecord (Stream *stream); + bool getRecord (Stream *stream); int getEncodedSize(); void deleteData(void); void printRecord(const char* header); @@ -119,10 +119,13 @@ public: Record (Table *table, int32 recordNumber, Stream *stream); Record (Database *database, Serialize* stream); - inline int hasRecord() + inline int hasRecord(bool forceThaw = true) { - return data.record != NULL; - }; + if (state == recChilled && forceThaw) + thaw(); + + return (data.record != NULL); + } inline char* getRecordData() { @@ -142,7 +145,6 @@ protected: public: volatile INTERLOCK_TYPE useCount; - //Table *table; Format *format; int recordNumber; int size; === modified file 'storage/falcon/RecordScavenge.cpp' --- a/storage/falcon/RecordScavenge.cpp 2008-05-09 19:58:50 +0000 +++ b/storage/falcon/RecordScavenge.cpp 2008-10-24 05:06:52 +0000 @@ -56,7 +56,7 @@ void RecordScavenge::inventoryRecord(Rec uint64 age = baseGeneration - record->generation; int size = record->size + sizeof(MemBigHeader); - if (record->hasRecord() || (record->state == recChilled)) + if (record->hasRecord(false) || record->state == recChilled) size += sizeof(MemBigHeader); if (age != UNDEFINED && age < AGE_GROUPS) === modified file 'storage/falcon/RecordVersion.cpp' --- a/storage/falcon/RecordVersion.cpp 2008-10-16 02:57:10 +0000 +++ b/storage/falcon/RecordVersion.cpp 2008-10-24 05:06:52 +0000 @@ -194,7 +194,7 @@ bool RecordVersion::scavenge(RecordScave if ( useCount == 1 && !transaction && transactionId < recordScavenge->transactionId - && (!hasRecord() + && (!hasRecord(false) || generation <= recordScavenge->scavengeGeneration || recordScavenge->forced)) { @@ -231,7 +231,7 @@ bool RecordVersion::scavenge(RecordScave if ( rec->useCount == 1 && !rec->getTransaction() && rec->getTransactionId() < recordScavenge->transactionId - && (!rec->hasRecord() + && (!rec->hasRecord(false) || rec->generation <= recordScavenge->scavengeGeneration)) return true; } @@ -353,7 +353,7 @@ uint64 RecordVersion::getVirtualOffset() return (virtualOffset); } -int RecordVersion::thaw() +int RecordVersion::thaw(bool force) { int bytesRestored = 0; Transaction *trans = transaction; @@ -367,7 +367,7 @@ int RecordVersion::thaw() // true, then the record data can be restored from the serial log. If writePending // is false, then the record data has been written to the data pages. - if (trans && trans->writePending) + if (trans && (trans->writePending || force)) { trans->addRef(); bytesRestored = trans->thaw(this); @@ -381,9 +381,6 @@ int RecordVersion::thaw() // The record data is no longer available in the serial log, so zap the // virtual offset and restore from the data page. - if (state != recChilled) - return size; - bool recordFetched = false; if (bytesRestored == 0) @@ -414,9 +411,10 @@ int RecordVersion::thaw() } if (state == recChilled) - ASSERT(bytesRestored > 0 || data.record == NULL); - - state = recData; + { + if (data.record != NULL) + state = recData; + } return bytesRestored; } === modified file 'storage/falcon/RecordVersion.h' --- a/storage/falcon/RecordVersion.h 2008-04-25 04:25:18 +0000 +++ b/storage/falcon/RecordVersion.h 2008-10-24 05:06:52 +0000 @@ -53,7 +53,7 @@ public: virtual void setPriorVersion (Record *oldVersion); virtual void setVirtualOffset(uint64 offset); virtual uint64 getVirtualOffset(); - virtual int thaw(); + virtual int thaw(bool force = false); virtual void print(void); virtual int getSize(void); virtual void serialize(Serialize* stream); === modified file 'storage/falcon/SRLUpdateRecords.cpp' --- a/storage/falcon/SRLUpdateRecords.cpp 2008-10-16 02:53:35 +0000 +++ b/storage/falcon/SRLUpdateRecords.cpp 2008-10-24 05:06:52 +0000 @@ -198,8 +198,11 @@ void SRLUpdateRecords::append(Transactio // Load the record data into a stream - if (record->hasRecord()) - record->getRecord(&stream); + if (record->hasRecord(false)) + { + if (!record->getRecord(&stream)) + continue; + } else ASSERT(record->state == recDeleted); @@ -247,7 +250,6 @@ void SRLUpdateRecords::append(Transactio log->chilledRecords += chilledRecordsWindow; log->chilledBytes += chilledBytesWindow; transaction->chilledRecords += chilledRecordsWindow; - transaction->chilledBytes += chilledBytesWindow; windowNumber = (uint32)log->writeWindow->virtualOffset / SRL_WINDOW_SIZE; } } // next window === modified file 'storage/falcon/Table.cpp' --- a/storage/falcon/Table.cpp 2008-10-21 20:51:43 +0000 +++ b/storage/falcon/Table.cpp 2008-10-24 05:06:52 +0000 @@ -2545,9 +2545,6 @@ bool Table::checkUniqueRecordVersion(int state = transaction->getRelativeState(dup, DO_NOT_WAIT); - if (dup->state == recChilled) - dup->getRecordData(); - // Check for a deleted record or a record lock if (!dup->hasRecord()) @@ -3548,6 +3545,13 @@ Record* Table::fetchForUpdate(Transactio return NULL; } + if (record->state == recChilled && !record->thaw()) + { + record->release(); + + return NULL; + } + // Lock the record if (dbb->debug & DEBUG_RECORD_LOCKS) @@ -3562,9 +3566,6 @@ Record* Table::fetchForUpdate(Transactio transaction->addRecord(recordVersion); recordVersion->release(); - if (record->state == recChilled) - record->thaw(); - ASSERT(record->useCount >= 2); return record; === modified file 'storage/falcon/Transaction.cpp' --- a/storage/falcon/Transaction.cpp 2008-10-16 02:53:35 +0000 +++ b/storage/falcon/Transaction.cpp 2008-10-24 05:06:52 +0000 @@ -1526,7 +1526,7 @@ void Transaction::backlogRecords(void) { prior = record->prevInTrans; - if (!record->hasRecord()) + if (!record->hasRecord(false)) { if (savePoints) for (; savePoint && record->savePointId < savePoint->id; savePoint = savePoint->next)