8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:03:02 +01:00

WIP - shared system requests cache

This commit is contained in:
AlexPeshkoff 2024-04-02 20:14:52 +03:00
parent abc7273eb6
commit 07ac45ee66
9 changed files with 83 additions and 75 deletions

View File

@ -200,8 +200,6 @@ Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb, JProvider* provider
att_active_snapshots(*pool),
att_statements(*pool),
att_requests(*pool),
att_internal(*pool),
att_dyn_req(*pool),
att_lock_owner_id(Database::getLockOwnerId()),
att_backup_state_counter(0),
att_stats(*pool),
@ -238,10 +236,7 @@ Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb, JProvider* provider
att_batches(*pool),
att_initial_options(*pool),
att_provider(provider)
{
att_internal.grow(irq_MAX);
att_dyn_req.grow(drq_MAX);
}
{ }
Jrd::Attachment::~Attachment()
@ -896,43 +891,6 @@ int Attachment::blockingAstReplSet(void* ast_object)
return 0;
}
// Find an inactive incarnation of a system request. If necessary, clone it.
Jrd::Request* Attachment::findSystemRequest(thread_db* tdbb, USHORT id, InternalRequest which)
{
static const int MAX_RECURSION = 100;
// If the request hasn't been compiled or isn't active, there're nothing to do.
//Database::CheckoutLockGuard guard(this, dbb_cmp_clone_mutex);
fb_assert(which == IRQ_REQUESTS || which == DYN_REQUESTS);
Statement* statement = (which == IRQ_REQUESTS ? att_internal[id] : att_dyn_req[id]);
if (!statement)
return NULL;
// Look for requests until we find one that is available.
for (int n = 0;; ++n)
{
if (n > MAX_RECURSION)
{
ERR_post(Arg::Gds(isc_no_meta_update) <<
Arg::Gds(isc_req_depth_exceeded) << Arg::Num(MAX_RECURSION));
// Msg363 "request depth exceeded. (Recursive definition?)"
}
Request* clone = statement->getRequest(tdbb, n);
if (!(clone->req_flags & (req_active | req_reserved)))
{
clone->req_flags |= req_reserved;
return clone;
}
}
}
ProfilerManager* Attachment::getProfilerManager(thread_db* tdbb)
{
auto profilerManager = att_profiler_manager.get();

View File

@ -527,8 +527,6 @@ private:
public:
Firebird::SortedArray<Statement*> att_statements; // Statements belonging to attachment
Firebird::SortedArray<Request*> att_requests; // Requests belonging to attachment
Firebird::Array<Statement*> att_internal; // internal statements
Firebird::Array<Statement*> att_dyn_req; // internal dyn statements
Lock* att_id_lock; // Attachment lock (if any)
AttNumber att_attachment_id; // Attachment ID
@ -614,9 +612,6 @@ public:
jrd_tra* getSysTransaction();
void setSysTransaction(jrd_tra* trans); // used only by TRA_init
void cacheRequest(InternalRequest which, USHORT id, Statement* stmt);
Request* findSystemRequest(thread_db* tdbb, USHORT id, InternalRequest which);
bool isSystem() const
{
return (att_flags & ATT_system);

View File

@ -41,6 +41,7 @@
#include "../jrd/os/pio_proto.h"
#include "../common/os/os_utils.h"
#include "../jrd/met.h"
#include "../jrd/Statement.h"
// Thread data block
#include "../common/ThreadData.h"
@ -469,6 +470,49 @@ namespace Jrd
dbb_filename, dbb_config));
}
// Find an inactive incarnation of a system request.
Request* Database::findSystemRequest(thread_db* tdbb, USHORT id, InternalRequest which)
{
fb_assert(which == IRQ_REQUESTS || which == DYN_REQUESTS);
//Database::CheckoutLockGuard guard(this, dbb_cmp_clone_mutex);
// If the request hasn't been compiled or isn't active, there're nothing to do.
auto* stPtr = &(which == IRQ_REQUESTS ? dbb_internal : dbb_dyn_req)[id];
Statement* statement = stPtr->load(std::memory_order_relaxed);
if (!statement)
return NULL;
return statement->findRequest(tdbb);
}
// Store newly compiled request in the cache
Request* Database::cacheRequest(InternalRequest which, USHORT id, Request* req)
{
auto* const stPtr = &(which == IRQ_REQUESTS ? dbb_internal : dbb_dyn_req)[id];
Statement* existingStmt = stPtr->load(std::memory_order_acquire);
Statement* const compiledStmt = req->getStatement();
if (!existingStmt)
{
if (stPtr->compare_exchange_strong(existingStmt, compiledStmt,
std::memory_order_release, std::memory_order_acquire))
{
return req;
}
}
// Someone else already stored system request in the cache
// Let's use it
fb_assert(existingStmt);
thread_db* tdbb = JRD_get_thread_data();
compiledStmt->release(tdbb);
return existingStmt->findRequest(tdbb);
}
// Database::Linger class implementation
void Database::Linger::handler()
@ -598,6 +642,8 @@ namespace Jrd
dbb_page_manager(this, *p),
dbb_file_id(*p),
dbb_modules(*p),
dbb_internal(*p),
dbb_dyn_req(*p),
dbb_extManager(nullptr),
dbb_flags(shared ? DBB_shared : 0),
dbb_filename(*p),
@ -625,6 +671,9 @@ namespace Jrd
dbb_mdc(FB_NEW_POOL(*p) MetadataCache(*p))
{
dbb_pools.add(p);
dbb_internal.grow(irq_MAX);
dbb_dyn_req.grow(drq_MAX);
}

View File

@ -103,6 +103,10 @@ public:
static void destroy(KeywordsMap* inst);
};
// Flags to indicate normal internal requests vs. dyn internal requests
enum InternalRequest : USHORT {
NOT_REQUEST, IRQ_REQUESTS, DYN_REQUESTS
};
//
// bit values for dbb_flags
@ -357,6 +361,9 @@ private:
DatabaseModules dbb_modules; // external function/filter modules
public:
Firebird::Array<std::atomic<Statement*>> dbb_internal; // internal statements
Firebird::Array<std::atomic<Statement*>> dbb_dyn_req; // internal dyn statements
Firebird::AutoPtr<ExtEngineManager> dbb_extManager; // external engine manager
Firebird::SyncObject dbb_flush_count_mutex;
@ -554,6 +561,9 @@ public:
return dbb_gblobj_holder->getReplConfig();
}
Request* findSystemRequest(thread_db* tdbb, USHORT id, InternalRequest which);
Request* cacheRequest(InternalRequest which, USHORT id, Request* req);
private:
//static int blockingAstSharedCounter(void*);
static int blocking_ast_sweep(void* ast_object);

View File

@ -165,13 +165,13 @@ RelationPermanent::RelationPermanent(thread_db* tdbb, MemoryPool& p, MetaId id,
rel_rescan_lock = FB_NEW_RPT(getPool(), 0)
Lock(tdbb, sizeof(SLONG), LCK_rel_rescan, this, rescan_ast_relation);
rel_rescan_lock->setKey(rel_id);
/*
if (rel_id >= rel_MAX)
{
rel_existence_lock = FB_NEW_RPT(getPool(), 0)
Lock(tdbb, sizeof(SLONG), LCK_rel_exist, this, blocking_ast_relation);
rel_existence_lock->setKey(rel_id);
}
} */
}
RelationPermanent::~RelationPermanent()

View File

@ -740,7 +740,7 @@ public:
static int partners_ast_relation(void* ast_object);
static int rescan_ast_relation(void* ast_object);
static int blocking_ast_relation(void* ast_object);
// static int blocking_ast_relation(void* ast_object);
vec<Format*>* rel_formats; // Known record formats
IndexLocks rel_index_locks; // index existence locks

View File

@ -1684,8 +1684,8 @@ static void trigger_failure(thread_db* tdbb, Request* trigger)
void AutoCacheRequest::cacheRequest()
{
Jrd::Attachment* att = JRD_get_thread_data()->getAttachment();
att->cacheRequest(which, id, request->getStatement());
Jrd::Database* dbb = JRD_get_thread_data()->getDatabase();
request = dbb->cacheRequest(which, id, request);
}
void AutoCacheRequest::release()

View File

@ -31,12 +31,7 @@ namespace Jrd {
class jrd_tra;
class AssignmentNode;
//
// Flags to indicate normal internal requests vs. dyn internal requests
//
enum InternalRequest : USHORT {
NOT_REQUEST, IRQ_REQUESTS, DYN_REQUESTS
};
enum InternalRequest : USHORT;
}
void EXE_assignment(Jrd::thread_db*, const Jrd::AssignmentNode*);
@ -71,7 +66,7 @@ namespace Jrd
AutoCacheRequest(thread_db* tdbb, USHORT aId, InternalRequest aWhich)
: id(aId),
which(aWhich),
request(tdbb->getAttachment()->findSystemRequest(tdbb, id, which))
request(tdbb->getDatabase()->findSystemRequest(tdbb, id, which))
{
}
@ -94,7 +89,7 @@ namespace Jrd
id = aId;
which = aWhich;
request = tdbb->getAttachment()->findSystemRequest(tdbb, id, which);
request = tdbb->getDatabase()->findSystemRequest(tdbb, id, which);
}
void compile(thread_db* tdbb, const UCHAR* blr, ULONG blrLength)

View File

@ -7564,20 +7564,6 @@ void release_attachment(thread_db* tdbb, Jrd::Attachment* attachment, XThreadEns
Monitoring::cleanupAttachment(tdbb);
// release the system requests
for (auto* itr : attachment->att_internal)
{
if (itr)
itr->release(tdbb);
}
for (auto* itr : attachment->att_dyn_req)
{
if (itr)
itr->release(tdbb);
}
dbb->dbb_extManager->closeAttachment(tdbb, attachment);
if (dbb->dbb_config->getServerMode() == MODE_SUPER)
@ -7821,6 +7807,21 @@ bool JRD_shutdown_database(Database* dbb, const unsigned flags)
return false;
}
// Release the system requests
for (auto& itr : dbb->dbb_internal)
{
auto* stmt = itr.load(std::memory_order_relaxed);
if (stmt)
stmt->release(tdbb);
}
for (auto& itr : dbb->dbb_dyn_req)
{
auto* stmt = itr.load(std::memory_order_relaxed);
if (stmt)
stmt->release(tdbb);
}
// Database linger
if ((flags & SHUT_DBB_LINGER) &&
(!(engineShutdown || (dbb->dbb_ast_flags & DBB_shutdown))) &&