Skip to content

Commit 2f3c2de

Browse files
committed
Implement a "database restoring" state, disallow user attachments for the restoring database, extract commonly used function swept_at_restore() as Ilya Eremin (@ilya071294) suggested.
1 parent 564c98b commit 2f3c2de

File tree

4 files changed

+38
-6
lines changed

4 files changed

+38
-6
lines changed

src/include/firebird/impl/msg/jrd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,3 +995,4 @@ FB_IMPL_MSG(JRD, 992, invalid_timezone_region_or_displacement, -901, "HY", "000"
995995
FB_IMPL_MSG(JRD, 993, argmustbe_exact_range_for, -833, "42", "000", "Arguments for range-based FOR must be exact numeric types")
996996
FB_IMPL_MSG(JRD, 994, range_for_by_should_be_positive, -833, "42", "000", "Range-based FOR BY argument must be positive")
997997
FB_IMPL_MSG(JRD, 995, missing_value_for_format_pattern, -901, "HY", "000", "Cannot find value in input string for \"@1\" pattern")
998+
FB_IMPL_MSG(JRD, 996, no_user_att_while_restore, -901, "HY", "000", "User attachments are not allowed for the database being restoring")

src/jrd/Database.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ const ULONG DBB_new = 0x8000L; // Database object is just created
228228
const ULONG DBB_gc_cooperative = 0x10000L; // cooperative garbage collection
229229
const ULONG DBB_gc_background = 0x20000L; // background garbage collection by gc_thread
230230
const ULONG DBB_sweep_starting = 0x40000L; // Auto-sweep is starting
231-
const ULONG DBB_creating = 0x80000L; // Database creation is in progress
231+
const ULONG DBB_creating = 0x80000L; // Database creation is in progress
232232
const ULONG DBB_shared = 0x100000L; // Database object is shared among connections
233233

234234
//
@@ -311,6 +311,9 @@ class Database : public pool_alloc<type_dbb>
311311
bool incTempCacheUsage(FB_SIZE_T size);
312312
void decTempCacheUsage(FB_SIZE_T size);
313313

314+
bool getRestoring() const { return m_restoring; }
315+
void setRestoring(bool value) { m_restoring = value; }
316+
314317
private:
315318
const Firebird::string m_id;
316319
const Firebird::RefPtr<const Firebird::Config> m_config;
@@ -321,14 +324,16 @@ class Database : public pool_alloc<type_dbb>
321324
Firebird::Mutex m_mutex;
322325
std::atomic<FB_UINT64> m_tempCacheUsage; // total size of in-memory temp space chunks (see TempSpace class)
323326
const FB_UINT64 m_tempCacheLimit;
327+
bool m_restoring;
324328

325329
explicit GlobalObjectHolder(const Firebird::string& id,
326330
const Firebird::PathName& filename,
327331
Firebird::RefPtr<const Firebird::Config> config)
328332
: m_id(getPool(), id), m_config(config),
329333
m_replConfig(Replication::Config::get(filename)),
330334
m_tempCacheUsage(0),
331-
m_tempCacheLimit(m_config->getTempCacheLimit())
335+
m_tempCacheLimit(m_config->getTempCacheLimit()),
336+
m_restoring(false)
332337
{}
333338
};
334339

@@ -718,6 +723,16 @@ class Database : public pool_alloc<type_dbb>
718723
dbb_gblobj_holder->decTempCacheUsage(size);
719724
}
720725

726+
bool isRestoring() const
727+
{
728+
return dbb_gblobj_holder->getRestoring();
729+
}
730+
731+
void setRestoring(bool value)
732+
{
733+
dbb_gblobj_holder->setRestoring(value);
734+
}
735+
721736
private:
722737
//static int blockingAstSharedCounter(void*);
723738
static int blocking_ast_sweep(void* ast_object);

src/jrd/dpm.epp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ namespace
100100

101101
return lock.release();
102102
}
103+
104+
inline bool swept_at_restore(thread_db* tdbb, const jrd_rel* relation)
105+
{
106+
return tdbb->getDatabase()->isRestoring() && !relation->isSystem();
107+
}
103108
}
104109

105110

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

22362241
// When restoring, mark primary data page as swept, pointer page already marked by locate_space()
2237-
if (tdbb->getAttachment()->isGbak() && !rpb->rpb_relation->isSystem() && (type == DPM_primary))
2242+
if (swept_at_restore(tdbb, rpb->rpb_relation) && (type == DPM_primary))
22382243
{
22392244
page->pag_flags |= dpg_swept;
22402245
CCH_RELEASE(tdbb, &rpb->getWindow(tdbb));
@@ -3093,7 +3098,7 @@ static void extend_relation(thread_db* tdbb, jrd_rel* relation, WIN* window, con
30933098
if (type == DPM_primary)
30943099
{
30953100
// When restoring, mark slot as swept, data page will be marked by our caller
3096-
if (tdbb->getAttachment()->isGbak() && !relation->isSystem())
3101+
if (swept_at_restore(tdbb, relation))
30973102
PPG_DP_BIT_SET(bits, slot, ppg_dp_swept);
30983103
}
30993104
else
@@ -3553,7 +3558,7 @@ static rhd* locate_space(thread_db* tdbb,
35533558
PPG_DP_BIT_CLEAR(bits, slot, ppg_dp_secondary);
35543559

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

39433948
// When restoring, mark primary data page as swept, pointer page already marked by locate_space()
3944-
if (tdbb->getAttachment()->isGbak() && !rpb->rpb_relation->isSystem() && (type == DPM_primary))
3949+
if (swept_at_restore(tdbb, rpb->rpb_relation) && (type == DPM_primary))
39453950
{
39463951
page->dpg_header.pag_flags |= dpg_swept;
39473952
}

src/jrd/jrd.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1913,6 +1913,12 @@ JAttachment* JProvider::internalAttach(CheckStatusWrapper* user_status, const ch
19131913
dbb->dbb_crypto_manager->attach(tdbb, attachment);
19141914
}
19151915

1916+
if (dbb->isRestoring())
1917+
{
1918+
if (!options.dpb_gbak_attach && !options.dpb_map_attach && !options.dpb_worker_attach)
1919+
ERR_post(Arg::Gds(isc_no_user_att_while_restore));
1920+
}
1921+
19161922
// Basic DBB initialization complete
19171923
initGuard.leave();
19181924

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

31063112
// Initialize the global objects
31073113
dbb->initGlobalObjects();
3114+
if (attachment->isGbak())
3115+
dbb->setRestoring(true);
31083116

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

7905+
if (attachment->att_flags & ATT_creator)
7906+
dbb->setRestoring(false);
7907+
78977908
// remove the attachment block from the dbb linked list
78987909
for (Jrd::Attachment** ptr = &dbb->dbb_attachments; *ptr; ptr = &(*ptr)->att_next)
78997910
{

0 commit comments

Comments
 (0)