Skip to content

Improvement #7928 : Make TempCacheLimit setting to be per-database, (not per-attachment) for SuperClassic. #7930

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/jrd/Database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,8 @@ namespace Jrd
m_replMgr = nullptr;

delete entry;

fb_assert(m_tempCacheUsage == 0);
}

LockManager* Database::GlobalObjectHolder::getLockManager()
Expand Down Expand Up @@ -580,6 +582,28 @@ namespace Jrd
return m_replMgr;
}

bool Database::GlobalObjectHolder::incTempCacheUsage(FB_SIZE_T size)
{
if (m_tempCacheUsage + size > m_tempCacheLimit)
return false;

const auto old = m_tempCacheUsage.fetch_add(size);
if (old + size > m_tempCacheLimit)
{
m_tempCacheUsage.fetch_sub(size);
return false;
}

return true;
}

void Database::GlobalObjectHolder::decTempCacheUsage(FB_SIZE_T size)
{
fb_assert(m_tempCacheUsage >= size);

m_tempCacheUsage.fetch_sub(size);
}

GlobalPtr<Database::GlobalObjectHolder::DbIdHash>
Database::GlobalObjectHolder::g_hashTable;
GlobalPtr<Mutex> Database::GlobalObjectHolder::g_mutex;
Expand Down
22 changes: 18 additions & 4 deletions src/jrd/Database.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,9 @@ class Database : public pool_alloc<type_dbb>
return m_replConfig.get();
}

bool incTempCacheUsage(FB_SIZE_T size);
void decTempCacheUsage(FB_SIZE_T size);

private:
const Firebird::string m_id;
const Firebird::RefPtr<const Firebird::Config> m_config;
Expand All @@ -326,12 +329,16 @@ class Database : public pool_alloc<type_dbb>
Firebird::AutoPtr<EventManager> m_eventMgr;
Firebird::AutoPtr<Replication::Manager> m_replMgr;
Firebird::Mutex m_mutex;
std::atomic<FB_UINT64> m_tempCacheUsage; // total size of in-memory temp space chunks (see TempSpace class)
const FB_UINT64 m_tempCacheLimit;

explicit GlobalObjectHolder(const Firebird::string& id,
const Firebird::PathName& filename,
Firebird::RefPtr<const Firebird::Config> config)
: m_id(getPool(), id), m_config(config),
m_replConfig(Replication::Config::get(filename))
m_replConfig(Replication::Config::get(filename)),
m_tempCacheUsage(0),
m_tempCacheLimit(m_config->getTempCacheLimit())
{}
};

Expand Down Expand Up @@ -495,9 +502,6 @@ class Database : public pool_alloc<type_dbb>
Firebird::SyncObject dbb_sortbuf_sync;
Firebird::Array<UCHAR*> dbb_sort_buffers; // sort buffers ready for reuse

Firebird::Mutex dbb_temp_cache_mutex;
FB_UINT64 dbb_temp_cache_size; // total size of in-memory temp space chunks (see TempSpace class)

TraNumber dbb_oldest_active; // Cached "oldest active" transaction
TraNumber dbb_oldest_transaction; // Cached "oldest interesting" transaction
TraNumber dbb_oldest_snapshot; // Cached "oldest snapshot" of all active transactions
Expand Down Expand Up @@ -683,6 +687,16 @@ class Database : public pool_alloc<type_dbb>
return dbb_gblobj_holder->getReplConfig();
}

bool incTempCacheUsage(FB_SIZE_T size)
{
return dbb_gblobj_holder->incTempCacheUsage(size);
}

void decTempCacheUsage(FB_SIZE_T size)
{
dbb_gblobj_holder->decTempCacheUsage(size);
}

private:
//static int blockingAstSharedCounter(void*);
static int blocking_ast_sweep(void* ast_object);
Expand Down
45 changes: 24 additions & 21 deletions src/jrd/TempSpace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,36 +49,35 @@ namespace
class TempCacheLimitGuard
{
public:
explicit TempCacheLimitGuard(FB_SIZE_T size)
: m_dbb(GET_DBB()), m_size(size),
m_guard(m_dbb->dbb_temp_cache_mutex, FB_FUNCTION)
{
m_allowed = (m_dbb->dbb_temp_cache_size + size <= m_dbb->dbb_config->getTempCacheLimit());
}
explicit TempCacheLimitGuard(Database* dbb) :
m_dbb(dbb),
m_size(0)
{}

bool isAllowed() const
~TempCacheLimitGuard()
{
return m_allowed;
if (m_size)
m_dbb->decTempCacheUsage(m_size);
}

void increment()
bool reserve(FB_SIZE_T size)
{
fb_assert(m_allowed);
m_dbb->dbb_temp_cache_size += m_size;
if (m_dbb->incTempCacheUsage(size))
{
m_size = size;
return true;
}
return false;
}

static void decrement(FB_SIZE_T size)
void commit()
{
Database* const dbb = GET_DBB();
MutexLockGuard guard(dbb->dbb_temp_cache_mutex, FB_FUNCTION);
dbb->dbb_temp_cache_size -= size;
m_size = 0;
}

private:
Database* const m_dbb;
FB_SIZE_T m_size;
MutexLockGuard m_guard;
bool m_allowed;
};
}

Expand Down Expand Up @@ -175,7 +174,11 @@ TempSpace::~TempSpace()
head = temp;
}

TempCacheLimitGuard::decrement(localCacheUsage);
if (localCacheUsage)
{
Database* const dbb = GET_DBB();
dbb->decTempCacheUsage(localCacheUsage);
}

while (tempFiles.getCount())
delete tempFiles.pop();
Expand Down Expand Up @@ -312,16 +315,16 @@ void TempSpace::extend(FB_SIZE_T size)
Block* block = NULL;

{ // scope
TempCacheLimitGuard guard(size);
TempCacheLimitGuard guard(GET_DBB());

if (guard.isAllowed())
if (guard.reserve(size))
{
try
{
// allocate block in virtual memory
block = FB_NEW_POOL(pool) MemoryBlock(FB_NEW_POOL(pool) UCHAR[size], tail, size);
localCacheUsage += size;
guard.increment();
guard.commit();
}
catch (const BadAlloc&)
{
Expand Down