8
0
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:
hvlad 2004-11-09 12:59:37 +00:00
parent 4bdf9211fb
commit aba34753cb
6 changed files with 93 additions and 33 deletions

View File

@ -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];
}

View File

@ -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 {

View File

@ -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);

View File

@ -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:

View File

@ -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);
}

View File

@ -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;
}