#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);
}
}
Thread |
---|
• bzr commit into mysql-6.0-falcon-team branch (vvaintroub:2977)Bug#42392 | Vladislav Vaintroub | 27 Jan |