Skip to content

Commit 48ea282

Browse files
dyemanovAlexPeshkoff
authored andcommitted
ODS14: header page refactoring (#8401)
* Make counters natively 64-bit, simplify the related code * Group implementation bytes together * Refactor backup/shutdown/replica flags into dedicated modes * Misc cleanup * Misc * Move database GUID to the core header part * A bit denser header layout. This also should fix alignment incompatibility between 32-bit and 64-bit builds spotted by the CI workflow.
1 parent 0f8e19d commit 48ea282

26 files changed

+405
-544
lines changed

src/common/classes/DbImplementation.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ const UCHAR backEndianess[FB_NELEM(hardware)] =
146146
namespace Firebird {
147147

148148
DbImplementation::DbImplementation(const Ods::header_page* h)
149-
: di_cpu(h->hdr_cpu), di_os(h->hdr_os), di_cc(h->hdr_cc), di_flags(h->hdr_compatibility_flags)
149+
: di_cpu(h->hdr_db_impl.hdr_cpu), di_os(h->hdr_db_impl.hdr_os),
150+
di_cc(h->hdr_db_impl.hdr_cc), di_flags(h->hdr_db_impl.hdr_compat)
150151
{
151152
}
152153

@@ -196,10 +197,10 @@ bool DbImplementation::compatible(const DbImplementation& v) const
196197

197198
void DbImplementation::store(Ods::header_page* h) const
198199
{
199-
h->hdr_cpu = di_cpu;
200-
h->hdr_os = di_os;
201-
h->hdr_cc = di_cc;
202-
h->hdr_compatibility_flags = di_flags;
200+
h->hdr_db_impl.hdr_cpu = di_cpu;
201+
h->hdr_db_impl.hdr_os = di_os;
202+
h->hdr_db_impl.hdr_cc = di_cc;
203+
h->hdr_db_impl.hdr_compat = di_flags;
203204
}
204205

205206
void DbImplementation::stuff(UCHAR** info) const
@@ -224,7 +225,7 @@ DbImplementation DbImplementation::fromBackwardCompatibleByte(UCHAR bcImpl)
224225
{
225226
for (UCHAR hw = 0; hw < FB_NELEM(hardware); ++hw)
226227
{
227-
USHORT ind = USHORT(os) * FB_NELEM(hardware) + USHORT(hw);
228+
const USHORT ind = USHORT(os) * FB_NELEM(hardware) + USHORT(hw);
228229
if (backwardTable[ind] == bcImpl)
229230
{
230231
return DbImplementation(hw, os, 0xFF, backEndianess[hw] ? EndianBig : EndianLittle);

src/common/classes/DbImplementation.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,13 @@ class DbImplementation
3838
{
3939
public:
4040
explicit DbImplementation(const Ods::header_page* h);
41-
DbImplementation (UCHAR p_cpu, UCHAR p_os, UCHAR p_cc, UCHAR p_flags)
41+
42+
DbImplementation(UCHAR p_cpu, UCHAR p_os, UCHAR p_cc, UCHAR p_flags)
4243
: di_cpu(p_cpu), di_os(p_os), di_cc(p_cc), di_flags(p_flags)
4344
{ }
44-
~DbImplementation() { }
45+
46+
~DbImplementation()
47+
{ }
4548

4649
private:
4750
UCHAR di_cpu, di_os, di_cc, di_flags;

src/jrd/CryptoManager.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,11 @@
5454

5555
using namespace Firebird;
5656

57-
namespace {
57+
namespace
58+
{
5859
THREAD_ENTRY_DECLARE cryptThreadStatic(THREAD_ENTRY_PARAM p)
5960
{
60-
Jrd::CryptoManager* cryptoManager = (Jrd::CryptoManager*) p;
61+
const auto cryptoManager = (Jrd::CryptoManager*) p;
6162
cryptoManager->cryptThread();
6263

6364
return 0;
@@ -68,12 +69,12 @@ namespace {
6869
const UCHAR CRYPT_CHANGE = LCK_PW;
6970
const UCHAR CRYPT_INIT = LCK_EX;
7071

71-
const int MAX_PLUGIN_NAME_LEN = 31;
72+
constexpr int MAX_PLUGIN_NAME_LEN = sizeof(Ods::header_page::hdr_crypt_plugin) - 1;
7273
}
7374

7475

75-
namespace Jrd {
76-
76+
namespace Jrd
77+
{
7778
class Header
7879
{
7980
protected:
@@ -553,10 +554,10 @@ namespace Jrd {
553554

554555
const bool newCryptState = plugName.hasData();
555556

556-
int bak_state = Ods::hdr_nbak_unknown;
557+
auto backupState = Ods::hdr_nbak_unknown;
557558
{ // scope
558559
BackupManager::StateReadGuard stateGuard(tdbb);
559-
bak_state = dbb.dbb_backup_manager->getState();
560+
backupState = dbb.dbb_backup_manager->getState();
560561
}
561562

562563
{ // window scope
@@ -574,7 +575,7 @@ namespace Jrd {
574575
(Arg::Gds(isc_cp_already_crypted)).raise();
575576
}
576577

577-
if (bak_state != Ods::hdr_nbak_normal)
578+
if (backupState != Ods::hdr_nbak_normal)
578579
{
579580
(Arg::Gds(isc_wish_list) << Arg::Gds(isc_random) <<
580581
"Cannot crypt: please wait for nbackup completion").raise();
@@ -625,9 +626,9 @@ namespace Jrd {
625626

626627
void CryptoManager::changeCryptState(thread_db* tdbb, const string& plugName)
627628
{
628-
if (plugName.length() > 31)
629+
if (plugName.length() > MAX_PLUGIN_NAME_LEN)
629630
{
630-
(Arg::Gds(isc_cp_name_too_long) << Arg::Num(31)).raise();
631+
(Arg::Gds(isc_cp_name_too_long) << Arg::Num(MAX_PLUGIN_NAME_LEN)).raise();
631632
}
632633

633634
const bool newCryptState = plugName.hasData();
@@ -656,8 +657,8 @@ namespace Jrd {
656657

657658
// Nbak's lock was taken in prepareChangeCryptState()
658659
// If it was invalidated it's enough reason not to continue now
659-
int bak_state = dbb.dbb_backup_manager->getState();
660-
if (bak_state != Ods::hdr_nbak_normal)
660+
auto backupState = dbb.dbb_backup_manager->getState();
661+
if (backupState != Ods::hdr_nbak_normal)
661662
{
662663
(Arg::Gds(isc_wish_list) << Arg::Gds(isc_random) <<
663664
"Cannot crypt: please wait for nbackup completion").raise();
@@ -669,7 +670,7 @@ namespace Jrd {
669670
(Arg::Gds(isc_cp_process_active)).raise();
670671
}
671672

672-
bool headerCryptState = hdr->hdr_flags & Ods::hdr_encrypted;
673+
const bool headerCryptState = hdr->hdr_flags & Ods::hdr_encrypted;
673674
if (headerCryptState == newCryptState)
674675
{
675676
(Arg::Gds(isc_cp_already_crypted)).raise();
@@ -1085,13 +1086,13 @@ namespace Jrd {
10851086
JRD_reschedule(tdbb);
10861087

10871088
// nbackup state check
1088-
int bak_state = Ods::hdr_nbak_unknown;
1089+
auto backupState = Ods::hdr_nbak_unknown;
10891090
{ // scope
10901091
BackupManager::StateReadGuard stateGuard(tdbb);
1091-
bak_state = dbb.dbb_backup_manager->getState();
1092+
backupState = dbb.dbb_backup_manager->getState();
10921093
}
10931094

1094-
if (bak_state != Ods::hdr_nbak_normal)
1095+
if (backupState != Ods::hdr_nbak_normal)
10951096
{
10961097
EngineCheckout checkout(tdbb, FB_FUNCTION);
10971098
Thread::sleep(10);

src/jrd/Database.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ namespace Jrd
269269
while (true)
270270
{
271271
AtomicCounter::counter_type old = dbb_flags;
272-
if ((old & (DBB_sweep_in_progress | DBB_sweep_starting)) || (dbb_ast_flags & DBB_shutdown))
272+
if ((old & (DBB_sweep_in_progress | DBB_sweep_starting)) || isShutdown())
273273
{
274274
dbb_thread_mutex.leave();
275275
return false;

src/jrd/Database.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,9 @@ const ULONG DBB_rescan_pages = 0x200000L; // Rescan pages after TIP cache crea
136136
const ULONG DBB_blocking = 0x1L; // Exclusive mode is blocking
137137
const ULONG DBB_get_shadows = 0x2L; // Signal received to check for new shadows
138138
const ULONG DBB_assert_locks = 0x4L; // Locks are to be asserted
139-
const ULONG DBB_shutdown = 0x8L; // Database is shutdown
140-
const ULONG DBB_shut_attach = 0x10L; // no new attachments accepted
141-
const ULONG DBB_shut_tran = 0x20L; // no new transactions accepted
142-
const ULONG DBB_shut_force = 0x40L; // forced shutdown in progress
143-
const ULONG DBB_shutdown_full = 0x80L; // Database fully shut down
144-
const ULONG DBB_shutdown_single = 0x100L; // Database is in single-user maintenance mode
139+
const ULONG DBB_shut_attach = 0x8L; // No new attachments accepted
140+
const ULONG DBB_shut_tran = 0x10L; // No new transactions accepted
141+
const ULONG DBB_shut_force = 0x20L; // Forced shutdown in progress
145142

146143
class Database : public pool_alloc<type_dbb>
147144
{
@@ -377,6 +374,7 @@ class Database : public pool_alloc<type_dbb>
377374
Firebird::RWLock dbb_ast_lock; // avoids delivering AST to going away database
378375
Firebird::AtomicCounter dbb_ast_flags; // flags modified at AST level
379376
Firebird::AtomicCounter dbb_flags;
377+
std::atomic<shut_mode_t> dbb_shutdown_mode; // shutdown mode
380378
USHORT dbb_ods_version; // major ODS version number
381379
USHORT dbb_minor_version; // minor ODS version number
382380
USHORT dbb_page_size; // page size
@@ -445,7 +443,7 @@ class Database : public pool_alloc<type_dbb>
445443
Lock* dbb_repl_lock; // replication state lock
446444
Firebird::SyncObject dbb_repl_sync;
447445
FB_UINT64 dbb_repl_sequence; // replication sequence
448-
ReplicaMode dbb_replica_mode; // replica access mode
446+
std::atomic<ReplicaMode> dbb_replica_mode; // replica access mode
449447

450448
unsigned dbb_compatibility_index; // datatype backward compatibility level
451449
Dictionary dbb_dic; // metanames dictionary
@@ -475,14 +473,24 @@ class Database : public pool_alloc<type_dbb>
475473

476474
void registerModule(Module&);
477475

476+
bool isShutdown() const
477+
{
478+
return (dbb_shutdown_mode.load(std::memory_order_relaxed) != shut_mode_online);
479+
}
480+
481+
bool isShutdown(shut_mode_t mode) const
482+
{
483+
return (dbb_shutdown_mode.load(std::memory_order_relaxed) == mode);
484+
}
485+
478486
bool isReplica() const
479487
{
480-
return (dbb_replica_mode != REPLICA_NONE);
488+
return (dbb_replica_mode.load(std::memory_order_relaxed) != REPLICA_NONE);
481489
}
482490

483491
bool isReplica(ReplicaMode mode) const
484492
{
485-
return (dbb_replica_mode == mode);
493+
return (dbb_replica_mode.load(std::memory_order_relaxed) == mode);
486494
}
487495

488496
USHORT getEncodedOdsVersion() const

src/jrd/Monitoring.cpp

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -838,9 +838,9 @@ void Monitoring::putDatabase(thread_db* tdbb, SnapshotData::DumpRecord& record)
838838
record.reset(rel_mon_database);
839839

840840
// Determine the backup state
841-
int backup_state = backup_state_unknown;
841+
int backupState = backup_state_unknown;
842842

843-
BackupManager* const bm = dbb->dbb_backup_manager;
843+
const auto bm = dbb->dbb_backup_manager;
844844

845845
if (bm && !bm->isShutDown())
846846
{
@@ -849,14 +849,16 @@ void Monitoring::putDatabase(thread_db* tdbb, SnapshotData::DumpRecord& record)
849849
switch (bm->getState())
850850
{
851851
case Ods::hdr_nbak_normal:
852-
backup_state = backup_state_normal;
852+
backupState = backup_state_normal;
853853
break;
854854
case Ods::hdr_nbak_stalled:
855-
backup_state = backup_state_stalled;
855+
backupState = backup_state_stalled;
856856
break;
857857
case Ods::hdr_nbak_merge:
858-
backup_state = backup_state_merge;
858+
backupState = backup_state_merge;
859859
break;
860+
default:
861+
fb_assert(false);
860862
}
861863
}
862864

@@ -887,18 +889,8 @@ void Monitoring::putDatabase(thread_db* tdbb, SnapshotData::DumpRecord& record)
887889
// SQL dialect
888890
temp = (dbb->dbb_flags & DBB_DB_SQL_dialect_3) ? 3 : 1;
889891
record.storeInteger(f_mon_db_dialect, temp);
890-
891892
// shutdown mode
892-
if (dbb->dbb_ast_flags & DBB_shutdown_full)
893-
temp = shut_mode_full;
894-
else if (dbb->dbb_ast_flags & DBB_shutdown_single)
895-
temp = shut_mode_single;
896-
else if (dbb->dbb_ast_flags & DBB_shutdown)
897-
temp = shut_mode_multi;
898-
else
899-
temp = shut_mode_online;
900-
record.storeInteger(f_mon_db_shut_mode, temp);
901-
893+
record.storeInteger(f_mon_db_shut_mode, dbb->dbb_shutdown_mode);
902894
// sweep interval
903895
record.storeInteger(f_mon_db_sweep_int, dbb->dbb_sweep_interval);
904896
// read only flag
@@ -915,7 +907,7 @@ void Monitoring::putDatabase(thread_db* tdbb, SnapshotData::DumpRecord& record)
915907
// database size
916908
record.storeInteger(f_mon_db_pages, PageSpace::actAlloc(dbb));
917909
// database backup state
918-
record.storeInteger(f_mon_db_backup_state, backup_state);
910+
record.storeInteger(f_mon_db_backup_state, backupState);
919911

920912
// crypt thread status
921913
if (dbb->dbb_crypto_manager)

src/jrd/SysFunction.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4612,13 +4612,13 @@ dsc* evlGetContext(thread_db* tdbb, const SysFunction*, const NestValueArray& ar
46124612
}
46134613
else if (nameStr == REPLICA_MODE)
46144614
{
4615-
if (dbb->dbb_replica_mode == REPLICA_READ_ONLY)
4615+
if (dbb->isReplica(REPLICA_READ_ONLY))
46164616
resultStr = RO_VALUE;
4617-
else if (dbb->dbb_replica_mode == REPLICA_READ_WRITE)
4617+
else if (dbb->isReplica(REPLICA_READ_WRITE))
46184618
resultStr = RW_VALUE;
46194619
else
46204620
{
4621-
fb_assert(dbb->dbb_replica_mode == REPLICA_NONE);
4621+
fb_assert(!dbb->isReplica());
46224622
return NULL;
46234623
}
46244624
}
@@ -4998,8 +4998,8 @@ dsc* evlGetTranCN(thread_db* tdbb, const SysFunction* function, const NestValueA
49984998
if ((traNum > traMax) && !(dbb->dbb_flags & DBB_shared))
49994999
{
50005000
WIN window(HEADER_PAGE_NUMBER);
5001-
const Ods::header_page* header = (Ods::header_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_header);
5002-
traMax = Ods::getNT(header);
5001+
const auto header = (const Ods::header_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_header);
5002+
traMax = header->hdr_next_transaction;
50035003
CCH_RELEASE(tdbb, &window);
50045004
}
50055005

0 commit comments

Comments
 (0)