Skip to content

Commit a68deff

Browse files
authored
Merge pull request #8549 from FirebirdSQL/work/gh_6413_restore_swept
Implement #6413 : Data pages of newly gbak restored databases should marked as "swept" [CORE6164]
2 parents cfc1185 + b76cd8b commit a68deff

File tree

7 files changed

+82
-6
lines changed

7 files changed

+82
-6
lines changed

src/burp/BurpTasks.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -902,8 +902,6 @@ void RestoreRelationTask::initItem(BurpGlobals* tdgbl, Item& item)
902902
m_masterGbl->gbl_dpb_data.begin(),
903903
m_masterGbl->gbl_dpb_data.getCount());
904904

905-
dpb.deleteWithTag(isc_dpb_gbak_attach);
906-
907905
const UCHAR* dpbBuffer = dpb.getBuffer();
908906
const USHORT dpbLength = dpb.getBufferLength();
909907

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,3 +997,4 @@ FB_IMPL_MSG(JRD, 994, range_for_by_should_be_positive, -833, "42", "000", "Range
997997
FB_IMPL_MSG(JRD, 995, missing_value_for_format_pattern, -901, "HY", "000", "Cannot find value in input string for \"@1\" pattern")
998998
FB_IMPL_MSG(JRD, 996, invalid_name, -901, "HY", "000", "Invalid name: @1")
999999
FB_IMPL_MSG(JRD, 997, invalid_unqualified_name_list, -901, "HY", "000", "Invalid list of unqualified names: @1")
1000+
FB_IMPL_MSG(JRD, 998, no_user_att_while_restore, -901, "HY", "000", "User attachments are not allowed for the database being restored")

src/include/gen/Firebird.pas

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5838,6 +5838,7 @@ IProfilerStatsImpl = class(IProfilerStats)
58385838
isc_missing_value_for_format_pattern = 335545315;
58395839
isc_invalid_name = 335545316;
58405840
isc_invalid_unqualified_name_list = 335545317;
5841+
isc_no_user_att_while_restore = 335545318;
58415842
isc_gfix_db_name = 335740929;
58425843
isc_gfix_invalid_sw = 335740930;
58435844
isc_gfix_incmp_sw = 335740932;

src/jrd/Database.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,9 @@ 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
233+
const ULONG DBB_restoring = 0x200000L; // Database restore is in progress
233234

234235
//
235236
// dbb_ast_flags
@@ -718,6 +719,19 @@ class Database : public pool_alloc<type_dbb>
718719
dbb_gblobj_holder->decTempCacheUsage(size);
719720
}
720721

722+
bool isRestoring() const
723+
{
724+
return dbb_flags & DBB_restoring;
725+
}
726+
727+
void setRestoring(bool value)
728+
{
729+
if (value)
730+
dbb_flags |= DBB_restoring;
731+
else
732+
dbb_flags &= ~DBB_restoring;
733+
}
734+
721735
private:
722736
//static int blockingAstSharedCounter(void*);
723737
static int blocking_ast_sweep(void* ast_object);

src/jrd/dpm.epp

Lines changed: 44 additions & 3 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

@@ -2232,7 +2237,14 @@ void DPM_store( thread_db* tdbb, record_param* rpb, PageStack& stack, const Jrd:
22322237
memset(data + size, 0, fill);
22332238

22342239
Ods::pag* page = rpb->getWindow(tdbb).win_buffer;
2235-
if (page->pag_flags & dpg_swept)
2240+
2241+
// When restoring, mark primary data page as swept, pointer page already marked by locate_space()
2242+
if (swept_at_restore(tdbb, rpb->rpb_relation) && (type == DPM_primary))
2243+
{
2244+
page->pag_flags |= dpg_swept;
2245+
CCH_RELEASE(tdbb, &rpb->getWindow(tdbb));
2246+
}
2247+
else if (page->pag_flags & dpg_swept)
22362248
{
22372249
page->pag_flags &= ~dpg_swept;
22382250
mark_full(tdbb, rpb);
@@ -3083,7 +3095,13 @@ static void extend_relation(thread_db* tdbb, jrd_rel* relation, WIN* window, con
30833095
UCHAR* bits = (UCHAR*) (ppage->ppg_page + dbb->dbb_dp_per_pp);
30843096
PPG_DP_BIT_CLEAR(bits, slot, PPG_DP_ALL_BITS);
30853097

3086-
if (type != DPM_primary)
3098+
if (type == DPM_primary)
3099+
{
3100+
// When restoring, mark slot as swept, data page will be marked by our caller
3101+
if (swept_at_restore(tdbb, relation))
3102+
PPG_DP_BIT_SET(bits, slot, ppg_dp_swept);
3103+
}
3104+
else
30873105
PPG_DP_BIT_SET(bits, slot, ppg_dp_secondary);
30883106

30893107
for (unsigned i = 1; i < cntAlloc; i++)
@@ -3536,7 +3554,13 @@ static rhd* locate_space(thread_db* tdbb,
35363554

35373555
PPG_DP_BIT_CLEAR(bits, slot, ppg_dp_empty);
35383556
if (type == DPM_primary)
3557+
{
35393558
PPG_DP_BIT_CLEAR(bits, slot, ppg_dp_secondary);
3559+
3560+
// When restoring, mark slot as swept, data page will be marked by our caller
3561+
if (swept_at_restore(tdbb, relation))
3562+
PPG_DP_BIT_SET(bits, slot, ppg_dp_swept);
3563+
}
35403564
else
35413565
PPG_DP_BIT_SET(bits, slot, ppg_dp_secondary);
35423566

@@ -3918,11 +3942,28 @@ static void store_big_record(thread_db* tdbb,
39183942
header->rhdf_b_page, header->rhdf_b_line);
39193943
#endif
39203944

3945+
3946+
bool markPP = false;
3947+
3948+
// When restoring, mark primary data page as swept, pointer page already marked by locate_space()
3949+
if (swept_at_restore(tdbb, rpb->rpb_relation) && (type == DPM_primary))
3950+
{
3951+
page->dpg_header.pag_flags |= dpg_swept;
3952+
}
3953+
else if (page->dpg_header.pag_flags & dpg_swept)
3954+
{
3955+
page->dpg_header.pag_flags &= ~dpg_swept;
3956+
markPP = true;
3957+
}
3958+
39213959
if (!(page->dpg_header.pag_flags & dpg_large))
39223960
{
39233961
page->dpg_header.pag_flags |= dpg_large;
3924-
mark_full(tdbb, rpb);
3962+
markPP = true;
39253963
}
3964+
3965+
if (markPP)
3966+
mark_full(tdbb, rpb);
39263967
else
39273968
CCH_RELEASE(tdbb, &rpb->getWindow(tdbb));
39283969
}

src/jrd/jrd.cpp

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

1947+
if (dbb->isRestoring())
1948+
{
1949+
if (!options.dpb_gbak_attach && !options.dpb_map_attach && !options.dpb_worker_attach)
1950+
ERR_post(Arg::Gds(isc_no_user_att_while_restore));
1951+
}
1952+
19471953
// Basic DBB initialization complete
19481954
initGuard.leave();
19491955

@@ -3145,6 +3151,8 @@ JAttachment* JProvider::createDatabase(CheckStatusWrapper* user_status, const ch
31453151

31463152
// Initialize the global objects
31473153
dbb->initGlobalObjects();
3154+
if (attachment->isGbak())
3155+
dbb->setRestoring(true);
31483156

31493157
// Initialize locks
31503158
LCK_init(tdbb, LCK_OWNER_database);
@@ -7973,6 +7981,9 @@ void release_attachment(thread_db* tdbb, Jrd::Attachment* attachment, XThreadEns
79737981
if (!other)
79747982
sync.lock(SYNC_EXCLUSIVE);
79757983

7984+
if (attachment->att_flags & ATT_creator)
7985+
dbb->setRestoring(false);
7986+
79767987
// remove the attachment block from the dbb linked list
79777988
for (Jrd::Attachment** ptr = &dbb->dbb_attachments; *ptr; ptr = &(*ptr)->att_next)
79787989
{

src/jrd/shut.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ union shutdown_data
5252
SLONG data_long;
5353
};
5454

55+
// Low byte of shutdown_data::flag used by shutdown modes, see isc_dpb_shut_XXX
56+
// High byte used for additional flags
57+
58+
const SSHORT SHUT_flag_restoring = 0x0100; // database restore is in progress
5559

5660
// Define this to true if you need to allow no-op behavior when requested shutdown mode
5761
// matches current. Logic of jrd8_create_database may need attention in this case too
@@ -122,6 +126,9 @@ bool SHUT_blocking_ast(thread_db* tdbb, bool ast)
122126
return false;
123127
}
124128

129+
if (flag & SHUT_flag_restoring)
130+
dbb->setRestoring(true);
131+
125132
if ((flag & isc_dpb_shut_force) && !delay)
126133
return shutdown(tdbb, flag, ast);
127134

@@ -472,6 +479,9 @@ static bool notify_shutdown(thread_db* tdbb, SSHORT flag, SSHORT delay, Sync* gu
472479
data.data_items.flag = flag;
473480
data.data_items.delay = delay;
474481

482+
if (dbb->isRestoring())
483+
data.data_items.flag |= SHUT_flag_restoring;
484+
475485
LCK_write_data(tdbb, dbb->dbb_lock, data.data_long);
476486

477487
{ // scope

0 commit comments

Comments
 (0)