From: Vladislav Vaintroub Date: January 27 2009 8:44pm Subject: bzr commit into mysql-6.0-falcon-team branch (vvaintroub:2977) Bug#42392 List-Archive: http://lists.mysql.com/commits/64202 X-Bug: 42392 Message-Id: <0KE5001K8DMUXH80@fe-emea-10.sun.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7BIT #At file:///G:/bzr/mysql-6.0-falcon-team/ based on revid:vvaintroub@stripped 2977 Vladislav Vaintroub 2009-01-27 Bug#42392: Falcon bugs in recovery of create tablespace Problem: during recovery of workload that does "create tablespace", falcon would assert with the message "page 1/1 wrong page type, expected 8 got N (where N != 8) Analysis: Reason for the error is recent fix for Bug42060, that introduces logging for page inventory pages. PIP page #1 needs special handling that is missing in the above mentioned bug fix. Unlike other PIP pages, this one is created during "create tablespace" and should already have first 4 pages marked as allocated (for special falcon pages header, pip, section and index roots that have numbers 1-3). Recovery did not mark those pages as allocated and they were taken away by some other page types. Fix: Don't log PIP if its page number is 1. Instead, recreate PIP and other special pages during recovery of "create tablespace". This patch also contains fix for Bug#42392 - removing unnecessary TableSpace::open() from TableSpaceManager::bootstrap() modified: storage/falcon/Dbb.cpp storage/falcon/Dbb.h storage/falcon/IO.cpp storage/falcon/PageInventoryPage.cpp storage/falcon/TableSpaceManager.cpp per-file messages: storage/falcon/Dbb.cpp Introduce additional parameter in Dbb::create() that allows to create tablespace on already existing file storage/falcon/Dbb.h Introduce additional parameter in Dbb::create() that allows to create tablespace on already existing file storage/falcon/IO.cpp map ERROR_SHARING_VIOLATION to EACCESS (this Windows error was incorrectly mapped to EINVAL) storage/falcon/PageInventoryPage.cpp Do not log creation of PIP_PAGE. It will be done when for "create tablespace" together with other special page types. storage/falcon/TableSpaceManager.cpp Do not try to open tableSpaces before recovery, they will be opened as needed. As we do not know what is on disk at this stage, we can easily run into IO errors or crash if some page structure is inconsistent. === modified file 'storage/falcon/Dbb.cpp' --- a/storage/falcon/Dbb.cpp 2008-12-19 18:45:32 +0000 +++ b/storage/falcon/Dbb.cpp 2009-01-27 20:44:30 +0000 @@ -149,7 +149,7 @@ Dbb::~Dbb() dbb->close(); } -Cache* Dbb::create(const char * fileName, int pageSz, int64 cacheSize, FileType fileType, TransId transId, const char *logRoot) +Cache* Dbb::create(const char * fileName, int pageSz, int64 cacheSize, FileType fileType, TransId transId, const char *logRoot, bool useExistingFile) { serialLog = database->serialLog; odsVersion = ODS_VERSION; @@ -157,7 +157,11 @@ Cache* Dbb::create(const char * fileName sequence = 1; init(pageSz, (int) ((cacheSize + pageSz - 1) / pageSz)); - createFile(fileName); + if(useExistingFile) + openFile(fileName, false); + else + createFile(fileName); + try { Hdr::create(this, fileType, transId, logRoot); @@ -168,7 +172,8 @@ Cache* Dbb::create(const char * fileName catch(...) { closeFile(); - deleteFile(); + if(!useExistingFile) + deleteFile(); throw; } === modified file 'storage/falcon/Dbb.h' --- a/storage/falcon/Dbb.h 2008-12-19 18:45:32 +0000 +++ b/storage/falcon/Dbb.h 2009-01-27 20:44:30 +0000 @@ -165,7 +165,9 @@ public: Bdb* fakePage (int32 pageNumber, PageType pageType, TransId transId); Bdb* trialFetch(int32 pageNumber, PageType pageType, LockType lockType); void init(int pageSz, int cacheSize); - Cache* create (const char *fileName, int pageSize, int64 cacheSize, FileType fileType, TransId transId, const char *logRoot); + Cache* create (const char *fileName, int pageSize, int64 cacheSize, FileType fileType, TransId transId, const char *logRoot, + bool useExistingFile = false); + void validateCache(void); void logUpdatedRecords(Transaction* transaction, RecordVersion* records, bool chill = false); void logIndexUpdates(DeferredIndex* deferredIndex); === modified file 'storage/falcon/IO.cpp' --- a/storage/falcon/IO.cpp 2008-12-18 12:32:24 +0000 +++ b/storage/falcon/IO.cpp 2009-01-27 20:44:30 +0000 @@ -792,6 +792,7 @@ static int winOpen(const char *filename, switch(GetLastError()) { case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: errno = EACCES; break; case ERROR_FILE_NOT_FOUND: === modified file 'storage/falcon/PageInventoryPage.cpp' --- a/storage/falcon/PageInventoryPage.cpp 2009-01-26 18:13:45 +0000 +++ b/storage/falcon/PageInventoryPage.cpp 2009-01-27 20:44:30 +0000 @@ -78,7 +78,8 @@ Bdb* PageInventoryPage::createInventoryP for (int n = 0; n < dbb->pipSlots; ++n) page->freePages [n] = -1; - if (dbb->database->serialLog && !dbb->database->serialLog->recovering) + if (dbb->database->serialLog && !dbb->database->serialLog->recovering + && (pageNumber != PIP_PAGE)) dbb->database->serialLog->logControl->inventoryPage.append(dbb, pageNumber); return bdb; === modified file 'storage/falcon/TableSpaceManager.cpp' --- a/storage/falcon/TableSpaceManager.cpp 2009-01-08 17:32:55 +0000 +++ b/storage/falcon/TableSpaceManager.cpp 2009-01-27 20:44:30 +0000 @@ -214,27 +214,11 @@ void TableSpaceManager::bootstrap(int se p = EncodedDataStream::decode(p, &id, true); p = EncodedDataStream::decode(p, &fileName, true); p = EncodedDataStream::decode(p, &type, true); - /*** - p = EncodedDataStream::decode(p, &comment, true); - TableSpaceInit tsInit; - tsInit.comment = comment.getString(); - ***/ TableSpace *tableSpace = new TableSpace(database, name.getString(), id.getInt(), fileName.getString(), type.getInt(), NULL); Log::debug("New table space %s, id %d, type %d, filename %s\n", (const char*) tableSpace->name, tableSpace->tableSpaceId, tableSpace->type, (const char*) tableSpace->filename); - - if (tableSpace->type == TABLESPACE_TYPE_TABLESPACE) - try - { - tableSpace->open(); - } - catch(SQLException& exception) - { - Log::log("Couldn't open table space file \"%s\" for tablespace \"%s\": %s\n", - fileName.getString(), name.getString(), exception.getText()); - } - + add(tableSpace); stream.clear(); } @@ -396,30 +380,44 @@ void TableSpaceManager::redoCreateTableS { Sync sync(&syncObject, "TableSpaceManager::redoCreateTableSpace"); sync.lock(Exclusive); - TableSpace *tableSpace; + TableSpace *tableSpace = NULL; for (tableSpace = idHash[id % TS_HASH_SIZE]; tableSpace; tableSpace = tableSpace->idCollision) if (tableSpace->tableSpaceId == id) - return; + { + tableSpace->close(); + break; + } - char buffer[1024]; - memcpy(buffer, name, nameLength); - buffer[nameLength] = 0; - char *file = buffer + nameLength + 1; - memcpy(file, fileName, fileNameLength); - file[fileNameLength] = 0; - tableSpace = new TableSpace(database, buffer, id, file, type, tsInit); - tableSpace->needSave = true; - add(tableSpace); + if (!tableSpace) + { + char buffer[1024]; + memcpy(buffer, name, nameLength); + buffer[nameLength] = 0; + char *file = buffer + nameLength + 1; + memcpy(file, fileName, fileNameLength); + file[fileNameLength] = 0; + tableSpace = new TableSpace(database, buffer, id, file, type, tsInit); + tableSpace->needSave = true; + add(tableSpace); + } try { - tableSpace->open(); + Dbb *dbb = tableSpace->dbb; + + dbb->create(tableSpace->filename, database->dbb->pageSize, 0, HdrTableSpace, + NO_TRANSACTION, "", true); + dbb->close(); + } catch(SQLException& exception) { Log::log("Couldn't open table space file \"%s\" for tablespace \"%s\": %s\n", - file, buffer, exception.getText()); + tableSpace->filename, tableSpace->name, exception.getText()); + + // remove from various hashtables + expungeTableSpace(tableSpace->tableSpaceId); } }