Skip to content

Implement #6413 : Data pages of newly gbak restored databases should marked as "swept" [CORE6164] #8549

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

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

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implement a "database restoring" state, disallow user attachments for…
… the restoring database, extract commonly used function swept_at_restore() as Ilya Eremin (@ilya071294) suggested.
  • Loading branch information
hvlad committed May 16, 2025
commit 2f3c2de0f18be0bc3490a608f17c9b4ec780ea7b
1 change: 1 addition & 0 deletions src/include/firebird/impl/msg/jrd.h
Original file line number Diff line number Diff line change
Expand Up @@ -995,3 +995,4 @@ FB_IMPL_MSG(JRD, 992, invalid_timezone_region_or_displacement, -901, "HY", "000"
FB_IMPL_MSG(JRD, 993, argmustbe_exact_range_for, -833, "42", "000", "Arguments for range-based FOR must be exact numeric types")
FB_IMPL_MSG(JRD, 994, range_for_by_should_be_positive, -833, "42", "000", "Range-based FOR BY argument must be positive")
FB_IMPL_MSG(JRD, 995, missing_value_for_format_pattern, -901, "HY", "000", "Cannot find value in input string for \"@1\" pattern")
FB_IMPL_MSG(JRD, 996, no_user_att_while_restore, -901, "HY", "000", "User attachments are not allowed for the database being restoring")
19 changes: 17 additions & 2 deletions src/jrd/Database.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ const ULONG DBB_new = 0x8000L; // Database object is just created
const ULONG DBB_gc_cooperative = 0x10000L; // cooperative garbage collection
const ULONG DBB_gc_background = 0x20000L; // background garbage collection by gc_thread
const ULONG DBB_sweep_starting = 0x40000L; // Auto-sweep is starting
const ULONG DBB_creating = 0x80000L; // Database creation is in progress
const ULONG DBB_creating = 0x80000L; // Database creation is in progress
const ULONG DBB_shared = 0x100000L; // Database object is shared among connections

//
Expand Down Expand Up @@ -311,6 +311,9 @@ class Database : public pool_alloc<type_dbb>
bool incTempCacheUsage(FB_SIZE_T size);
void decTempCacheUsage(FB_SIZE_T size);

bool getRestoring() const { return m_restoring; }
void setRestoring(bool value) { m_restoring = value; }

private:
const Firebird::string m_id;
const Firebird::RefPtr<const Firebird::Config> m_config;
Expand All @@ -321,14 +324,16 @@ class Database : public pool_alloc<type_dbb>
Firebird::Mutex m_mutex;
std::atomic<FB_UINT64> m_tempCacheUsage; // total size of in-memory temp space chunks (see TempSpace class)
const FB_UINT64 m_tempCacheLimit;
bool m_restoring;

explicit GlobalObjectHolder(const Firebird::string& id,
const Firebird::PathName& filename,
Firebird::RefPtr<const Firebird::Config> config)
: m_id(getPool(), id), m_config(config),
m_replConfig(Replication::Config::get(filename)),
m_tempCacheUsage(0),
m_tempCacheLimit(m_config->getTempCacheLimit())
m_tempCacheLimit(m_config->getTempCacheLimit()),
m_restoring(false)
{}
};

Expand Down Expand Up @@ -718,6 +723,16 @@ class Database : public pool_alloc<type_dbb>
dbb_gblobj_holder->decTempCacheUsage(size);
}

bool isRestoring() const
{
return dbb_gblobj_holder->getRestoring();
}

void setRestoring(bool value)
{
dbb_gblobj_holder->setRestoring(value);
}

private:
//static int blockingAstSharedCounter(void*);
static int blocking_ast_sweep(void* ast_object);
Expand Down
13 changes: 9 additions & 4 deletions src/jrd/dpm.epp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ namespace

return lock.release();
}

inline bool swept_at_restore(thread_db* tdbb, const jrd_rel* relation)
{
return tdbb->getDatabase()->isRestoring() && !relation->isSystem();
}
}


Expand Down Expand Up @@ -2234,7 +2239,7 @@ void DPM_store( thread_db* tdbb, record_param* rpb, PageStack& stack, const Jrd:
Ods::pag* page = rpb->getWindow(tdbb).win_buffer;

// When restoring, mark primary data page as swept, pointer page already marked by locate_space()
if (tdbb->getAttachment()->isGbak() && !rpb->rpb_relation->isSystem() && (type == DPM_primary))
if (swept_at_restore(tdbb, rpb->rpb_relation) && (type == DPM_primary))
{
page->pag_flags |= dpg_swept;
CCH_RELEASE(tdbb, &rpb->getWindow(tdbb));
Expand Down Expand Up @@ -3093,7 +3098,7 @@ static void extend_relation(thread_db* tdbb, jrd_rel* relation, WIN* window, con
if (type == DPM_primary)
{
// When restoring, mark slot as swept, data page will be marked by our caller
if (tdbb->getAttachment()->isGbak() && !relation->isSystem())
if (swept_at_restore(tdbb, relation))
PPG_DP_BIT_SET(bits, slot, ppg_dp_swept);
}
else
Expand Down Expand Up @@ -3553,7 +3558,7 @@ static rhd* locate_space(thread_db* tdbb,
PPG_DP_BIT_CLEAR(bits, slot, ppg_dp_secondary);

// When restoring, mark slot as swept, data page will be marked by our caller
if (tdbb->getAttachment()->isGbak() && !relation->isSystem())
if (swept_at_restore(tdbb, relation))
PPG_DP_BIT_SET(bits, slot, ppg_dp_swept);
}
else
Expand Down Expand Up @@ -3941,7 +3946,7 @@ static void store_big_record(thread_db* tdbb,
bool markPP = false;

// When restoring, mark primary data page as swept, pointer page already marked by locate_space()
if (tdbb->getAttachment()->isGbak() && !rpb->rpb_relation->isSystem() && (type == DPM_primary))
if (swept_at_restore(tdbb, rpb->rpb_relation) && (type == DPM_primary))
{
page->dpg_header.pag_flags |= dpg_swept;
}
Expand Down
11 changes: 11 additions & 0 deletions src/jrd/jrd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1913,6 +1913,12 @@ JAttachment* JProvider::internalAttach(CheckStatusWrapper* user_status, const ch
dbb->dbb_crypto_manager->attach(tdbb, attachment);
}

if (dbb->isRestoring())
{
if (!options.dpb_gbak_attach && !options.dpb_map_attach && !options.dpb_worker_attach)
ERR_post(Arg::Gds(isc_no_user_att_while_restore));
}

// Basic DBB initialization complete
initGuard.leave();

Expand Down Expand Up @@ -3105,6 +3111,8 @@ JAttachment* JProvider::createDatabase(CheckStatusWrapper* user_status, const ch

// Initialize the global objects
dbb->initGlobalObjects();
if (attachment->isGbak())
dbb->setRestoring(true);

// Initialize locks
LCK_init(tdbb, LCK_OWNER_database);
Expand Down Expand Up @@ -7894,6 +7902,9 @@ void release_attachment(thread_db* tdbb, Jrd::Attachment* attachment, XThreadEns
if (!other)
sync.lock(SYNC_EXCLUSIVE);

if (attachment->att_flags & ATT_creator)
dbb->setRestoring(false);

// remove the attachment block from the dbb linked list
for (Jrd::Attachment** ptr = &dbb->dbb_attachments; *ptr; ptr = &(*ptr)->att_next)
{
Expand Down
Loading