mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 00:03:03 +01:00
Add config file parameter for the garbage collection policy
This commit is contained in:
parent
4bdf9211fb
commit
aba34753cb
@ -40,6 +40,15 @@ typedef Firebird::PathName string;
|
||||
* Configuration entries
|
||||
*/
|
||||
|
||||
const char* GCPolicyCooperative = "cooperative";
|
||||
const char* GCPolicyBackground = "background";
|
||||
const char* GCPolicyCombined = "combined";
|
||||
#ifdef SUPERSERVER
|
||||
const char* GCPolicyDefault = GCPolicyCombined;
|
||||
#else
|
||||
const char* GCPolicyDefault = GCPolicyCooperative;
|
||||
#endif
|
||||
|
||||
const ConfigImpl::ConfigEntry ConfigImpl::entries[] =
|
||||
{
|
||||
{TYPE_STRING, "RootDirectory", (ConfigValue) 0},
|
||||
@ -114,7 +123,8 @@ const ConfigImpl::ConfigEntry ConfigImpl::entries[] =
|
||||
{TYPE_BOOLEAN, "BugcheckAbort", (ConfigValue) false}, // whether to abort() engine when internal error is found
|
||||
#endif
|
||||
{TYPE_INTEGER, "TraceDSQL", (ConfigValue) 0}, // bitmask
|
||||
{TYPE_BOOLEAN, "LegacyHash", (ConfigValue) false} // let use old passwd hash verification
|
||||
{TYPE_BOOLEAN, "LegacyHash", (ConfigValue) false}, // let use old passwd hash verification
|
||||
{TYPE_STRING, "GCPolicy", (ConfigValue) GCPolicyDefault} // garbage collection policy
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
@ -488,3 +498,8 @@ bool Config::getLegacyHash()
|
||||
{
|
||||
return (bool) sysConfig.values[KEY_LEGACY_HASH];
|
||||
}
|
||||
|
||||
const char *Config::getGCPolicy()
|
||||
{
|
||||
return (const char *) sysConfig.values[KEY_GC_POLICY];
|
||||
}
|
||||
|
@ -58,6 +58,11 @@
|
||||
in config.cpp module.
|
||||
**/
|
||||
|
||||
extern const char* GCPolicyCooperative;
|
||||
extern const char* GCPolicyBackground;
|
||||
extern const char* GCPolicyCombined;
|
||||
extern const char* GCPolicyDefault;
|
||||
|
||||
class Config
|
||||
{
|
||||
enum ConfigKey
|
||||
@ -106,7 +111,8 @@ class Config
|
||||
KEY_TEMP_DIRECTORIES, // 40
|
||||
KEY_BUGCHECK_ABORT, // 41
|
||||
KEY_TRACE_DSQL, // 42
|
||||
KEY_LEGACY_HASH // 43
|
||||
KEY_LEGACY_HASH, // 43
|
||||
KEY_GC_POLICY // 44
|
||||
};
|
||||
|
||||
public:
|
||||
@ -330,6 +336,11 @@ public:
|
||||
Let use of des hash to verify passwords
|
||||
*/
|
||||
static bool getLegacyHash();
|
||||
|
||||
/*
|
||||
GC policy
|
||||
*/
|
||||
static const char *getGCPolicy();
|
||||
};
|
||||
|
||||
namespace Firebird {
|
||||
|
@ -5490,6 +5490,34 @@ static Database* init(thread_db* tdbb,
|
||||
dbb->dbb_flags |= DBB_exclusive;
|
||||
dbb->dbb_sweep_interval = SWEEP_INTERVAL;
|
||||
|
||||
/* set a garbage collection policy */
|
||||
|
||||
if ((dbb->dbb_flags & (DBB_gc_cooperative | DBB_gc_background)) == 0)
|
||||
{
|
||||
const char* gc_policy = Config::getGCPolicy();
|
||||
if (stricmp(gc_policy, GCPolicyCooperative) == 0) {
|
||||
dbb->dbb_flags |= DBB_gc_cooperative;
|
||||
}
|
||||
else if (stricmp(gc_policy, GCPolicyBackground) == 0) {
|
||||
dbb->dbb_flags |= DBB_gc_background;
|
||||
}
|
||||
else if (stricmp(gc_policy, GCPolicyCombined) == 0) {
|
||||
dbb->dbb_flags |= DBB_gc_cooperative | DBB_gc_background;
|
||||
}
|
||||
else // config value is invalid, use default
|
||||
if (stricmp(GCPolicyDefault, GCPolicyCooperative) == 0) {
|
||||
dbb->dbb_flags |= DBB_gc_cooperative;
|
||||
}
|
||||
else if (stricmp(GCPolicyDefault, GCPolicyBackground) == 0) {
|
||||
dbb->dbb_flags |= DBB_gc_background;
|
||||
}
|
||||
else if (stricmp(GCPolicyDefault, GCPolicyCombined) == 0) {
|
||||
dbb->dbb_flags |= DBB_gc_cooperative | DBB_gc_background;
|
||||
}
|
||||
else
|
||||
fb_assert(false);
|
||||
};
|
||||
|
||||
/* Initialize a number of subsystems */
|
||||
|
||||
TRA_init(tdbb);
|
||||
|
@ -335,7 +335,8 @@ const ULONG DBB_security_db = 0x80000L; /* ISC security database */
|
||||
const ULONG DBB_sweep_thread_started = 0x100000L; /* A database sweep thread has been started */
|
||||
const ULONG DBB_suspend_bgio = 0x200000L; /* Suspend I/O by background threads */
|
||||
const ULONG DBB_being_opened = 0x400000L; /* database is being attached to */
|
||||
|
||||
const ULONG DBB_gc_cooperative = 0x0800000L; /* cooperative garbage collection */
|
||||
const ULONG DBB_gc_background = 0x1000000L; /* background garbage collection by gc_thread */
|
||||
//
|
||||
// dbb_ast_flags
|
||||
//
|
||||
@ -633,9 +634,6 @@ typedef Firebird::ObjectsArray<Trigger> trig_vec;
|
||||
|
||||
#ifdef GARBAGE_THREAD
|
||||
|
||||
#define GC_NOTIFY_ON_WRITE
|
||||
//#define GC_NOTIFY_ON_READ
|
||||
|
||||
class RelationGarbage
|
||||
{
|
||||
private:
|
||||
|
@ -95,7 +95,7 @@ const int DEFAULT_LOCK_TIMEOUT = -1; // infinite
|
||||
using namespace Jrd;
|
||||
using namespace Ods;
|
||||
|
||||
#if defined(GARBAGE_THREAD) && defined(GC_NOTIFY_ON_WRITE)
|
||||
#ifdef GARBAGE_THREAD
|
||||
#include "../jrd/isc_s_proto.h"
|
||||
#endif
|
||||
|
||||
@ -1662,8 +1662,10 @@ jrd_tra* TRA_start(thread_db* tdbb, int tpb_length, const SCHAR* tpb)
|
||||
if (trans->tra_oldest_active > dbb->dbb_oldest_snapshot) {
|
||||
dbb->dbb_oldest_snapshot = trans->tra_oldest_active;
|
||||
|
||||
#if defined(GARBAGE_THREAD) && defined(GC_NOTIFY_ON_WRITE)
|
||||
if (!(dbb->dbb_flags & DBB_gc_active)) {
|
||||
#if defined(GARBAGE_THREAD)
|
||||
if (!(dbb->dbb_flags & DBB_gc_active) &&
|
||||
(dbb->dbb_flags & DBB_gc_background) )
|
||||
{
|
||||
dbb->dbb_flags |= DBB_gc_pending;
|
||||
ISC_event_post(dbb->dbb_gc_event);
|
||||
}
|
||||
|
@ -496,6 +496,9 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb, RecordSource*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
const bool gcPolicyCooperative = tdbb->tdbb_database->dbb_flags & DBB_gc_cooperative;
|
||||
const bool gcPolicyBackground = tdbb->tdbb_database->dbb_flags & DBB_gc_background;
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_TRACE_ALL) {
|
||||
printf
|
||||
@ -547,8 +550,8 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb, RecordSource*
|
||||
(rpb->rpb_b_page == 0 ||
|
||||
rpb->rpb_transaction_nr >= transaction->tra_oldest_active))
|
||||
{
|
||||
#if defined(GARBAGE_THREAD) && defined(GC_NOTIFY_ON_WRITE)
|
||||
if (rpb->rpb_b_page)
|
||||
#ifdef GARBAGE_THREAD
|
||||
if (gcPolicyBackground && rpb->rpb_b_page)
|
||||
notify_garbage_collector(tdbb, rpb);
|
||||
#endif // GARBAGE_THREAD
|
||||
|
||||
@ -877,8 +880,8 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb, RecordSource*
|
||||
if (rpb->rpb_transaction_nr < transaction->tra_oldest_active &&
|
||||
!(attachment->att_flags & ATT_no_cleanup))
|
||||
{
|
||||
#if defined(GARBAGE_THREAD) && defined(GC_NOTIFY_ON_READ)
|
||||
if (attachment->att_flags & ATT_notify_gc) {
|
||||
#ifdef GARBAGE_THREAD
|
||||
if (!gcPolicyCooperative && (attachment->att_flags & ATT_notify_gc)) {
|
||||
notify_garbage_collector(tdbb, rpb);
|
||||
CCH_RELEASE(tdbb, &rpb->rpb_window);
|
||||
}
|
||||
@ -900,15 +903,16 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb, RecordSource*
|
||||
might interfere with the updater (prepare_update, update_in_place...).
|
||||
That might be the reason for the rpb_chained check. */
|
||||
|
||||
bool cannotGC =
|
||||
const bool cannotGC =
|
||||
rpb->rpb_transaction_nr >= transaction->tra_oldest_active ||
|
||||
rpb->rpb_b_page == 0 ||
|
||||
rpb->rpb_flags & rpb_chained ||
|
||||
attachment->att_flags & ATT_no_cleanup;
|
||||
|
||||
if (cannotGC) {
|
||||
#if defined(GARBAGE_THREAD) && defined(GC_NOTIFY_ON_WRITE)
|
||||
if (attachment->att_flags & (ATT_notify_gc | ATT_garbage_collector) &&
|
||||
#ifdef GARBAGE_THREAD
|
||||
if (gcPolicyBackground &&
|
||||
attachment->att_flags & (ATT_notify_gc | ATT_garbage_collector) &&
|
||||
(rpb->rpb_b_page != 0 && !(rpb->rpb_flags & rpb_chained)) )
|
||||
{
|
||||
// VIO_chase_record_version
|
||||
@ -920,8 +924,8 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb, RecordSource*
|
||||
|
||||
/* Garbage collect. */
|
||||
|
||||
#if defined(GARBAGE_THREAD) && defined(GC_NOTIFY_ON_READ)
|
||||
if (attachment->att_flags & ATT_notify_gc) {
|
||||
#ifdef GARBAGE_THREAD
|
||||
if (!gcPolicyCooperative && (attachment->att_flags & ATT_notify_gc)) {
|
||||
notify_garbage_collector(tdbb, rpb);
|
||||
return true;
|
||||
}
|
||||
@ -1508,9 +1512,10 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
transaction->tra_flags |= TRA_perform_autocommit;
|
||||
}
|
||||
|
||||
#if defined(GARBAGE_THREAD) && defined(GC_NOTIFY_ON_WRITE)
|
||||
#ifdef GARBAGE_THREAD
|
||||
// VIO_erase
|
||||
notify_garbage_collector(tdbb, rpb, transaction->tra_number);
|
||||
if (tdbb->tdbb_database->dbb_flags | DBB_gc_background)
|
||||
notify_garbage_collector(tdbb, rpb, transaction->tra_number);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2057,7 +2062,8 @@ void VIO_init(thread_db* tdbb)
|
||||
Database* dbb = tdbb->tdbb_database;
|
||||
Attachment* attachment = tdbb->tdbb_attachment;
|
||||
|
||||
if (dbb->dbb_flags & DBB_read_only) {
|
||||
if ((dbb->dbb_flags & DBB_read_only) ||
|
||||
!(dbb->dbb_flags & DBB_gc_background) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2378,9 +2384,10 @@ void VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb,
|
||||
transaction->tra_flags |= TRA_perform_autocommit;
|
||||
}
|
||||
|
||||
#if defined(GARBAGE_THREAD) && defined(GC_NOTIFY_ON_WRITE)
|
||||
#ifdef GARBAGE_THREAD
|
||||
// VIO_modify
|
||||
notify_garbage_collector(tdbb, org_rpb, transaction->tra_number);
|
||||
if (tdbb->tdbb_database->dbb_flags | DBB_gc_background)
|
||||
notify_garbage_collector(tdbb, org_rpb, transaction->tra_number);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -3494,9 +3501,10 @@ static void expunge(thread_db* tdbb, record_param* rpb,
|
||||
/* Re-fetch the record */
|
||||
|
||||
if (!DPM_get(tdbb, rpb, LCK_write)) {
|
||||
#if defined(GARBAGE_THREAD) && defined(GC_NOTIFY_ON_WRITE)
|
||||
#ifdef GARBAGE_THREAD
|
||||
// expunge
|
||||
notify_garbage_collector(tdbb, rpb);
|
||||
if (tdbb->tdbb_database->dbb_flags | DBB_gc_background)
|
||||
notify_garbage_collector(tdbb, rpb);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@ -3517,9 +3525,10 @@ static void expunge(thread_db* tdbb, record_param* rpb,
|
||||
rpb->rpb_transaction_nr >= transaction->tra_oldest_active)
|
||||
{
|
||||
|
||||
#if defined(GARBAGE_THREAD) && defined(GC_NOTIFY_ON_WRITE)
|
||||
#ifdef GARBAGE_THREAD
|
||||
// expunge
|
||||
notify_garbage_collector(tdbb, rpb);
|
||||
if (tdbb->tdbb_database->dbb_flags | DBB_gc_background)
|
||||
notify_garbage_collector(tdbb, rpb);
|
||||
#endif
|
||||
|
||||
CCH_RELEASE(tdbb, &rpb->rpb_window);
|
||||
@ -4120,9 +4129,6 @@ static void notify_garbage_collector(thread_db* tdbb, record_param* rpb, SLONG t
|
||||
ContextPoolHolder context(tdbb, dbb->dbb_permanent);
|
||||
const SLONG dp_sequence = rpb->rpb_number.getValue() / dbb->dbb_max_records;
|
||||
|
||||
#if !defined(GC_NOTIFY_ON_WRITE)
|
||||
PBM_SET(tdbb->getDefaultPool(), &relation->rel_gc_bitmap, dp_sequence);
|
||||
#else
|
||||
if (!relation->rel_garbage) {
|
||||
relation->rel_garbage =
|
||||
FB_NEW(*tdbb->getDefaultPool()) RelationGarbage(*tdbb->getDefaultPool());
|
||||
@ -4132,7 +4138,6 @@ static void notify_garbage_collector(thread_db* tdbb, record_param* rpb, SLONG t
|
||||
|
||||
if (tranid > relation->rel_garbage->minTranID())
|
||||
tranid = relation->rel_garbage->minTranID();
|
||||
#endif // GC_NOTIFY_ON_WRITE
|
||||
|
||||
/* If the garbage collector isn't active then poke
|
||||
the event on which it sleeps to awaken it. */
|
||||
@ -4574,9 +4579,10 @@ static void purge(thread_db* tdbb, record_param* rpb)
|
||||
if (!DPM_get(tdbb, rpb, LCK_write)) {
|
||||
gc_rec->rec_flags &= ~REC_gc_active;
|
||||
|
||||
#if defined(GARBAGE_THREAD) && defined(GC_NOTIFY_ON_WRITE)
|
||||
#ifdef GARBAGE_THREAD
|
||||
// purge
|
||||
notify_garbage_collector(tdbb, rpb);
|
||||
if (tdbb->tdbb_database->dbb_flags | DBB_gc_background)
|
||||
notify_garbage_collector(tdbb, rpb);
|
||||
#endif
|
||||
return; //false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user