#At file:///G:/bzr/ts2/ based on revid:lars-erik.bjork@stripped
3026 Vladislav Vaintroub 2009-02-18
Bug #42745 Exception: can't find table space during recovery
Bug #41837 Falcon recovery error: page 102/0 wrong page type,
expected 7 got 0
Problem: Falcon internal table system.tablespaces can be inconsistent
when mysqld has crashed or was killed.
This table (possibly inconsistent) was previously read on Falcon startup
in TableSpaceManager::bootstrap(), to provide recovery with enough
information to associate tablespace IDs in log records with actual
tablespace files.
But since the table is possibly outdated information, it was still possible
to have lost tablespaceid without any correspond file. Recovery will stop
then.
Another problem with TableSpace::bootstrap() is attempt to read behind the
end of falcon_master.fts. Typically it would be a page present referenced
in a section page, and referenced page was not yet flushed to disk at the
moment of crash(Bug#41837)
Solution:
Avoid reading system.tablespaces from disk whenever possible. Instead,
when a new tablespace is added or some tablespace is deleted, current state
(listof all existing tablespaces) is written to serial log in
SRLTableSpaces record. If recovery finds SRLTableSpaces during the first
pass, last SRLTableSpaces record is used to reconstruct the before-crash
state.
If recovery does not find SRLTableSpaces, it will still read system.table
spaces with TableSpaceManager::bootstrap() as before. However reading from
disk is safe, because tablespaces were not modified since the last
checkpoint.
added:
storage/falcon/SRLTableSpaces.cpp
storage/falcon/SRLTableSpaces.h
modified:
storage/falcon/CMakeLists.txt
storage/falcon/Database.cpp
storage/falcon/Makefile.am
storage/falcon/SRLVersion.h
storage/falcon/SerialLog.cpp
storage/falcon/SerialLogControl.cpp
storage/falcon/SerialLogControl.h
storage/falcon/SerialLogRecord.h
storage/falcon/TableSpaceManager.cpp
storage/falcon/TableSpaceManager.h
per-file messages:
storage/falcon/CMakeLists.txt
Added SRLTableSpaces
storage/falcon/Database.cpp
initialization of tableSpaceManager moved to
createDatabase() and recovery code
storage/falcon/Database.h
Added SRLTableSpaces
storage/falcon/Makefile.am
Added SRLTableSpaces
storage/falcon/SerialLog.cpp
Initialize and open tablespaces at the start of recovery phase2,
instead of pre-recovery.
During the phase1, the last change of tablespace manager (
list of existing tablespaces) could be saved in serial log,
if tablespace was added or deleted. We need to use information
from serial log in this case, because Falcon's data dictionary
(system.tablespaces) can be outdated or inconsistent leading
to "tablespace not found" errors during recovery.
storage/falcon/SerialLogControl.cpp
new log type SRLTableSpaces
storage/falcon/SerialLogControl.h
NEw log type SRLTableSpaces
storage/falcon/SerialLogRecord.h
new log type SRLTableSpaces
storage/falcon/TableSpaceManager.cpp
Log the list of tablespaces each time tablespace is added or deleted.
(for recovery)
storage/falcon/TableSpaceManager.h
TableSpaceManager::bootstrap is refactored and does not open tablespaces,
only reads system.tablespaces from disk.
To open all existing table spaces,separate function openTableSpaces() is provided
=== modified file 'storage/falcon/CMakeLists.txt'
--- a/storage/falcon/CMakeLists.txt 2009-01-28 06:52:48 +0000
+++ b/storage/falcon/CMakeLists.txt 2009-02-18 17:41:40 +0000
@@ -254,7 +254,8 @@ SET(FALCON_SOURCES
SRLSequence.cpp
SRLSequencePage.cpp
SRLSession.cpp
- SRLSwitchLog.cpp
+ SRLSwitchLog.cpp
+ SRLTableSpaces.cpp
SRLUpdateIndex.cpp
SRLUpdateBlob.cpp
SRLUpdateRecords.cpp
@@ -535,7 +536,8 @@ SET(FALCON_SOURCES
SRLSequence.h
SRLSequencePage.h
SRLSession.h
- SRLSwitchLog.h
+ SRLSwitchLog.h
+ SRLTableSpaces.h
SRLUpdateIndex.h
SRLUpdateBlob.h
SRLUpdateRecords.h
=== modified file 'storage/falcon/Database.cpp'
--- a/storage/falcon/Database.cpp 2009-02-03 02:53:42 +0000
+++ b/storage/falcon/Database.cpp 2009-02-18 17:41:40 +0000
@@ -516,7 +516,6 @@ void Database::start()
imageManager = new ImageManager(this);
roleModel = new RoleModel(this);
systemConnection = new Connection(this);
- tableSpaceManager = new TableSpaceManager(this);
dbb->serialLog = serialLog = new SerialLog(this, configuration->checkpointSchedule, configuration->maxTransactionBacklog);
pageWriter = new PageWriter(this);
searchWords = new SearchWords (this);
@@ -645,7 +644,7 @@ void Database::createDatabase(const char
// If valid, use the user-defined serial log path, otherwise use the default.
JString logRoot = setLogRoot(filename, true);
-
+ tableSpaceManager = new TableSpaceManager(this);
//TBD: Return error to server.
#ifdef STORAGE_ENGINE
@@ -745,8 +744,6 @@ void Database::openDatabase(const char *
if (dbb->logLength)
serialLog->copyClone(dbb->logRoot, dbb->logOffset, dbb->logLength);
serialLog->open(dbb->logRoot, false);
- if (dbb->tableSpaceSectionId)
- tableSpaceManager->bootstrap(dbb->tableSpaceSectionId);
try
{
@@ -1791,10 +1788,14 @@ void Database::scavenge(bool forced)
transactionManager->reportStatistics();
if (serialLog)
+ {
serialLog->reportStatistics();
+ if (!serialLog->recovering)
+ tableSpaceManager->reportStatistics();
+ }
dbb->reportStatistics();
- tableSpaceManager->reportStatistics();
+
repositoryManager->reportStatistics();
if (backLog)
=== modified file 'storage/falcon/Makefile.am'
--- a/storage/falcon/Makefile.am 2009-02-12 17:56:03 +0000
+++ b/storage/falcon/Makefile.am 2009-02-18 17:41:40 +0000
@@ -168,6 +168,7 @@ falcon_headers= Agent.h Alias.h Applicat
SRLSequencePage.h \
SRLSession.h \
SRLSwitchLog.h \
+ SRLTableSpaces.h \
SRLUpdateIndex.h \
SRLUpdateBlob.h \
SRLUpdateRecords.h \
@@ -353,6 +354,7 @@ falcon_sources= Agent.cpp Alias.cpp \
SRLSequencePage.cpp \
SRLSession.cpp \
SRLSwitchLog.cpp \
+ SRLTableSpaces.cpp \
SRLUpdateIndex.cpp \
SRLUpdateBlob.cpp \
SRLUpdateRecords.cpp \
=== added file 'storage/falcon/SRLTableSpaces.cpp'
--- a/storage/falcon/SRLTableSpaces.cpp 1970-01-01 00:00:00 +0000
+++ b/storage/falcon/SRLTableSpaces.cpp 2009-02-18 17:41:40 +0000
@@ -0,0 +1,107 @@
+/* Copyright 2009 Sun Microsystems, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "Engine.h"
+#include "SRLTableSpaces.h"
+#include "TableSpaceManager.h"
+#include "TableSpace.h"
+#include "Database.h"
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static const char THIS_FILE[]=__FILE__;
+#endif
+
+static TableSpaceManager *tableSpaceManager;
+
+SRLTableSpaces::SRLTableSpaces()
+{
+ tableSpaceManager = NULL;
+}
+
+SRLTableSpaces::~SRLTableSpaces()
+{
+}
+
+TableSpaceManager *SRLTableSpaces::getTableSpaceManager()
+{
+ return tableSpaceManager;
+}
+
+// Serialize TableSpaceManager to the the serial log
+void SRLTableSpaces::append(TableSpaceManager *manager)
+{
+ START_RECORD(srlTableSpaces, "SRLTableSpaces::append");
+
+ int count = 0;
+ for(TableSpace *tableSpace = manager->tableSpaces; tableSpace ; tableSpace = tableSpace->next)
+ count++;
+
+ putInt(count);
+
+ for(TableSpace *tableSpace = manager->tableSpaces; tableSpace ; tableSpace = tableSpace->next)
+ {
+ putInt(tableSpace->tableSpaceId);
+ putInt(tableSpace->type);
+
+ int len = tableSpace->name.length()+1;
+ putInt(len);
+ putData(len, (const UCHAR *)tableSpace->name.getString());
+
+ len = tableSpace->filename.length()+1;
+ putInt(len);
+ putData(len, (const UCHAR *)tableSpace->filename.getString());
+ }
+
+ log->flush(false, log->nextBlockNumber, &sync);
+}
+
+
+// Deserialize TableSpaceManager from SerialLog and store
+// it in recoveryTablespaceManager
+void SRLTableSpaces::read()
+{
+ int count = getInt();
+
+ if (log->recoveryPhase==1)
+ {
+ delete tableSpaceManager;
+ tableSpaceManager = new TableSpaceManager(log->database);
+ }
+
+ for(int i=0; i < count; i++)
+ {
+ int id = getInt();
+ int type = getInt();
+ int len = getInt();
+ char *name = (char *)getData(len);
+ len = getInt();
+ char *filename = (char *)getData(len);
+ if (log->recoveryPhase==1)
+ tableSpaceManager->add(new TableSpace(log->database, name, id, filename, type, NULL));
+ }
+}
+
+void SRLTableSpaces::print()
+{
+ logPrint("SRLTableSpaces\n");
+ TableSpace *tableSpace;
+ for(tableSpace = tableSpaceManager->tableSpaces; tableSpace ; tableSpace= tableSpace->next)
+ {
+ logPrint("name = %s, id = %d, filename = %s\n",
+ tableSpace->name.getString(), tableSpace->tableSpaceId, tableSpace->filename.getString());
+ }
+}
=== added file 'storage/falcon/SRLTableSpaces.h'
--- a/storage/falcon/SRLTableSpaces.h 1970-01-01 00:00:00 +0000
+++ b/storage/falcon/SRLTableSpaces.h 2009-02-18 17:41:40 +0000
@@ -0,0 +1,37 @@
+/* Copyright 2009 Sun Microsystems, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef SRL_TABLESPACES_H
+#define SRL_TABLESPACES_H
+
+#include "SerialLogRecord.h"
+class TableSpaceManager;
+
+class SRLTableSpaces : public SerialLogRecord
+{
+public:
+ virtual void print();
+ void append(TableSpaceManager *manager);
+ virtual void read();
+ SRLTableSpaces();
+ virtual ~SRLTableSpaces();
+
+ // Return the most recent tablespace list
+ // found in serialLog
+ static TableSpaceManager *getTableSpaceManager();
+};
+
+#endif
=== modified file 'storage/falcon/SRLVersion.h'
--- a/storage/falcon/SRLVersion.h 2009-02-10 22:50:04 +0000
+++ b/storage/falcon/SRLVersion.h 2009-02-18 17:41:40 +0000
@@ -44,7 +44,8 @@ static const int srlVersion14 = 14; //
static const int srlVersion15 = 15; // Added tablespace parameters to SRLCreateTableSpace March 27, 2008
static const int srlVersion16 = 16; // Added SRLInventoryPage January 26, 2009
static const int srlVersion17 = 17; // Log root page number in SRLCreateIndex
-static const int srlCurrentVersion = srlVersion17;
+static const int srlVersion18 = 18; // Log tablespace list in SRLTableSpaces
+static const int srlCurrentVersion = srlVersion18;
class SRLVersion : public SerialLogRecord
{
=== modified file 'storage/falcon/SerialLog.cpp'
--- a/storage/falcon/SerialLog.cpp 2009-02-13 19:45:32 +0000
+++ b/storage/falcon/SerialLog.cpp 2009-02-18 17:41:40 +0000
@@ -214,6 +214,33 @@ void SerialLog::start()
gopher->start();
}
+
+// Setup up tableSpaceManager and open all tablespaces.
+//
+// This function should be called after phase 1 of recovery,
+// At this stage, serial log is inspected and up-to-date tablespace list
+// is stored in SRLTableSpaces.
+//
+// If no SRLTableSpaces is not found in serial log, it means no changes
+// were done to tablespace list after the last checkpoint and it is safe
+// to use TableSpaceManager::bootstrap() that reads from disk
+
+static void openTableSpaces(Database *database)
+{
+ TableSpaceManager *manager = SRLTableSpaces::getTableSpaceManager();
+
+ if(!manager)
+ {
+ manager = new TableSpaceManager(database);
+ manager->bootstrap(database->dbb->tableSpaceSectionId);
+ }
+
+ manager->openTableSpaces();
+
+ database->tableSpaceManager = database->serialLog->tableSpaceManager =
+ manager;
+
+}
void SerialLog::recover()
{
Log::log("Recovering database %s ...\n", (const char*) defaultDbb->fileName);
@@ -352,13 +379,15 @@ void SerialLog::recover()
recoveryPages->reset();
recoveryIndexes->reset();
recoverySections->reset();
- recoveryPhase = 2; // Physical operations, skip old incarnations
+ recoveryPhase = 2; // Physical operations, skip old incarnations
// Next, make a second pass to reallocate any necessary pages
Log::log("Recovery phase 2...\n");
recordCount = 0;
+ openTableSpaces(database);
+
while ( (record = control.nextRecord()) )
{
if (++recordCount % RECORD_MAX == 0)
=== modified file 'storage/falcon/SerialLogControl.cpp'
--- a/storage/falcon/SerialLogControl.cpp 2009-01-26 18:13:45 +0000
+++ b/storage/falcon/SerialLogControl.cpp 2009-02-18 17:41:40 +0000
@@ -175,6 +175,9 @@ SerialLogRecord* SerialLogControl::getRe
case srlInventoryPage:
return &inventoryPage;
+ case srlTableSpaces:
+ return &tableSpaces;
+
default:
ASSERT(false);
}
=== modified file 'storage/falcon/SerialLogControl.h'
--- a/storage/falcon/SerialLogControl.h 2009-01-26 18:13:45 +0000
+++ b/storage/falcon/SerialLogControl.h 2009-02-18 17:41:40 +0000
@@ -63,6 +63,7 @@
#include "SRLSession.h"
#include "SRLSavepointRollback.h"
#include "SRLInventoryPage.h"
+#include "SRLTableSpaces.h"
#define LOW_BYTE_FLAG 0x80
@@ -139,6 +140,7 @@ public:
SRLSession session;
SRLSavepointRollback savepointRollback;
SRLInventoryPage inventoryPage;
+ SRLTableSpaces tableSpaces;
};
#endif // !defined(AFX_SERIALLOGCONTROL_H__77229761_E146_4AE4_8BBC_2114F6A0FC93__INCLUDED_)
=== modified file 'storage/falcon/SerialLogRecord.h'
--- a/storage/falcon/SerialLogRecord.h 2009-01-26 18:13:45 +0000
+++ b/storage/falcon/SerialLogRecord.h 2009-02-18 17:41:40 +0000
@@ -72,7 +72,8 @@ static const int srlSmallBlob = 35;
static const int srlSession = 36;
static const int srlSavepointRollback = 37;
static const int srlInventoryPage = 38;
-static const int srlMax = 39;
+static const int srlTableSpaces = 39;
+static const int srlMax = 40;
class SerialLog;
=== modified file 'storage/falcon/TableSpaceManager.cpp'
--- a/storage/falcon/TableSpaceManager.cpp 2009-02-16 13:25:28 +0000
+++ b/storage/falcon/TableSpaceManager.cpp 2009-02-18 17:41:40 +0000
@@ -82,6 +82,9 @@ void TableSpaceManager::add(TableSpace *
idHash[slot] = tableSpace;
tableSpace->next = tableSpaces;
tableSpaces = tableSpace;
+
+ if (database->serialLog && !database->serialLog->recovering)
+ database->serialLog->logControl->tableSpaces.append(this);
}
TableSpace* TableSpaceManager::findTableSpace(const char *name)
@@ -217,17 +220,6 @@ void TableSpaceManager::bootstrap(int se
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);
- try
- {
- tableSpace->open();
- add(tableSpace);
- }
- catch(SQLException &e)
- {
- Log::debug("Can't open tablespace %s, id %d : %s\n",
- (const char*) tableSpace->name, tableSpace->tableSpaceId,e.getText());
- delete tableSpace;
- }
stream.clear();
}
}
@@ -365,7 +357,9 @@ void TableSpaceManager::expungeTableSpac
*ptr = tableSpace->next;
break;
}
-
+
+ if (database->serialLog)
+ database->serialLog->logControl->tableSpaces.append(this);
sync.unlock();
//File already deleted, just close the file descriptor
tableSpace->close();
@@ -415,6 +409,7 @@ void TableSpaceManager::redoCreateTableS
dbb->create(tableSpace->filename, database->dbb->pageSize, 0, HdrTableSpace,
NO_TRANSACTION, "", true);
+ tableSpace->active = true;
}
catch(SQLException& exception)
@@ -578,3 +573,19 @@ int TableSpaceManager::createTableSpaceI
int id = (int) sequence->update(1, database->getSystemTransaction());
return id;
}
+
+void TableSpaceManager::openTableSpaces()
+{
+ for(TableSpace *ts = tableSpaces; ts; ts = ts->next)
+ {
+ try
+ {
+ ts->open();
+ }
+ catch(SQLException &e)
+ {
+ Log::debug("Can't open tablespace %s, id %d : %s\n",
+ (const char*) ts->name, ts->tableSpaceId,e.getText());
+ }
+ }
+}
=== modified file 'storage/falcon/TableSpaceManager.h'
--- a/storage/falcon/TableSpaceManager.h 2009-01-31 23:22:42 +0000
+++ b/storage/falcon/TableSpaceManager.h 2009-02-18 17:41:40 +0000
@@ -64,6 +64,7 @@ public:
void redoCreateTableSpace(int id, int nameLength, const char* name, int fileNameLength, const char* fileName, int type, TableSpaceInit* tsInit);
void initialize(void);
int createTableSpaceId();
+ void openTableSpaces();
Database *database;
TableSpace *tableSpaces;
Thread |
---|
• bzr commit into mysql-6.0-falcon-team branch (vvaintroub:3026)Bug#41837 Bug#42745 | Vladislav Vaintroub | 18 Feb |