MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:January 28 2009 11:01am
Subject:bzr commit into mysql-6.0-falcon-team branch (vvaintroub:2981)
Bug#40946
View as plain text  
#At file:///G:/bzr/mysql-6.0-falcon-team/ based on revid:vvaintroub@stripped

 2981 Vladislav Vaintroub	2009-01-28
      Bug #40946: assertion in PageInventoryPage::allocPage in recovery.
      
      Reason : 
      Creation of section pages was not always logged. Hence, not all section pages were redone by recovery. During recovery a section root was missing and Section::getSectionPage was trying to allocate a missing root. This caused the assertion in bug.
      
      Solution : always log section pages and rebuild them on recovery.
      - This patch also simplified the redo logic for section pages - no more guessing and trying to save information in it. The page should be clean after creation. 
      
      - This patch also removed another "allocate on demand" code in getSectionRoot()  - it should not be necessary since the page is either already  in the tablespace (written by last checkpoint), or exists as in log record and will be created  in recovery prior to first use.
modified:
  storage/falcon/Section.cpp

=== modified file 'storage/falcon/Section.cpp'
--- a/storage/falcon/Section.cpp	2008-06-17 17:41:54 +0000
+++ b/storage/falcon/Section.cpp	2009-01-28 11:01:08 +0000
@@ -164,6 +164,10 @@ void Section::createSection(Dbb *dbb, in
 
 	if (sections->pages [slot] == 0)
 		{
+		// If we're in recovery and slot is empty, something went wrong , page must have
+		// been logged and rebuilt already (every allocation is redone)
+		ASSERT (!(dbb->serialLog && dbb->serialLog->recovering));
+
 		sectionsBdb->mark(transId);
 		Bdb *sectionBdb = dbb->allocPage(PAGE_sections, transId);
 		BDB_HISTORY(sectionBdb);
@@ -172,6 +176,11 @@ void Section::createSection(Dbb *dbb, in
 		sections->pages [slot] = sectionBdb->pageNumber;
 		SectionPage	 *page = (SectionPage*) sectionBdb->buffer;
 		page->section = sectionId;
+
+		// Log allocated page
+		dbb->serialLog->logControl->sectionPage.append(dbb, transId, SECTION_ROOT,
+				sectionBdb->pageNumber, slot, sectionId, 0, 0);
+
 		sectionBdb->release(REL_HISTORY);
 		}
 
@@ -1196,38 +1205,25 @@ bool Section::isCleanupRequired()
 
 void Section::redoSectionPage(Dbb *dbb, int32 parentPage, int32 pageNumber, int slot, int sectionId, int sequence, int level)
 {
-	Bdb *bdb = dbb->fetchPage (parentPage, PAGE_any, Exclusive);
+	Bdb *bdb = dbb->fetchPage (parentPage, PAGE_sections, Exclusive);
 	BDB_HISTORY(bdb);
 	SectionPage *page = (SectionPage*) bdb->buffer;
 
-	//  Unless parent page is already leaf, probe and if necessary rebuild section page
 
-	//if (pageNumber && (page->level > 0 || parentPage == SECTION_ROOT))
-	if (pageNumber && (page->level > 0 || page->section == -1))
-		{
-		Bdb *sectionBdb = dbb->fakePage(pageNumber, PAGE_any, 0);
-		BDB_HISTORY(bdb);
-		SectionPage *sectionPage = (SectionPage*) sectionBdb->buffer;
-		
-		if (!dbb->trialRead(sectionBdb) ||
-			sectionPage->pageType != PAGE_sections ||
-			sectionPage->section != sectionId ||
-			sectionPage->sequence != sequence ||
-			sectionPage->level != level)
-			{
-			memset(sectionPage, 0, dbb->pageSize);
-			//sectionPage->pageType = PAGE_sections;
-			sectionBdb->setPageHeader(PAGE_sections);
-			sectionPage->section = sectionId;
-			sectionPage->sequence = sequence;
-			sectionPage->level = level;
-			}
+	Bdb *sectionBdb = dbb->fakePage(pageNumber, PAGE_any, 0);
+	BDB_HISTORY(bdb);
+	SectionPage *sectionPage = (SectionPage*) sectionBdb->buffer;
+	memset(sectionPage, 0, dbb->pageSize);
+	sectionBdb->setPageHeader(PAGE_sections);
+	sectionPage->section = sectionId;
+	sectionPage->sequence = sequence;
+	sectionPage->level = level;
 
-		PageInventoryPage::markPageInUse(dbb, pageNumber, NO_TRANSACTION);
-		sectionBdb->release(REL_HISTORY);
-		}
+	PageInventoryPage::markPageInUse(dbb, pageNumber, NO_TRANSACTION);
+	sectionBdb->release(REL_HISTORY);
 
-	// Now try to store it in the right place
+
+	// Now store it in the right place
 
 	if (page->pages[slot] != pageNumber)
 		{
@@ -1243,33 +1239,9 @@ int32 Section::getSectionRoot()
 	Bdb *bdb = getSectionPage(dbb, SECTION_ROOT, sectionId / dbb->pagesPerSection, Shared, NO_TRANSACTION);
 	BDB_HISTORY(bdb);
 	SectionPage *sectionPage = (SectionPage*) bdb->buffer;
-	root = sectionPage->pages[sectionId % dbb->pagesPerSection];
+	int slot = sectionId % dbb->pagesPerSection;
+	root = sectionPage->pages[slot];
 	bdb->release(REL_HISTORY);
-
-	if (root == 0)
-		{
-		if (!dbb->serialLog->recovering)
-			throw SQLError(DATABASE_DAMAGED, "Missing section root for section %d/%d\n", sectionId, dbb->tableSpaceId);
-
-		// Missing root page -- make a new one
-		
-		Bdb *sectionBdb = dbb->allocPage(PAGE_sections, NO_TRANSACTION);
-		BDB_HISTORY(sectionBdb);
-		root = sectionBdb->pageNumber;
-		SectionPage *page = (SectionPage*) sectionBdb->buffer;
-		page->section = sectionId;
-		sectionBdb->release(REL_HISTORY);
-		
-		// Register new root page
-			
-		bdb = getSectionPage(dbb, SECTION_ROOT, sectionId / dbb->pagesPerSection, Exclusive, NO_TRANSACTION);
-		BDB_HISTORY(bdb);
-		sectionPage = (SectionPage*) bdb->buffer;
-		sectionPage->pages[sectionId % dbb->pagesPerSection] = root;
-		bdb->release(REL_HISTORY);
-		}
-
-		
 	return root;
 }
 

Thread
bzr commit into mysql-6.0-falcon-team branch (vvaintroub:2981)Bug#40946Vladislav Vaintroub28 Jan
  • Re: bzr commit into mysql-6.0-falcon-team branch (vvaintroub:2981)Bug#40946Kevin Lewis28 Jan