#At file:///G:/bzr/mysql-6.0-falcon-team/ based on revid:hky@stripped
2988 Vladislav Vaintroub 2009-01-30
Bug#41227 Falcon: potential corruption of RecordLocatorPage
on recovery
Problem: If falcon pager size is set to 32K, recovery
involving blob updates will crash in assertion.
Section::redoBlobUpdate and Section::redoBlobDelete will
try to set available space to the page size (32K)in record locator page
However, 32K=32768 becomes negative (-32768) when converted to short.
RecordLocatorPage::linkSpaceSlot() checks for positive value for
"space available" and asserts.
Fix is to set spaceAvailable to more realistic value
(page size - page header overhead) that is guaranteed not to overflow
and not to change sign of a short even for 32 K pages.
modified:
storage/falcon/DataPage.h
storage/falcon/RecordLocatorPage.cpp
storage/falcon/Section.cpp
=== modified file 'storage/falcon/DataPage.h'
--- a/storage/falcon/DataPage.h 2008-09-27 18:37:54 +0000
+++ b/storage/falcon/DataPage.h 2009-01-30 01:28:53 +0000
@@ -61,4 +61,7 @@ public:
LineIndex lineIndex [1];
};
+/* Maximal length of data that can be stored in a page */
+#define DATA_PAGE_MAX_AVAILABLE_SPACE(pageSize) (pageSize - sizeof(DataPage))
+
#endif // !defined(AFX_DATAPAGE_H__6A019C29_A340_11D2_AB5A_0000C01D2301__INCLUDED_)
=== modified file 'storage/falcon/RecordLocatorPage.cpp'
--- a/storage/falcon/RecordLocatorPage.cpp 2008-06-17 17:41:54 +0000
+++ b/storage/falcon/RecordLocatorPage.cpp 2009-01-30 01:28:53 +0000
@@ -269,7 +269,9 @@ void RecordLocatorPage::printPage(void)
void RecordLocatorPage::setIndexSlot(int slot, int32 pageNumber, int line, int availableSpace)
{
- ASSERT(availableSpace >= 0);
+ // Check that availableSpace is positive and can be converted to short
+ // without losing bits or changing sign
+ ASSERT(availableSpace >= 0 && availableSpace < 0x8000);
RecordIndex *element = elements + slot;
//validateSpaceSlots();
@@ -366,6 +368,7 @@ void RecordLocatorPage::setIndexSlot(int
void RecordLocatorPage::insertSpaceSlot(int slot, int availableSpace)
{
+ ASSERT(availableSpace > 0 && availableSpace < 0x8000);
int priorSlot;
int nextSlot;
=== modified file 'storage/falcon/Section.cpp'
--- a/storage/falcon/Section.cpp 2009-01-29 14:14:02 +0000
+++ b/storage/falcon/Section.cpp 2009-01-30 01:28:53 +0000
@@ -1437,7 +1437,7 @@ void Section::redoBlobUpdate(Dbb* dbb, i
if (page->maxLine <= locatorLine)
page->maxLine = locatorLine + 1;
- page->setIndexSlot(locatorLine, dataPage, dataLine, dbb->pageSize);
+ page->setIndexSlot(locatorLine, dataPage, dataLine, DATA_PAGE_MAX_AVAILABLE_SPACE(dbb->pageSize));
bdb->release(REL_HISTORY);
}
@@ -1471,7 +1471,7 @@ void Section::redoBlobDelete(Dbb* dbb, i
BDB_HISTORY(bdb);
bdb->mark(NO_TRANSACTION);
RecordLocatorPage *page = (RecordLocatorPage*) bdb->buffer;
- page->setIndexSlot(locatorLine, 0, 0, dbb->pageSize);
+ page->setIndexSlot(locatorLine, 0, 0, DATA_PAGE_MAX_AVAILABLE_SPACE(dbb->pageSize));
bdb->release(REL_HISTORY);
}
| Thread |
|---|
| • bzr commit into mysql-6.0-falcon-team branch (vvaintroub:2988)Bug#41227 | Vladislav Vaintroub | 30 Jan |