2008-02-14 13:24:27 +01:00
|
|
|
/*
|
|
|
|
* PROGRAM: JRD access method
|
|
|
|
* MODULE: Database.h
|
|
|
|
* DESCRIPTION: Common descriptions
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Interbase Public
|
|
|
|
* License Version 1.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy
|
|
|
|
* of the License at http://www.Inprise.com/IPL.html
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an
|
|
|
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
|
|
|
* or implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code was created by Inprise Corporation
|
|
|
|
* and its predecessors. Portions created by Inprise Corporation are
|
|
|
|
* Copyright (C) Inprise Corporation.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
|
|
|
*
|
|
|
|
* 2002.10.28 Sean Leyne - Code cleanup, removed obsolete "DecOSF" port
|
|
|
|
*
|
|
|
|
* 2002.10.29 Sean Leyne - Removed obsolete "Netware" port
|
|
|
|
* Claudio Valderrama C.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef JRD_DATABASE_H
|
|
|
|
#define JRD_DATABASE_H
|
2008-03-20 17:42:29 +01:00
|
|
|
|
2008-02-14 13:24:27 +01:00
|
|
|
#include "firebird.h"
|
|
|
|
#include "../jrd/cch.h"
|
2010-10-13 12:39:52 +02:00
|
|
|
#include "../common/gdsassert.h"
|
2010-10-12 10:02:57 +02:00
|
|
|
#include "../common/dsc.h"
|
2008-02-14 13:24:27 +01:00
|
|
|
#include "../jrd/btn.h"
|
|
|
|
#include "../jrd/jrd_proto.h"
|
|
|
|
#include "../jrd/val.h"
|
2008-02-28 14:48:16 +01:00
|
|
|
#include "../jrd/irq.h"
|
|
|
|
#include "../jrd/drq.h"
|
2008-03-20 17:42:29 +01:00
|
|
|
#include "../include/gen/iberror.h"
|
|
|
|
|
2008-02-14 13:24:27 +01:00
|
|
|
#include "../common/classes/fb_atomic.h"
|
|
|
|
#include "../common/classes/fb_string.h"
|
|
|
|
#include "../common/classes/MetaName.h"
|
|
|
|
#include "../common/classes/array.h"
|
|
|
|
#include "../common/classes/objects_array.h"
|
|
|
|
#include "../common/classes/stack.h"
|
|
|
|
#include "../common/classes/timestamp.h"
|
|
|
|
#include "../common/classes/GenericMap.h"
|
2008-03-20 17:42:29 +01:00
|
|
|
#include "../common/classes/RefCounted.h"
|
2008-10-10 17:58:05 +02:00
|
|
|
#include "../common/classes/semaphore.h"
|
2008-12-11 12:58:50 +01:00
|
|
|
#include "../common/utils_proto.h"
|
2008-02-14 13:24:27 +01:00
|
|
|
#include "../jrd/RandomGenerator.h"
|
2010-10-12 10:02:57 +02:00
|
|
|
#include "../common/os/guid.h"
|
2008-02-14 13:24:27 +01:00
|
|
|
#include "../jrd/sbm.h"
|
|
|
|
#include "../jrd/flu.h"
|
|
|
|
#include "../jrd/RuntimeStatistics.h"
|
2009-01-28 13:27:18 +01:00
|
|
|
#include "../jrd/event_proto.h"
|
2013-02-17 13:08:53 +01:00
|
|
|
#include "../jrd/ExtEngineManager.h"
|
2009-01-28 13:27:18 +01:00
|
|
|
#include "../lock/lock_proto.h"
|
2010-02-28 19:00:51 +01:00
|
|
|
#include "../common/config/config.h"
|
2011-05-09 12:15:19 +02:00
|
|
|
#include "../common/classes/SyncObject.h"
|
|
|
|
#include "../common/classes/Synchronize.h"
|
2012-05-19 14:04:37 +02:00
|
|
|
#include "fb_types.h"
|
2008-03-20 17:42:29 +01:00
|
|
|
|
2008-02-14 13:24:27 +01:00
|
|
|
namespace Jrd
|
|
|
|
{
|
2011-05-09 12:15:19 +02:00
|
|
|
template <typename T> class vec;
|
|
|
|
class jrd_rel;
|
|
|
|
class Shadow;
|
|
|
|
class BlobFilter;
|
|
|
|
class TipCache;
|
|
|
|
class BackupManager;
|
|
|
|
class ExternalFileDirectoryList;
|
|
|
|
class MonitoringData;
|
2011-05-27 09:57:16 +02:00
|
|
|
class GarbageCollector;
|
2012-05-31 18:53:42 +02:00
|
|
|
class CryptoManager;
|
2008-02-14 13:24:27 +01:00
|
|
|
|
2011-01-21 18:55:04 +01:00
|
|
|
// general purpose vector
|
|
|
|
template <class T, BlockType TYPE = type_vec>
|
|
|
|
class vec_base : protected pool_alloc<TYPE>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef typename Firebird::Array<T>::iterator iterator;
|
|
|
|
typedef typename Firebird::Array<T>::const_iterator const_iterator;
|
2011-01-22 18:15:52 +01:00
|
|
|
|
2011-01-21 18:55:04 +01:00
|
|
|
/*
|
|
|
|
static vec_base* newVector(MemoryPool& p, int len)
|
|
|
|
{
|
|
|
|
return FB_NEW(p) vec_base<T, TYPE>(p, len);
|
|
|
|
}
|
2011-01-22 18:15:52 +01:00
|
|
|
|
2011-01-21 18:55:04 +01:00
|
|
|
static vec_base* newVector(MemoryPool& p, const vec_base& base)
|
|
|
|
{
|
|
|
|
return FB_NEW(p) vec_base<T, TYPE>(p, base);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
size_t count() const { return v.getCount(); }
|
|
|
|
T& operator[](size_t index) { return v[index]; }
|
|
|
|
const T& operator[](size_t index) const { return v[index]; }
|
|
|
|
|
|
|
|
iterator begin() { return v.begin(); }
|
|
|
|
iterator end() { return v.end(); }
|
|
|
|
|
|
|
|
const_iterator begin() const { return v.begin(); }
|
|
|
|
const_iterator end() const { return v.end(); }
|
|
|
|
|
|
|
|
void clear() { v.clear(); }
|
|
|
|
|
|
|
|
T* memPtr() { return &v[0]; }
|
|
|
|
|
|
|
|
void resize(size_t n, T val = T()) { v.resize(n, val); }
|
|
|
|
|
|
|
|
void operator delete(void* mem) { MemoryPool::globalFree(mem); }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
vec_base(MemoryPool& p, int len)
|
|
|
|
: v(p, len)
|
|
|
|
{
|
|
|
|
v.resize(len);
|
|
|
|
}
|
2011-01-22 18:15:52 +01:00
|
|
|
|
2011-01-21 18:55:04 +01:00
|
|
|
vec_base(MemoryPool& p, const vec_base& base)
|
|
|
|
: v(p)
|
|
|
|
{
|
|
|
|
v = base.v;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
Firebird::Array<T> v;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
class vec : public vec_base<T, type_vec>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
static vec* newVector(MemoryPool& p, int len)
|
|
|
|
{
|
|
|
|
return FB_NEW(p) vec<T>(p, len);
|
|
|
|
}
|
2011-01-22 18:15:52 +01:00
|
|
|
|
2011-01-21 18:55:04 +01:00
|
|
|
static vec* newVector(MemoryPool& p, const vec& base)
|
|
|
|
{
|
|
|
|
return FB_NEW(p) vec<T>(p, base);
|
|
|
|
}
|
2011-01-22 18:15:52 +01:00
|
|
|
|
2011-01-21 18:55:04 +01:00
|
|
|
static vec* newVector(MemoryPool& p, vec* base, int len)
|
|
|
|
{
|
|
|
|
if (!base)
|
|
|
|
base = FB_NEW(p) vec<T>(p, len);
|
|
|
|
else if (len > (int) base->count())
|
|
|
|
base->resize(len);
|
|
|
|
return base;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
vec(MemoryPool& p, int len) : vec_base<T, type_vec>(p, len) {}
|
|
|
|
vec(MemoryPool& p, const vec& base) : vec_base<T, type_vec>(p, base) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
class vcl : public vec_base<ULONG, type_vcl>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
static vcl* newVector(MemoryPool& p, int len)
|
|
|
|
{
|
|
|
|
return FB_NEW(p) vcl(p, len);
|
|
|
|
}
|
2011-01-22 18:15:52 +01:00
|
|
|
|
2011-01-21 18:55:04 +01:00
|
|
|
static vcl* newVector(MemoryPool& p, const vcl& base)
|
|
|
|
{
|
|
|
|
return FB_NEW(p) vcl(p, base);
|
|
|
|
}
|
2011-01-22 18:15:52 +01:00
|
|
|
|
2011-01-21 18:55:04 +01:00
|
|
|
static vcl* newVector(MemoryPool& p, vcl* base, int len)
|
|
|
|
{
|
|
|
|
if (!base)
|
|
|
|
base = FB_NEW(p) vcl(p, len);
|
|
|
|
else if (len > (int) base->count())
|
|
|
|
base->resize(len);
|
|
|
|
return base;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
vcl(MemoryPool& p, int len) : vec_base<ULONG, type_vcl>(p, len) {}
|
|
|
|
vcl(MemoryPool& p, const vcl& base) : vec_base<ULONG, type_vcl>(p, base) {}
|
|
|
|
};
|
|
|
|
|
2012-05-19 14:04:37 +02:00
|
|
|
typedef vec<TraNumber> TransactionsVector;
|
2011-01-21 18:55:04 +01:00
|
|
|
|
|
|
|
|
2008-09-04 11:58:20 +02:00
|
|
|
//
|
|
|
|
// bit values for dbb_flags
|
|
|
|
//
|
|
|
|
const ULONG DBB_damaged = 0x1L;
|
|
|
|
const ULONG DBB_exclusive = 0x2L; // Database is accessed in exclusive mode
|
|
|
|
const ULONG DBB_bugcheck = 0x4L; // Bugcheck has occurred
|
|
|
|
const ULONG DBB_garbage_collector = 0x8L; // garbage collector thread exists
|
|
|
|
const ULONG DBB_gc_active = 0x10L; // ... and is actively working.
|
|
|
|
const ULONG DBB_gc_pending = 0x20L; // garbage collection requested
|
|
|
|
const ULONG DBB_force_write = 0x40L; // Database is forced write
|
|
|
|
const ULONG DBB_no_reserve = 0x80L; // No reserve space for versions
|
|
|
|
const ULONG DBB_DB_SQL_dialect_3 = 0x100L; // database SQL dialect 3
|
|
|
|
const ULONG DBB_read_only = 0x200L; // DB is ReadOnly (RO). If not set, DB is RW
|
|
|
|
const ULONG DBB_being_opened_read_only = 0x400L; // DB is being opened RO. If unset, opened as RW
|
|
|
|
const ULONG DBB_not_in_use = 0x800L; // Database to be ignored while attaching
|
2012-06-21 17:37:38 +02:00
|
|
|
const ULONG DBB_sweep_in_progress = 0x1000L; // A database sweep operation is in progress
|
|
|
|
const ULONG DBB_security_db = 0x2000L; // ISC security database
|
|
|
|
const ULONG DBB_suspend_bgio = 0x4000L; // Suspend I/O by background threads
|
2012-12-14 18:59:02 +01:00
|
|
|
const ULONG DBB_new = 0x8000L; // Database object is just created
|
2012-06-21 17:37:38 +02:00
|
|
|
const ULONG DBB_gc_cooperative = 0x10000L; // cooperative garbage collection
|
|
|
|
const ULONG DBB_gc_background = 0x20000L; // background garbage collection by gc_thread
|
|
|
|
const ULONG DBB_no_fs_cache = 0x40000L; // Not using file system cache
|
2008-09-04 11:58:20 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// dbb_ast_flags
|
|
|
|
//
|
2009-08-23 14:35:03 +02:00
|
|
|
const ULONG DBB_blocking = 0x1L; // Exclusive mode is blocking
|
|
|
|
const ULONG DBB_get_shadows = 0x2L; // Signal received to check for new shadows
|
|
|
|
const ULONG DBB_assert_locks = 0x4L; // Locks are to be asserted
|
|
|
|
const ULONG DBB_shutdown = 0x8L; // Database is shutdown
|
|
|
|
const ULONG DBB_shut_attach = 0x10L; // no new attachments accepted
|
|
|
|
const ULONG DBB_shut_tran = 0x20L; // no new transactions accepted
|
|
|
|
const ULONG DBB_shut_force = 0x40L; // forced shutdown in progress
|
2011-10-10 15:51:10 +02:00
|
|
|
const ULONG DBB_shutdown_full = 0x80L; // Database fully shut down
|
|
|
|
const ULONG DBB_shutdown_single = 0x100L; // Database is in single-user maintenance mode
|
|
|
|
const ULONG DBB_monitor_off = 0x200L; // Database has the monitoring lock released
|
2008-09-04 11:58:20 +02:00
|
|
|
|
2011-04-25 19:47:56 +02:00
|
|
|
class Database : public pool_alloc<type_dbb>
|
2008-02-14 13:24:27 +01:00
|
|
|
{
|
|
|
|
public:
|
2011-02-15 08:16:57 +01:00
|
|
|
class SharedCounter
|
|
|
|
{
|
|
|
|
static const ULONG DEFAULT_CACHE_SIZE = 16;
|
|
|
|
|
|
|
|
struct ValueCache
|
|
|
|
{
|
2012-03-27 12:52:15 +02:00
|
|
|
Lock* lock; // lock which holds shared counter value
|
|
|
|
SLONG curVal; // current value of shared counter lock
|
|
|
|
SLONG maxVal; // maximum cached value of shared counter lock
|
2011-02-15 08:16:57 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
ATTACHMENT_ID_SPACE = 0,
|
|
|
|
TRANSACTION_ID_SPACE = 1,
|
|
|
|
STATEMENT_ID_SPACE = 2,
|
|
|
|
TOTAL_ITEMS = 3
|
|
|
|
};
|
|
|
|
|
|
|
|
SharedCounter();
|
2011-02-25 08:32:36 +01:00
|
|
|
~SharedCounter();
|
2011-02-15 08:16:57 +01:00
|
|
|
|
|
|
|
SLONG generate(thread_db* tdbb, ULONG space, ULONG prefetch = DEFAULT_CACHE_SIZE);
|
|
|
|
void shutdown(thread_db* tdbb);
|
|
|
|
|
|
|
|
private:
|
|
|
|
static int blockingAst(void* arg);
|
|
|
|
|
|
|
|
ValueCache m_counters[TOTAL_ITEMS];
|
|
|
|
};
|
|
|
|
|
2008-05-06 10:46:39 +02:00
|
|
|
static Database* create()
|
2008-04-19 11:42:01 +02:00
|
|
|
{
|
2008-05-06 10:46:39 +02:00
|
|
|
Firebird::MemoryStats temp_stats;
|
|
|
|
MemoryPool* const pool = MemoryPool::createPool(NULL, temp_stats);
|
|
|
|
Database* const dbb = FB_NEW(*pool) Database(pool);
|
|
|
|
pool->setStatsGroup(dbb->dbb_memory_stats);
|
|
|
|
return dbb;
|
2008-02-14 13:24:27 +01:00
|
|
|
}
|
|
|
|
|
2008-05-06 10:46:39 +02:00
|
|
|
// The destroy() function MUST be used to delete a Database object.
|
2008-02-14 13:24:27 +01:00
|
|
|
// The function hides some tricky order of operations. Since the
|
|
|
|
// memory for the vectors in the Database is allocated out of the Database's
|
|
|
|
// permanent memory pool, the entire delete() operation needs
|
|
|
|
// to complete _before_ the permanent pool is deleted, or else
|
|
|
|
// risk an aborted engine.
|
2008-05-06 10:46:39 +02:00
|
|
|
static void destroy(Database* const toDelete)
|
2008-02-14 13:24:27 +01:00
|
|
|
{
|
|
|
|
if (!toDelete)
|
|
|
|
return;
|
2008-02-20 16:29:07 +01:00
|
|
|
|
|
|
|
MemoryPool* const perm = toDelete->dbb_permanent;
|
|
|
|
|
|
|
|
// Memory pool destruction below decrements memory statistics
|
|
|
|
// situated in database block we are about to deallocate right now
|
2008-02-14 13:24:27 +01:00
|
|
|
Firebird::MemoryStats temp_stats;
|
|
|
|
perm->setStatsGroup(temp_stats);
|
2008-02-20 16:29:07 +01:00
|
|
|
|
2008-02-14 13:24:27 +01:00
|
|
|
delete toDelete;
|
|
|
|
MemoryPool::deletePool(perm);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG getLockOwnerId()
|
|
|
|
{
|
2008-12-11 12:58:50 +01:00
|
|
|
return fb_utils::genUniqueId();
|
2008-02-14 13:24:27 +01:00
|
|
|
}
|
|
|
|
|
2011-05-09 12:15:19 +02:00
|
|
|
Firebird::SyncObject dbb_sync;
|
2011-10-02 12:19:06 +02:00
|
|
|
Firebird::SyncObject dbb_sys_attach; // syncronize operations with dbb_sys_attachments
|
2011-05-09 12:15:19 +02:00
|
|
|
Firebird::SyncObject dbb_lck_sync; // syncronize operations with att_long_locks at different attachments
|
|
|
|
|
2011-10-02 12:19:06 +02:00
|
|
|
MemoryPool* dbb_permanent;
|
2008-02-14 13:24:27 +01:00
|
|
|
|
2010-11-08 11:21:04 +01:00
|
|
|
LockManager* dbb_lock_mgr;
|
|
|
|
EventManager* dbb_event_mgr;
|
2008-06-07 11:08:16 +02:00
|
|
|
|
2008-02-14 13:24:27 +01:00
|
|
|
Database* dbb_next; // Next database block in system
|
|
|
|
Attachment* dbb_attachments; // Active attachments
|
2011-05-27 09:57:16 +02:00
|
|
|
Attachment* dbb_sys_attachments; // System attachments
|
2008-02-14 13:24:27 +01:00
|
|
|
BufferControl* dbb_bcb; // Buffer control block
|
2008-12-11 12:58:50 +01:00
|
|
|
int dbb_monitoring_id; // dbb monitoring identifier
|
2008-02-14 13:24:27 +01:00
|
|
|
Lock* dbb_lock; // granddaddy lock
|
2011-05-10 03:12:14 +02:00
|
|
|
|
2011-05-09 12:15:19 +02:00
|
|
|
Firebird::SyncObject dbb_sh_counter_sync;
|
2011-05-10 03:12:14 +02:00
|
|
|
|
2011-05-09 12:15:19 +02:00
|
|
|
Firebird::SyncObject dbb_shadow_sync;
|
2008-02-14 13:24:27 +01:00
|
|
|
Shadow* dbb_shadow; // shadow control block
|
|
|
|
Lock* dbb_shadow_lock; // lock for synchronizing addition of shadows
|
2011-05-09 12:15:19 +02:00
|
|
|
|
2008-02-14 13:24:27 +01:00
|
|
|
Lock* dbb_retaining_lock; // lock for preserving commit retaining snapshot
|
|
|
|
Lock* dbb_monitor_lock; // lock for monitoring purposes
|
|
|
|
PageManager dbb_page_manager;
|
|
|
|
vcl* dbb_t_pages; // pages number for transactions
|
|
|
|
vcl* dbb_gen_id_pages; // known pages for gen_id
|
|
|
|
BlobFilter* dbb_blob_filters; // known blob filters
|
|
|
|
|
2011-05-09 12:15:19 +02:00
|
|
|
Firebird::SyncObject dbb_mon_sync; // syncronize operations with dbb_monitor_lock
|
|
|
|
MonitoringData* dbb_monitoring_data; // monitoring data
|
2009-01-28 13:27:18 +01:00
|
|
|
|
2008-02-14 13:24:27 +01:00
|
|
|
DatabaseModules dbb_modules; // external function/filter modules
|
2011-05-09 12:15:19 +02:00
|
|
|
ExtEngineManager dbb_extManager; // external engine manager
|
2008-03-13 15:20:32 +01:00
|
|
|
|
2011-05-09 12:15:19 +02:00
|
|
|
Firebird::SyncObject dbb_flush_count_mutex;
|
2012-12-14 18:59:02 +01:00
|
|
|
Firebird::RWLock dbb_ast_lock; // avoids delivering AST to going away database
|
2011-05-09 12:15:19 +02:00
|
|
|
Firebird::AtomicCounter dbb_ast_flags; // flags modified at AST level
|
|
|
|
Firebird::AtomicCounter dbb_flags;
|
2008-02-14 13:24:27 +01:00
|
|
|
USHORT dbb_ods_version; // major ODS version number
|
|
|
|
USHORT dbb_minor_version; // minor ODS version number
|
|
|
|
USHORT dbb_page_size; // page size
|
|
|
|
USHORT dbb_dp_per_pp; // data pages per pointer page
|
|
|
|
USHORT dbb_max_records; // max record per data page
|
|
|
|
USHORT dbb_max_idx; // max number of indexes on a root page
|
2009-08-25 13:38:03 +02:00
|
|
|
|
2008-02-14 13:24:27 +01:00
|
|
|
#ifdef SUPERSERVER_V2
|
|
|
|
USHORT dbb_prefetch_sequence; // sequence to pace frequency of prefetch requests
|
|
|
|
USHORT dbb_prefetch_pages; // prefetch pages per request
|
|
|
|
#endif
|
2009-08-25 13:38:03 +02:00
|
|
|
|
2008-02-14 13:24:27 +01:00
|
|
|
Firebird::PathName dbb_filename; // filename string
|
|
|
|
Firebird::PathName dbb_database_name; // database ID (file name or alias)
|
|
|
|
|
2011-05-09 12:15:19 +02:00
|
|
|
Firebird::SyncObject dbb_pools_sync;
|
|
|
|
Firebird::Array<MemoryPool*> dbb_pools; // pools
|
2008-02-14 13:24:27 +01:00
|
|
|
|
2011-10-18 20:02:57 +02:00
|
|
|
Firebird::SyncObject dbb_threads_sync;
|
|
|
|
thread_db* dbb_active_threads;
|
|
|
|
|
2012-05-26 20:05:56 +02:00
|
|
|
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
|
|
|
|
TraNumber dbb_next_transaction; // Next transaction id used by NETWARE
|
2008-02-14 13:24:27 +01:00
|
|
|
SLONG dbb_attachment_id; // Next attachment id for ReadOnly DB's
|
|
|
|
ULONG dbb_page_buffers; // Page buffers from header page
|
|
|
|
|
2011-05-27 09:57:16 +02:00
|
|
|
GarbageCollector* dbb_garbage_collector; // GarbageCollector class
|
2008-10-10 17:58:05 +02:00
|
|
|
Firebird::Semaphore dbb_gc_sem; // Event to wake up garbage collector
|
|
|
|
Firebird::Semaphore dbb_gc_init; // Event for initialization garbage collector
|
|
|
|
Firebird::Semaphore dbb_gc_fini; // Event for finalization garbage collector
|
2008-02-14 13:24:27 +01:00
|
|
|
|
|
|
|
Firebird::MemoryStats dbb_memory_stats;
|
|
|
|
|
|
|
|
RuntimeStatistics dbb_stats;
|
2012-05-26 20:05:56 +02:00
|
|
|
TraNumber dbb_last_header_write; // Transaction id of last header page physical write
|
2008-02-14 13:24:27 +01:00
|
|
|
SLONG dbb_flush_cycle; // Current flush cycle
|
2012-05-19 14:04:37 +02:00
|
|
|
ULONG dbb_sweep_interval; // Transactions between sweep
|
2008-02-14 13:24:27 +01:00
|
|
|
const ULONG dbb_lock_owner_id; // ID for the lock manager
|
|
|
|
SLONG dbb_lock_owner_handle; // Handle for the lock manager
|
|
|
|
|
|
|
|
USHORT unflushed_writes; // unflushed writes
|
|
|
|
time_t last_flushed_write; // last flushed write time
|
|
|
|
|
2011-05-09 12:15:19 +02:00
|
|
|
TipCache* dbb_tip_cache; // cache of latest known state of all transactions in system
|
2011-01-21 18:55:04 +01:00
|
|
|
TransactionsVector* dbb_pc_transactions; // active precommitted transactions
|
|
|
|
BackupManager* dbb_backup_manager; // physical backup manager
|
|
|
|
Firebird::TimeStamp dbb_creation_date; // creation date
|
2010-02-28 19:00:51 +01:00
|
|
|
ExternalFileDirectoryList* dbb_external_file_directory_list;
|
|
|
|
Firebird::RefPtr<Config> dbb_config;
|
2008-02-14 13:24:27 +01:00
|
|
|
|
2011-02-15 08:16:57 +01:00
|
|
|
SharedCounter dbb_shared_counter;
|
2012-05-31 18:53:42 +02:00
|
|
|
CryptoManager* dbb_crypto_manager;
|
2011-02-15 08:16:57 +01:00
|
|
|
|
2008-02-14 13:24:27 +01:00
|
|
|
// returns true if primary file is located on raw device
|
|
|
|
bool onRawDevice() const;
|
|
|
|
|
2009-01-28 13:27:18 +01:00
|
|
|
// returns an unique ID string for a database file
|
2009-01-28 14:02:59 +01:00
|
|
|
Firebird::string getUniqueFileId() const;
|
2009-01-28 13:27:18 +01:00
|
|
|
|
2012-12-14 18:59:02 +01:00
|
|
|
#ifdef DEV_BUILD
|
|
|
|
// returns true if main lock is in exclusive state
|
|
|
|
bool locked() const
|
|
|
|
{
|
|
|
|
return dbb_sync.ourExclusiveLock();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-02-14 13:24:27 +01:00
|
|
|
MemoryPool* createPool()
|
|
|
|
{
|
2008-04-10 09:21:54 +02:00
|
|
|
MemoryPool* const pool = MemoryPool::createPool(dbb_permanent, dbb_memory_stats);
|
2011-05-09 12:15:19 +02:00
|
|
|
|
|
|
|
Firebird::SyncLockGuard guard(&dbb_pools_sync, Firebird::SYNC_EXCLUSIVE, "Database::createPool");
|
2008-02-14 13:24:27 +01:00
|
|
|
dbb_pools.add(pool);
|
|
|
|
return pool;
|
|
|
|
}
|
|
|
|
|
|
|
|
void deletePool(MemoryPool* pool);
|
|
|
|
|
|
|
|
private:
|
|
|
|
explicit Database(MemoryPool* p)
|
2011-10-02 12:19:06 +02:00
|
|
|
: dbb_permanent(p),
|
|
|
|
dbb_page_manager(this, *p),
|
2008-02-14 13:24:27 +01:00
|
|
|
dbb_modules(*p),
|
2009-10-21 02:42:38 +02:00
|
|
|
dbb_extManager(*p),
|
2008-02-14 13:24:27 +01:00
|
|
|
dbb_filename(*p),
|
|
|
|
dbb_database_name(*p),
|
|
|
|
dbb_pools(*p, 4),
|
2009-02-01 23:10:12 +01:00
|
|
|
dbb_stats(*p),
|
2008-02-14 13:24:27 +01:00
|
|
|
dbb_lock_owner_id(getLockOwnerId()),
|
2011-05-09 12:15:19 +02:00
|
|
|
dbb_tip_cache(NULL),
|
2011-05-10 13:56:52 +02:00
|
|
|
dbb_creation_date(Firebird::TimeStamp::getCurrentTimeStamp()),
|
2010-02-28 19:00:51 +01:00
|
|
|
dbb_external_file_directory_list(NULL)
|
2008-02-14 13:24:27 +01:00
|
|
|
{
|
|
|
|
dbb_pools.add(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
~Database();
|
|
|
|
|
|
|
|
public:
|
2011-02-15 08:16:57 +01:00
|
|
|
SLONG generateAttachmentId(thread_db* tdbb)
|
|
|
|
{
|
|
|
|
return dbb_shared_counter.generate(tdbb, SharedCounter::ATTACHMENT_ID_SPACE, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
SLONG generateTransactionId(thread_db* tdbb)
|
|
|
|
{
|
|
|
|
return dbb_shared_counter.generate(tdbb, SharedCounter::TRANSACTION_ID_SPACE, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
SLONG generateStatementId(thread_db* tdbb)
|
|
|
|
{
|
|
|
|
return dbb_shared_counter.generate(tdbb, SharedCounter::STATEMENT_ID_SPACE);
|
|
|
|
}
|
|
|
|
|
2011-02-15 08:32:56 +01:00
|
|
|
USHORT getMaxIndexKeyLength() const
|
|
|
|
{
|
|
|
|
return dbb_page_size / 4;
|
|
|
|
}
|
|
|
|
|
2012-04-12 11:02:13 +02:00
|
|
|
bool readOnly() const
|
|
|
|
{
|
|
|
|
return (dbb_flags & DBB_read_only) != 0;
|
|
|
|
}
|
|
|
|
|
2008-02-14 13:24:27 +01:00
|
|
|
private:
|
2008-10-16 04:31:49 +02:00
|
|
|
static int blockingAstSharedCounter(void*);
|
2008-10-14 11:10:36 +02:00
|
|
|
|
2008-02-14 13:24:27 +01:00
|
|
|
// The delete operators are no-oped because the Database memory is allocated from the
|
|
|
|
// Database's own permanent pool. That pool has already been released by the Database
|
|
|
|
// destructor, so the memory has already been released. Hence the operator
|
|
|
|
// delete no-op.
|
2009-04-26 12:24:44 +02:00
|
|
|
void operator delete(void*) {}
|
|
|
|
void operator delete[](void*) {}
|
2008-02-14 13:24:27 +01:00
|
|
|
|
|
|
|
Database(const Database&); // no impl.
|
|
|
|
const Database& operator =(const Database&) { return *this; }
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace Jrd
|
|
|
|
|
|
|
|
#endif // JRD_DATABASE_H
|