List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:February 18 2009 5:41pm
Subject:bzr commit into mysql-6.0-falcon-team branch (vvaintroub:3026)
Bug#41837 Bug#42745
View as plain text  
#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#42745Vladislav Vaintroub18 Feb