Skip to content

Commit 93db880

Browse files
authored
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 9b8ac53 commit 93db880

26 files changed

+406
-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
@@ -260,7 +260,7 @@ namespace Jrd
260260
while (true)
261261
{
262262
AtomicCounter::counter_type old = dbb_flags;
263-
if ((old & (DBB_sweep_in_progress | DBB_sweep_starting)) || (dbb_ast_flags & DBB_shutdown))
263+
if ((old & (DBB_sweep_in_progress | DBB_sweep_starting)) || isShutdown())
264264
{
265265
dbb_thread_mutex.leave();
266266
return false;

src/jrd/Database.h

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -237,12 +237,9 @@ const ULONG DBB_shared = 0x100000L; // Database object is shared among conne
237237
const ULONG DBB_blocking = 0x1L; // Exclusive mode is blocking
238238
const ULONG DBB_get_shadows = 0x2L; // Signal received to check for new shadows
239239
const ULONG DBB_assert_locks = 0x4L; // Locks are to be asserted
240-
const ULONG DBB_shutdown = 0x8L; // Database is shutdown
241-
const ULONG DBB_shut_attach = 0x10L; // no new attachments accepted
242-
const ULONG DBB_shut_tran = 0x20L; // no new transactions accepted
243-
const ULONG DBB_shut_force = 0x40L; // forced shutdown in progress
244-
const ULONG DBB_shutdown_full = 0x80L; // Database fully shut down
245-
const ULONG DBB_shutdown_single = 0x100L; // Database is in single-user maintenance mode
240+
const ULONG DBB_shut_attach = 0x8L; // No new attachments accepted
241+
const ULONG DBB_shut_tran = 0x10L; // No new transactions accepted
242+
const ULONG DBB_shut_force = 0x20L; // Forced shutdown in progress
246243

247244
class Database : public pool_alloc<type_dbb>
248245
{
@@ -472,6 +469,7 @@ class Database : public pool_alloc<type_dbb>
472469
Firebird::RWLock dbb_ast_lock; // avoids delivering AST to going away database
473470
Firebird::AtomicCounter dbb_ast_flags; // flags modified at AST level
474471
Firebird::AtomicCounter dbb_flags;
472+
std::atomic<shut_mode_t> dbb_shutdown_mode; // shutdown mode
475473
USHORT dbb_ods_version; // major ODS version number
476474
USHORT dbb_minor_version; // minor ODS version number
477475
USHORT dbb_page_size; // page size
@@ -540,7 +538,7 @@ class Database : public pool_alloc<type_dbb>
540538
Lock* dbb_repl_lock; // replication state lock
541539
Firebird::SyncObject dbb_repl_sync;
542540
FB_UINT64 dbb_repl_sequence; // replication sequence
543-
ReplicaMode dbb_replica_mode; // replica access mode
541+
std::atomic<ReplicaMode> dbb_replica_mode; // replica access mode
544542

545543
unsigned dbb_compatibility_index; // datatype backward compatibility level
546544
Dictionary dbb_dic; // metanames dictionary
@@ -576,14 +574,24 @@ class Database : public pool_alloc<type_dbb>
576574

577575
void registerModule(Module&);
578576

577+
bool isShutdown() const
578+
{
579+
return (dbb_shutdown_mode.load(std::memory_order_relaxed) != shut_mode_online);
580+
}
581+
582+
bool isShutdown(shut_mode_t mode) const
583+
{
584+
return (dbb_shutdown_mode.load(std::memory_order_relaxed) == mode);
585+
}
586+
579587
bool isReplica() const
580588
{
581-
return (dbb_replica_mode != REPLICA_NONE);
589+
return (dbb_replica_mode.load(std::memory_order_relaxed) != REPLICA_NONE);
582590
}
583591

584592
bool isReplica(ReplicaMode mode) const
585593
{
586-
return (dbb_replica_mode == mode);
594+
return (dbb_replica_mode.load(std::memory_order_relaxed) == mode);
587595
}
588596

589597
USHORT getEncodedOdsVersion() const
@@ -605,6 +613,7 @@ class Database : public pool_alloc<type_dbb>
605613
dbb_modules(*p),
606614
dbb_extManager(nullptr),
607615
dbb_flags(shared ? DBB_shared : 0),
616+
dbb_shutdown_mode(shut_mode_online),
608617
dbb_filename(*p),
609618
dbb_database_name(*p),
610619
#ifdef HAVE_ID_BY_NAME

src/jrd/Monitoring.cpp

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

839839
// Determine the backup state
840-
int backup_state = backup_state_unknown;
840+
int backupState = backup_state_unknown;
841841

842-
BackupManager* const bm = dbb->dbb_backup_manager;
842+
const auto bm = dbb->dbb_backup_manager;
843843

844844
if (bm && !bm->isShutDown())
845845
{
@@ -848,14 +848,16 @@ void Monitoring::putDatabase(thread_db* tdbb, SnapshotData::DumpRecord& record)
848848
switch (bm->getState())
849849
{
850850
case Ods::hdr_nbak_normal:
851-
backup_state = backup_state_normal;
851+
backupState = backup_state_normal;
852852
break;
853853
case Ods::hdr_nbak_stalled:
854-
backup_state = backup_state_stalled;
854+
backupState = backup_state_stalled;
855855
break;
856856
case Ods::hdr_nbak_merge:
857-
backup_state = backup_state_merge;
857+
backupState = backup_state_merge;
858858
break;
859+
default:
860+
fb_assert(false);
859861
}
860862
}
861863

@@ -886,18 +888,8 @@ void Monitoring::putDatabase(thread_db* tdbb, SnapshotData::DumpRecord& record)
886888
// SQL dialect
887889
temp = (dbb->dbb_flags & DBB_DB_SQL_dialect_3) ? 3 : 1;
888890
record.storeInteger(f_mon_db_dialect, temp);
889-
890891
// shutdown mode
891-
if (dbb->dbb_ast_flags & DBB_shutdown_full)
892-
temp = shut_mode_full;
893-
else if (dbb->dbb_ast_flags & DBB_shutdown_single)
894-
temp = shut_mode_single;
895-
else if (dbb->dbb_ast_flags & DBB_shutdown)
896-
temp = shut_mode_multi;
897-
else
898-
temp = shut_mode_online;
899-
record.storeInteger(f_mon_db_shut_mode, temp);
900-
892+
record.storeInteger(f_mon_db_shut_mode, dbb->dbb_shutdown_mode);
901893
// sweep interval
902894
record.storeInteger(f_mon_db_sweep_int, dbb->dbb_sweep_interval);
903895
// read only flag
@@ -914,7 +906,7 @@ void Monitoring::putDatabase(thread_db* tdbb, SnapshotData::DumpRecord& record)
914906
// database size
915907
record.storeInteger(f_mon_db_pages, PageSpace::actAlloc(dbb));
916908
// database backup state
917-
record.storeInteger(f_mon_db_backup_state, backup_state);
909+
record.storeInteger(f_mon_db_backup_state, backupState);
918910

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

src/jrd/SysFunction.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4611,13 +4611,13 @@ dsc* evlGetContext(thread_db* tdbb, const SysFunction*, const NestValueArray& ar
46114611
}
46124612
else if (nameStr == REPLICA_MODE)
46134613
{
4614-
if (dbb->dbb_replica_mode == REPLICA_READ_ONLY)
4614+
if (dbb->isReplica(REPLICA_READ_ONLY))
46154615
resultStr = RO_VALUE;
4616-
else if (dbb->dbb_replica_mode == REPLICA_READ_WRITE)
4616+
else if (dbb->isReplica(REPLICA_READ_WRITE))
46174617
resultStr = RW_VALUE;
46184618
else
46194619
{
4620-
fb_assert(dbb->dbb_replica_mode == REPLICA_NONE);
4620+
fb_assert(!dbb->isReplica());
46214621
return NULL;
46224622
}
46234623
}
@@ -4997,8 +4997,8 @@ dsc* evlGetTranCN(thread_db* tdbb, const SysFunction* function, const NestValueA
49974997
if ((traNum > traMax) && !(dbb->dbb_flags & DBB_shared))
49984998
{
49994999
WIN window(HEADER_PAGE_NUMBER);
5000-
const Ods::header_page* header = (Ods::header_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_header);
5001-
traMax = Ods::getNT(header);
5000+
const auto header = (const Ods::header_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_header);
5001+
traMax = header->hdr_next_transaction;
50025002
CCH_RELEASE(tdbb, &window);
50035003
}
50045004

0 commit comments

Comments
 (0)