mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 13:23:02 +01:00
Fixed bug CORE-4444 : Engine could hung and block all attachments in out of disk space condition during physical backup
Improvement CORE-4445 : Extend main database file faster when physical backup state changed from stalled to merge
This commit is contained in:
parent
97ff4dee5b
commit
9612a8600b
@ -188,7 +188,7 @@ bool GlobalRWLock::lockWrite(thread_db* tdbb, SSHORT wait)
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalRWLock::unlockWrite(thread_db* tdbb)
|
||||
void GlobalRWLock::unlockWrite(thread_db* tdbb, const bool release)
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
@ -201,13 +201,12 @@ void GlobalRWLock::unlockWrite(thread_db* tdbb)
|
||||
|
||||
currentWriter = false;
|
||||
|
||||
if (!lockCaching)
|
||||
if (!lockCaching || release)
|
||||
LCK_release(tdbb, cachedLock);
|
||||
else if (blocking)
|
||||
{
|
||||
LCK_downgrade(tdbb, cachedLock);
|
||||
blocking = false;
|
||||
}
|
||||
|
||||
blocking = false;
|
||||
|
||||
if (cachedLock->lck_physical < LCK_read)
|
||||
invalidate(tdbb);
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
|
||||
// This function returns false if it cannot take the lock
|
||||
bool lockWrite(thread_db* tdbb, SSHORT wait);
|
||||
void unlockWrite(thread_db* tdbb);
|
||||
void unlockWrite(thread_db* tdbb, const bool release = false);
|
||||
bool lockRead(thread_db* tdbb, SSHORT wait, const bool queueJump = false);
|
||||
void unlockRead(thread_db* tdbb);
|
||||
bool tryReleaseLock(thread_db* tdbb);
|
||||
|
@ -360,6 +360,46 @@ ULONG BackupManager::getPageCount()
|
||||
}
|
||||
|
||||
|
||||
bool BackupManager::extendDatabase(thread_db* tdbb)
|
||||
{
|
||||
ULONG maxPage = 0;
|
||||
{
|
||||
LocalAllocReadGuard localAllocGuard(this);
|
||||
AllocItemTree::Accessor all(alloc_table);
|
||||
|
||||
if (all.getFirst()) {
|
||||
do
|
||||
{
|
||||
const ULONG pg = all.current().db_page;
|
||||
if (maxPage < pg)
|
||||
maxPage = pg;
|
||||
} while (all.getNext());
|
||||
}
|
||||
}
|
||||
|
||||
PageSpace *pgSpace = database->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
||||
ULONG maxAllocPage = pgSpace->maxAlloc(database->dbb_page_size);
|
||||
if (maxAllocPage >= maxPage)
|
||||
return true;
|
||||
|
||||
if (!pgSpace->extend(tdbb, maxPage, true))
|
||||
return false;
|
||||
|
||||
maxAllocPage = pgSpace->maxAlloc(database->dbb_page_size);
|
||||
while (maxAllocPage < maxPage)
|
||||
{
|
||||
const USHORT ret = PIO_init_data(database, pgSpace->file, tdbb->tdbb_status_vector,
|
||||
maxAllocPage, 256);
|
||||
|
||||
if (ret != 256)
|
||||
return false;
|
||||
|
||||
maxAllocPage += ret;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Merge difference file to main files (if needed) and unlink() difference
|
||||
// file then. If merge is already in progress method silently returns and
|
||||
// does nothing (so it can be used for recovery on database startup).
|
||||
@ -398,6 +438,9 @@ void BackupManager::endBackup(thread_db* tdbb, bool recover)
|
||||
endLock.unlockWrite(tdbb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (backup_state == nbak_state_stalled && !extendDatabase(tdbb))
|
||||
status_exception::raise(tdbb->tdbb_status_vector);
|
||||
}
|
||||
|
||||
// Here backup state can be changed. Need to check it again after lock
|
||||
@ -410,6 +453,13 @@ void BackupManager::endBackup(thread_db* tdbb, bool recover)
|
||||
endLock.unlockWrite(tdbb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!extendDatabase(tdbb))
|
||||
{
|
||||
stateGuard.setSuccess();
|
||||
status_exception::raise(tdbb->tdbb_status_vector);
|
||||
}
|
||||
|
||||
header = (Ods::header_page*) window.win_buffer;
|
||||
|
||||
NBAK_TRACE(("difference file %s, current backup state is %d", diff_name.c_str(), backup_state));
|
||||
|
@ -365,7 +365,7 @@ public:
|
||||
void unlockStateWrite(thread_db* tdbb)
|
||||
{
|
||||
tdbb->tdbb_flags &= ~TDBB_backup_write_locked;
|
||||
stateLock->unlockWrite(tdbb);
|
||||
stateLock->unlockWrite(tdbb, backup_state == nbak_state_unknown);
|
||||
}
|
||||
|
||||
bool lockStateRead(thread_db* tdbb, SSHORT wait)
|
||||
@ -464,6 +464,7 @@ private:
|
||||
|
||||
ULONG findPageIndex(thread_db* tdbb, ULONG db_page);
|
||||
void generateFilename();
|
||||
bool extendDatabase(thread_db* tdbb);
|
||||
|
||||
void lockAllocWrite(thread_db* tdbb)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user