List:Commits« Previous MessageNext Message »
From:Olav Sandstaa Date:June 22 2009 12:23pm
Subject:bzr commit into mysql-6.0-falcon-team branch (olav:2739) Bug#44744 Bug#45297
View as plain text  
#At file:///home/os136802/mysql/develop/repo/falcon-bug45297/ based on revid:kevin.lewis@stripped

 2739 Olav Sandstaa	2009-06-22
      Fix for Bug#44744 "Recovery stage 3: segfault in RecoveryObjects::findRecoveryObject" and Bug#45297 "Crash
      during recovery due to pread reading beyond EOF"
      
      These crashes was both caused by an inconsistency between the Record Locator Page and the Data page. The record 
      locator page claimed that the record was stored in a data page while the record was not present in the data page.
      This situation can happen during recovery if the Record Locator page has been written to disk while the 
      data page has not been written to disk when a server crash occurs. The recovery crash happened when the code
      had locate the record by a lookup in the Record Locator page and then called DataPage::updateRecord() where the
      record was not present. In the crash situation the record expected to be located on the same line number as
      the maxLine of the data page. This lead to reading "garbage" from the data page and resulted in an invalid 
      overflow page number.
      
      This patch fixes this problem by handling that DataPage::updateRecord and DataPage::deleteLine handles to
      be called also when the record is not present in the data page. In this situation both the functions will
      just ignore the call. DataPage::updateRecord() will return that there was not room for the record. This will
      result in the inconsistency between the data page and the Record Locator page being resolved since 
      the "failing" call to DataPage::updateRecord() will trigger removal of the record's entry in the Record Locator 
      page - and the record will be inserted somewhere else.
     @ storage/falcon/DataPage.cpp
        During recovery: extend DataPage::updateRecord() and DataPage::deleteLine() so that they handle to
        be called with a line number that is equal or larger than the current maxLine. If this is the case
        the call will just be ignored.

    modified:
      storage/falcon/DataPage.cpp
=== modified file 'storage/falcon/DataPage.cpp'
--- a/storage/falcon/DataPage.cpp	2009-06-12 13:34:24 +0000
+++ b/storage/falcon/DataPage.cpp	2009-06-22 12:23:12 +0000
@@ -43,7 +43,18 @@ static const char THIS_FILE[]=__FILE__;
 
 int DataPage::updateRecord(Section *section, int lineNumber, Stream *stream, TransId transId, bool earlyWrite)
 {
-	ASSERT(lineNumber < maxLine);
+	/* During recovery we might be asked to update a record that does
+	   not exist on the page. This situation can happen when the
+	   Record Locator page was written to disk while this data page
+	   was not written to disk before the server crash. We handle this
+	   by returning that there is no rom for this record on this
+	   page. */
+
+	if (lineNumber >= maxLine)
+		{
+		ASSERT(section->dbb->serialLog->recovering);
+		return 0;
+		}
 
 	Dbb *dbb = section->dbb;
 	LineIndex *index = lineIndex + lineNumber;
@@ -295,6 +306,17 @@ int DataPage::storeRecord(Dbb *dbb, Bdb 
 
 int DataPage::deleteLine (Dbb *dbb, int line, TransId transId)
 {
+	/* During recovery we might be asked to delete a record that does
+	   not exists on the page. This situation can happen when the
+	   Record Locator page was written to disk while this data
+	   page was not written to disk before the server crashed. */
+
+	if (line >= maxLine)
+		{
+		ASSERT(dbb->serialLog->recovering);
+		return 0;
+		}
+
 	// Handle overflow pages first
 
 	if (lineIndex [line].length < 0)


Attachment: [text/bzr-bundle] bzr/olav@sun.com-20090622122312-3wp689bpd17avscj.bundle
Thread
bzr commit into mysql-6.0-falcon-team branch (olav:2739) Bug#44744 Bug#45297Olav Sandstaa22 Jun
  • Re: bzr commit into mysql-6.0-falcon-team branch (olav:2739) Bug#44744Bug#45297Kevin Lewis22 Jun