Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not allow run concurrent sweep instances #8320

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/include/firebird/impl/msg/jrd.h
Original file line number Diff line number Diff line change
Expand Up @@ -987,4 +987,7 @@ FB_IMPL_MSG(JRD, 984, incompatible_format_patterns, -901, "HY", "000", "@1 incom
FB_IMPL_MSG(JRD, 985, only_one_pattern_can_be_used, -901, "HY", "000", "Can use only one of these patterns @1")
FB_IMPL_MSG(JRD, 986, can_not_use_same_pattern_twice, -901, "HY", "000", "Cannot use the same pattern twice: @1")
FB_IMPL_MSG(JRD, 987, sysf_invalid_gen_uuid_version, -833, "42", "000", "Invalid GEN_UUID version (@1). Must be 4 or 7")
FB_IMPL_MSG(JRD, 988, sweep_concurrent_instance, -901, "42", "000", "Another instance of sweep is already running")
FB_IMPL_MSG(JRD, 988, sweep_unable_to_run, -901, "42", "000", "Unable to run sweep")
FB_IMPL_MSG(JRD, 989, sweep_concurrent_instance, -901, "42", "000", "Another instance of sweep is already running")
FB_IMPL_MSG(JRD, 990, sweep_read_only, -901, "42", "000", "Database in read only state")
FB_IMPL_MSG(JRD, 991, sweep_attach_no_cleanup, -901, "42", "000", "Attachment has no cleanup flag set")
5 changes: 4 additions & 1 deletion src/include/gen/Firebird.pas
Original file line number Diff line number Diff line change
Expand Up @@ -5740,7 +5740,10 @@ IProfilerStatsImpl = class(IProfilerStats)
isc_only_one_pattern_can_be_used = 335545305;
isc_can_not_use_same_pattern_twice = 335545306;
isc_sysf_invalid_gen_uuid_version = 335545307;
isc_sweep_concurrent_instance = 335545308;
isc_sweep_unable_to_run = 335545308;
isc_sweep_concurrent_instance = 335545309;
isc_sweep_read_only = 335545310;
isc_sweep_attach_no_cleanup = 335545311;
isc_gfix_db_name = 335740929;
isc_gfix_invalid_sw = 335740930;
isc_gfix_incmp_sw = 335740932;
Expand Down
28 changes: 17 additions & 11 deletions src/jrd/Database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@

using namespace Firebird;

namespace
{
void unableToRunSweepException(const Arg::Gds& reason)
TreeHunter9 marked this conversation as resolved.
Show resolved Hide resolved
{
ERR_post(Arg::Gds(isc_sweep_unable_to_run) << reason);
}
}

namespace Jrd
{
bool Database::onRawDevice() const
Expand Down Expand Up @@ -299,35 +307,35 @@ namespace Jrd
}
}

bool Database::allowSweepRun(thread_db* tdbb)
void Database::initiateSweepRun(thread_db* tdbb)
{
SPTHR_DEBUG(fprintf(stderr, "allowSweepRun %p\n", this));
SPTHR_DEBUG(fprintf(stderr, FB_FUNCTION " %p\n", this));

if (readOnly())
return false;
unableToRunSweepException(Arg::Gds(isc_sweep_read_only));

Jrd::Attachment* const attachment = tdbb->getAttachment();
if (attachment->att_flags & ATT_no_cleanup)
return false;
unableToRunSweepException(Arg::Gds(isc_sweep_attach_no_cleanup));

while (true)
{
AtomicCounter::counter_type old = dbb_flags;
if (old & DBB_sweep_in_progress)
{
clearSweepStarting();
ERR_post(Arg::Gds(isc_sweep_concurrent_instance));
unableToRunSweepException(Arg::Gds(isc_sweep_concurrent_instance));
}

if (dbb_flags.compareExchange(old, old | DBB_sweep_in_progress))
break;
}

SPTHR_DEBUG(fprintf(stderr, "allowSweepRun - set DBB_sweep_in_progress\n"));
SPTHR_DEBUG(fprintf(stderr, FB_FUNCTION " - set DBB_sweep_in_progress\n"));

if (!(dbb_flags & DBB_sweep_starting))
{
SPTHR_DEBUG(fprintf(stderr, "allowSweepRun - createSweepLock\n"));
SPTHR_DEBUG(fprintf(stderr, FB_FUNCTION " - createSweepLock\n"));

createSweepLock(tdbb);
if (!LCK_lock(tdbb, dbb_sweep_lock, LCK_EX, -1))
Expand All @@ -336,17 +344,15 @@ namespace Jrd
fb_utils::init_status(tdbb->tdbb_status_vector);

dbb_flags &= ~DBB_sweep_in_progress;
ERR_post(Arg::Gds(isc_sweep_concurrent_instance));
unableToRunSweepException(Arg::Gds(isc_sweep_concurrent_instance));
}
}
else
{
SPTHR_DEBUG(fprintf(stderr, "allowSweepRun - clearSweepStarting\n"));
SPTHR_DEBUG(fprintf(stderr, FB_FUNCTION " - clearSweepStarting\n"));
attachment->att_flags |= ATT_from_thread;
clearSweepStarting();
}

return true;
}

void Database::clearSweepFlags(thread_db* tdbb)
Expand Down
5 changes: 2 additions & 3 deletions src/jrd/Database.h
Original file line number Diff line number Diff line change
Expand Up @@ -657,9 +657,8 @@ class Database : public pool_alloc<type_dbb>

// returns true if sweeper thread could start
bool allowSweepThread(thread_db* tdbb);
// Returns true if sweep could run.
// Exception can be thrown if another sweep instance is already running.
bool allowSweepRun(thread_db* tdbb);
// Throw an exception if sweep cannot be run
void initiateSweepRun(thread_db* tdbb);
// reset sweep flag and release sweep lock
void clearSweepFlags(thread_db* tdbb);
// reset sweep starting flag, release thread starting mutex
Expand Down
8 changes: 2 additions & 6 deletions src/jrd/tra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1846,11 +1846,7 @@ void TRA_sweep(thread_db* tdbb)
Database* const dbb = tdbb->getDatabase();
CHECK_DBB(dbb);

if (!dbb->allowSweepRun(tdbb))
{
dbb->clearSweepFlags(tdbb);
return;
}
dbb->initiateSweepRun(tdbb);

fb_assert(dbb->dbb_flags & DBB_sweep_in_progress);

Expand Down Expand Up @@ -2756,7 +2752,7 @@ namespace {
status.check();

AutoRelease<IAttachment> att(prov->attachDatabase(&status, dbName.c_str(), dpbLen, dpbBytes));
if (fb_utils::containsErrorCode(status->getErrors(), isc_sweep_concurrent_instance))
if (fb_utils::containsErrorCode(status->getErrors(), isc_sweep_unable_to_run))
return;

status.check();
Expand Down
Loading