List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:April 20 2009 6:40pm
Subject:bzr commit into mysql-6.0-falcon-team branch (vvaintroub:3129)
Bug#41840
View as plain text  
#At file:///G:/bzr/overflowpages/ based on revid:kevin.lewis@stripped

 3129 Vladislav Vaintroub	2009-04-20
      Bug #41840 Unbounded tablespace growth during recovery
      Sometimes, after recovery the tablespaces get huge, orders of
      magnitude larger than original tablespace.
      
      The problem was that page overflow pages were not deleted 
      during recovery. If a record was modified several times during 
      recovery, the overflow pages that were created during recovery
      also leaked.
      
      The fix is to remove overflow pages , when it is possible.
      - remove all SRLOverflowPages found in course of recovery
      - just like during normal runtime,when record gets modified in 
      recovery,  remove overflow pages if the removal is safe.
      Safe means,  that page referenced is a valid dataoverflow page.
      Validity is guaranteed, if page is either not touched by recovery, 
      or the page was allocated during recovery and not yet freed.

    modified:
      storage/falcon/DataPage.cpp
      storage/falcon/SRLOverflowPages.cpp
      storage/falcon/Section.cpp
      storage/falcon/SerialLog.cpp
      storage/falcon/SerialLog.h
=== modified file 'storage/falcon/DataPage.cpp'
--- a/storage/falcon/DataPage.cpp	2008-12-04 12:22:04 +0000
+++ b/storage/falcon/DataPage.cpp	2009-04-20 18:40:49 +0000
@@ -55,7 +55,7 @@ int DataPage::updateRecord(Section *sect
 		int32 overflowPageNumber;
 		memcpy (&overflowPageNumber, ptr, sizeof (int32));
 
-		if (overflowPageNumber && !dbb->serialLog->recovering)
+		if (overflowPageNumber)
 			deleteOverflowPages (dbb, overflowPageNumber, transId);
 		}
 
@@ -301,7 +301,7 @@ int DataPage::deleteLine (Dbb *dbb, int 
 		int32 overflowPageNumber;
 		memcpy (&overflowPageNumber, ptr, sizeof (int32));
 
-		if (overflowPageNumber && !dbb->serialLog->recovering)
+		if (overflowPageNumber)
 			deleteOverflowPages (dbb, overflowPageNumber, transId);
 		}
 
@@ -341,6 +341,16 @@ void DataPage::validate(Dbb *dbb)
 
 void DataPage::deleteOverflowPages(Dbb * dbb, int32 overflowPageNumber, TransId transId)
 {
+	SerialLog *log = dbb->serialLog;
+
+	if (log->recovering)
+		{
+		if (!log->isOverflowPageValid(overflowPageNumber, dbb->tableSpaceId))
+			return;
+		log->setOverflowPageInvalid(overflowPageNumber, dbb->tableSpaceId);
+		}
+
+
 	while (overflowPageNumber)
 		{
 		Bdb *bdb = dbb->fetchPage (overflowPageNumber, PAGE_data_overflow, Exclusive);

=== modified file 'storage/falcon/SRLOverflowPages.cpp'
--- a/storage/falcon/SRLOverflowPages.cpp	2008-03-11 16:15:47 +0000
+++ b/storage/falcon/SRLOverflowPages.cpp	2009-04-20 18:40:49 +0000
@@ -89,7 +89,11 @@ void SRLOverflowPages::pass2(void)
 		if (log->tracePage == pageNumber)
 			print();
 		
-		log->bumpPageIncarnation(pageNumber, tableSpaceId, objInUse);
+		if (log->bumpPageIncarnation(pageNumber, tableSpaceId, objInUse))
+			{
+			log->redoFreePage(pageNumber, tableSpaceId);
+			log->setOverflowPageInvalid(pageNumber, tableSpaceId);
+			}
 		}
 }
 

=== modified file 'storage/falcon/Section.cpp'
--- a/storage/falcon/Section.cpp	2009-04-16 11:25:48 +0000
+++ b/storage/falcon/Section.cpp	2009-04-20 18:40:49 +0000
@@ -782,9 +782,16 @@ int Section::storeTail(Stream * stream, 
 
 	*pLength = length;
 	
-	if (!dbb->serialLog->recovering && !dbb->noLog)
-		dbb->serialLog->logControl->overflowPages.append(dbb, &pageNumbers);
-	
+
+	SerialLog *log = dbb->serialLog;
+	if (log)
+		{
+		if (log->recovering)
+			log->setOverflowPageValid(overflowPageNumber, dbb->tableSpaceSectionId);
+		else if (!earlyWrite)
+			log->logControl->overflowPages.append(dbb, &pageNumbers);
+		}
+
 	return overflowPageNumber;
 }
 

=== modified file 'storage/falcon/SerialLog.cpp'
--- a/storage/falcon/SerialLog.cpp	2009-04-13 22:37:55 +0000
+++ b/storage/falcon/SerialLog.cpp	2009-04-20 18:40:49 +0000
@@ -96,6 +96,7 @@ SerialLog::SerialLog(Database *db, JStri
 	bufferSpace = NULL;
 	recoveryPages = NULL;
 	recoveryIndexes = NULL;
+	recoveryOverflowPages = NULL;
 	recoverySections = NULL;
 	recoveryPhase = 0;
 	tracePage = TRACE_PAGE;
@@ -153,6 +154,7 @@ SerialLog::~SerialLog()
 	delete logControl;
 	delete recoveryIndexes;
 	delete recoverySections;
+	delete recoveryOverflowPages;
 	SerialLogWindow *window;
 
 	while ( (window = firstWindow) )
@@ -394,6 +396,7 @@ void SerialLog::recover()
 	recoveryPages = new RecoveryObjects(this);
 	recoverySections = new RecoveryObjects(this);
 	recoveryIndexes = new RecoveryObjects(this);
+	recoveryOverflowPages = new RecoveryObjects(this);
 	recoveryPhase = 1;	
 	
 	// Phase 1 - read from the start to end of the part of the
@@ -505,9 +508,12 @@ void SerialLog::recover()
 	delete recoveryPages;
 	delete recoverySections;
 	delete recoveryIndexes;
+	delete recoveryOverflowPages;
 	recoveryPages = NULL;
 	recoveryIndexes = NULL;
 	recoverySections = NULL;
+	recoveryOverflowPages = NULL;
+
 	droppedTablespaces.clear();
 	
 	for (window = firstWindow; window; window = window->next)
@@ -1173,6 +1179,29 @@ bool SerialLog::isSectionActive(int sect
 	return recoverySections->isObjectActive(sectionId, tableSpaceId);
 }
 
+bool SerialLog::isOverflowPageValid(int pageNumber, int tableSpaceId)
+{
+	// If page was not touched by recovery, assume it is valid
+	if (!recoveryPages->findRecoveryObject(pageNumber, tableSpaceId))
+		return true;
+
+	// Otherwise, if page was not created during recovery itself, 
+	// or was deleted in course of recovery, it is invalid
+	if (!recoveryOverflowPages->findRecoveryObject(pageNumber, tableSpaceId))
+		return false;
+	return recoveryOverflowPages->isObjectActive(pageNumber, tableSpaceId);
+}
+
+void SerialLog::setOverflowPageValid(int pageNumber, int tableSpaceId)
+{
+	recoveryOverflowPages->setActive(pageNumber, tableSpaceId);
+}
+
+void SerialLog::setOverflowPageInvalid(int pageNumber, int tableSpaceId)
+{
+	recoveryOverflowPages->setInactive(pageNumber, tableSpaceId);
+}
+
 uint32 SerialLog::appendLog(IO *shadow, int lastPage)
 {
 	Sync sync(&syncWrite, "SerialLog::appendLog");

=== modified file 'storage/falcon/SerialLog.h'
--- a/storage/falcon/SerialLog.h	2009-04-13 22:37:55 +0000
+++ b/storage/falcon/SerialLog.h	2009-04-20 18:40:49 +0000
@@ -94,6 +94,7 @@ public:
 	uint32			appendLog (IO *shadow, int lastPage);
 	bool			isSectionActive(int sectionId, int tableSpaceId);
 	bool			isIndexActive(int indexId, int tableSpaceId);
+
 	SerialLogBlock* findLastBlock (SerialLogWindow *window);
 	void			initializeWriteBlock (SerialLogBlock *block);
 	void			checkpoint(bool force);
@@ -127,6 +128,9 @@ public:
 	void			setSectionInactive(int id, int tableSpaceId);
 	void			setIndexActive(int id, int tableSpaceId);
 	void			setIndexInactive(int id, int tableSpaceId);
+	void			setOverflowPageValid(int pageNumber, int tableSpaceId);
+	void			setOverflowPageInvalid(int pageNumber, int tableSpaceId);
+	bool			isOverflowPageValid(int pageNumber, int tableSpaceId);
 	void			setTableSpaceDropped(int tableSpaceId);
 	bool			isTableSpaceDropped(int tableSpaceId);
 	void			updateSectionUseVector(uint sectionId, int tableSpaceId, int delta);
@@ -173,6 +177,7 @@ public:
 	RecoveryObjects		*recoveryPages;
 	RecoveryObjects		*recoverySections;
 	RecoveryObjects		*recoveryIndexes;
+	RecoveryObjects		*recoveryOverflowPages;
 	Bitmap				droppedTablespaces;
 	Dbb					*defaultDbb;
 	Gopher				*gophers;


Attachment: [text/bzr-bundle] bzr/vvaintroub@mysql.com-20090420184049-ejyzmbtc9rhwl8r9.bundle
Thread
bzr commit into mysql-6.0-falcon-team branch (vvaintroub:3129)Bug#41840Vladislav Vaintroub20 Apr
  • Re: bzr commit into mysql-6.0-falcon-team branch (vvaintroub:3129)Bug#41840Kevin Lewis20 Apr