Looks OK to push.
Vladislav Vaintroub wrote:
> #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;
>
>
>
> ------------------------------------------------------------------------
>
>