1
/* Copyright (C) 2005 PrimeBase Technologies GmbH
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
* 2005-01-15 Paul McCullagh
23
#ifndef __xt_database_h__
24
#define __xt_database_h__
28
#include "thread_xt.h"
29
#include "hashtab_xt.h"
31
#include "sortedlist_xt.h"
32
#include "xaction_xt.h"
34
#include "xactlog_xt.h"
35
#include "restart_xt.h"
39
//#define XT_USE_XACTION_DEBUG_SIZES
42
#ifdef XT_USE_XACTION_DEBUG_SIZES
43
#define XT_DB_TABLE_POOL_SIZE 2
45
#define XT_DB_TABLE_POOL_SIZE 10 // The number of open tables maintained by the sweeper
48
#define XT_ASYNC_THREAD_COUNT 10
50
/* Turn this switch on to enable spin lock based wait-for logic: */
51
#define XT_USE_SPINLOCK_WAIT_FOR
53
extern xtLogOffset xt_db_log_file_threshold;
54
extern size_t xt_db_log_buffer_size;
55
extern size_t xt_db_transaction_buffer_size;
56
extern size_t xt_db_checkpoint_frequency;
57
extern off_t xt_db_data_log_threshold;
58
extern size_t xt_db_data_file_grow_size;
59
extern size_t xt_db_row_file_grow_size;
60
extern size_t xt_db_record_write_threshold;
61
extern int xt_db_garbage_threshold;
62
extern int xt_db_log_file_count;
63
extern int xt_db_auto_increment_mode;
64
extern int xt_db_offline_log_function;
65
extern int xt_db_sweeper_priority;
66
extern int xt_db_rewrite_flushing;
67
extern int xt_db_index_dirty_threshold;
68
extern int xt_db_flush_log_at_trx_commit;
70
extern XTSortedListPtr xt_db_open_db_by_id;
71
extern XTHashTabPtr xt_db_open_databases;
72
extern time_t xt_db_approximate_time;
74
#define XT_OPEN_TABLE_POOL_HASH_SIZE 223
76
#define XT_SW_WORK_NORMAL 0
77
#define XT_SW_NO_MORE_XACT_SLOTS 1
78
#define XT_SW_DIRTY_RECORD_FOUND 2
79
#define XT_SW_TOO_FAR_BEHIND 3 /* The sweeper is getting too far behind, although it is working! */
81
#ifdef XT_SWEEPER_SORT_XACTS
82
#define XT_SW_XACT_SORT_LIST_SIZE 100 /* Size of the list of transactions sorted for sweeping. */
85
#define XT_TABLE_NOT_LOCKED 0
86
#define XT_TABLE_LOCK_WAITING 1
87
#define XT_TABLE_LOCK_FLUSHING 2
88
#define XT_TABLE_LOCKED 3
90
typedef struct XTOpenTablePool {
91
struct XTDatabase *opt_db;
92
xtTableID opt_tab_id; /* The table ID. */
93
u_int opt_total_open; /* Total number of open tables. */
94
int opt_locked; /* This table is locked open tables are freed on return to pool. */
96
XTOpenTablePtr opt_free_list; /* A list of free, unused open tables. */
97
struct XTOpenTablePool *opt_next_hash;
98
} XTOpenTablePoolRec, *XTOpenTablePoolPtr;
100
typedef struct XTAllTablePools {
101
xt_mutex_type opt_lock; /* This lock protects the open table pool. */
102
xt_cond_type opt_cond; /* Used to wait for an exclusive lock on a table. */
104
u_int otp_total_free; /* This is the total number of free open tables (not in use): */
106
/* All free (unused tables) are on this list: */
107
XTOpenTablePtr otp_mr_used;
108
XTOpenTablePtr otp_lr_used;
109
time_t otp_free_time; /* The free time of the LRU open table. */
111
XTOpenTablePoolPtr otp_hash[XT_OPEN_TABLE_POOL_HASH_SIZE];
112
} XTAllTablePoolsRec, *XTAllTablePoolsPtr;
114
typedef struct XTTablePath {
115
u_int tp_tab_count; /* The number of tables using this path. */
116
char tp_path[XT_VAR_LENGTH]; /* The table path. */
117
} XTTablePathRec, *XTTablePathPtr;
119
#define XT_THREAD_BUSY 0
120
#define XT_THREAD_IDLE 1
121
#define XT_THREAD_INERR 2
123
#define XT_XA_HASH_TAB_SIZE 223
125
typedef struct XTDatabase : public XTHeap {
126
char *db_name; /* The name of the database, last component of the path! */
129
xtTableID db_curr_tab_id; /* The ID of the last table created. */
130
XTHashTabPtr db_tables;
131
XTSortedListPtr db_table_by_id;
132
XTSortedListPtr db_table_paths; /* A list of table paths used by this database. */
133
xtBool db_multi_path;
134
XTSortedListPtr db_error_list; /* A list of errors already reported. */
136
/* The open table pool: */
137
XTAllTablePoolsRec db_ot_pool;
139
/* Transaction related stuff: */
140
XTSpinLockRec db_xn_id_lock; /* Lock for next transaction ID. */
141
xtXactID db_xn_curr_id; /* The ID of the last transaction started. */
142
xtXactID db_xn_min_ram_id; /* The lowest ID of the transactions in memory (RAM). */
143
xtXactID db_xn_to_clean_id; /* The next transaction to be cleaned (>= db_xn_min_ram_id). */
144
xtXactID db_xn_min_run_id; /* The lowest ID of all running transactions (not up-to-date! >= db_xn_to_clean_id) */
145
xtWord4 db_xn_end_time; /* The time of the transaction end. */
146
XTXactSegRec db_xn_idx[XT_XN_NO_OF_SEGMENTS]; /* Index of transactions in RAM. */
147
xtWord1 *db_xn_data; /* Start of the block allocated to contain transaction data. */
148
xtWord1 *db_xn_data_end; /* End of the transaction data block. */
149
u_int db_stat_sweep_waits; /* STATISTICS: count the sweeper waits. */
150
XTDatabaseLogRec db_xlog; /* The transaction log for this database. */
151
XTXactRestartRec db_restart; /* Database recovery stuff. */
152
xt_mutex_type db_init_sweep_lock; /* Lock so that only one thread can does the initial sweep. */
153
xtBool db_init_sweep_done; /* Set to TRUE once the initial sweep has been done. */
154
xt_mutex_type db_xn_xa_lock;
155
XTXactPreparePtr db_xn_xa_table[XT_XA_HASH_TAB_SIZE];
156
XTSortedListPtr db_xn_xa_list; /* The "wait-for" list, of transactions waiting for other transactions. */
158
XTSortedListPtr db_xn_wait_for; /* The "wait-for" list, of transactions waiting for other transactions. */
159
u_int db_xn_call_start; /* Start of the post wait calls. */
160
XTSpinLockRec db_xn_wait_spinlock;
161
//xt_mutex_type db_xn_wait_lock; /* The lock associated with the wait for list. */
162
//xt_cond_type db_xn_wait_cond; /* This condition is signalled when a transaction quits. */
163
//u_int db_xn_wait_on_cond; /* Number of threads waiting on the condition. */
164
int db_xn_wait_count; /* Number of waiting transactions. */
165
u_int db_xn_total_writer_count; /* The total number of writers. */
166
int db_xn_writer_count; /* The number of writer threads. */
167
int db_xn_writer_wait_count; /* The number of writer threads waiting. */
168
int db_xn_long_running_count; /* The number of long running writer threads. */
171
struct XTThread *db_sw_thread; /* The sweeper thread (cleans up transactions). */
172
xt_mutex_type db_sw_lock; /* The lock associated with the sweeper. */
173
xt_cond_type db_sw_cond; /* The sweeper wakeup condition. */
174
u_int db_sw_check_count;
175
int db_sw_idle; /* BUSY/IDLE/INERR depending on the state of the sweeper. */
176
int db_sw_faster; /* non-zero if the sweeper should work faster. */
177
xtBool db_sw_fast; /* TRUE if the sweeper is working faster. */
178
#ifdef XT_SWEEPER_SORT_XACTS
179
xtXactID db_sw_to_add; /* The next transaction to be added. */
180
u_int db_sw_list_size; /* The number of transaction in the list. */
181
XTXactDataPtr db_sw_xact_list[XT_SW_XACT_SORT_LIST_SIZE];
185
struct XTThread *db_wr_thread; /* The writer thread (write log data to the database). */
186
int db_wr_idle; /* BUSY/IDLE/INERR depending on the state of the writer. */
187
xtBool db_wr_faster; /* Set to TRUE if the writer should work faster. */
188
xtBool db_wr_fast; /* TRUE if the writer is working faster. */
189
u_int db_wr_thread_waiting; /* Count the number of threads waiting for the writer. */
190
xtBool db_wr_freeer_waiting; /* TRUE if the freeer is wating for the writer. */
191
xt_mutex_type db_wr_lock;
192
xt_cond_type db_wr_cond; /* Writer condition when idle (must bw woken by log flush! */
193
xtLogID db_wr_log_id; /* Current write log ID. */
194
xtLogOffset db_wr_log_offset; /* Current write log offset. */
195
xtLogID db_wr_flush_point_log_id; /* This is the point to which the writer will write (log ID). */
196
xtLogOffset db_wr_flush_point_log_offset; /* This is the point to which the writer will write (log offset). */
198
/* Data log stuff: */
199
XTDataLogCacheRec db_datalogs; /* The database data log stuff. */
200
XTIndexLogPoolRec db_indlogs; /* Index logs used for consistent write. */
202
/* Compactor stuff: */
203
struct XTThread *db_co_thread; /* The compator thread (compacts data logs). */
204
xt_mutex_type db_co_ext_lock; /* Required when extended data is moved, or removed. */
205
xtBool db_co_busy; /* True of the compactor is busy compacting a data log. */
206
xt_mutex_type db_co_dlog_lock; /* This is the lock required to flusht the compactors data log. */
208
/* Checkpointer stuff: */
209
struct XTThread *db_cp_thread; /* The checkpoint thread (flushes the database data). */
210
xt_mutex_type db_cp_lock;
211
xt_cond_type db_cp_cond; /* Writer condition when idle (must bw woken by log flush! */
212
XTCheckPointStateRec db_cp_state; /* The checkpoint state. */
215
xt_mutex_type db_pool_lock;
216
xt_cond_type db_pool_cond;
217
u_int db_pool_job_count; /* The number of busy threads. */
218
u_int db_pool_thread_count; /* The number of threads in the pool. */
219
XTThreadPtr db_thread_pool;
220
XTTask *db_task_queue_front;
221
XTTask *db_task_queue_back;
223
/* The "flusher" thread (used when pbxt_flush_log_at_trx_commit = 0 or 2) */
224
struct XTThread *db_fl_thread; /* The flusher thread (flushes the transation log). */
225
xt_mutex_type db_fl_lock;
226
} XTDatabaseRec, *XTDatabaseHPtr; /* Heap pointer */
228
#define XT_FOR_USER 0
229
#define XT_FOR_COMPACTOR 1
230
#define XT_FOR_SWEEPER 2
231
#define XT_FOR_WRITER 3
232
#define XT_FOR_CHECKPOINTER 4
233
#define XT_FOR_POOL 5
235
void xt_create_database(XTThreadPtr th, char *path);
236
XTDatabaseHPtr xt_get_database(XTThreadPtr self, const char *path, xtBool multi_path);
237
XTDatabaseHPtr xt_get_database_by_id(XTThreadPtr self, xtDatabaseID db_id);
238
void xt_drop_database(XTThreadPtr self, XTDatabaseHPtr db);
240
void xt_add_pbxt_file(size_t size, char *path, const char *file);
241
void xt_add_location_file(size_t size, char *path);
242
void xt_add_tables_file(size_t size, char *path);
243
void xt_add_pbxt_dir(size_t size, char *path);
244
void xt_add_system_dir(size_t size, char *path);
245
void xt_add_data_dir(size_t size, char *path);
247
void xt_use_database(XTThreadPtr self, XTDatabaseHPtr db, int what_for);
248
void xt_unuse_database(XTThreadPtr self, XTThreadPtr other_thr);
249
void xt_open_database(XTThreadPtr self, const char *path, xtBool multi_path);
251
void xt_lock_installation(XTThreadPtr self, const char *installation_path);
252
void xt_unlock_installation(XTThreadPtr self, const char *installation_path);
253
void xt_crash_me(void);
255
void xt_init_databases(XTThreadPtr self);
256
void xt_stop_database_threads(XTThreadPtr self, xtBool sync);
257
void xt_exit_databases(XTThreadPtr self);
259
void xt_dump_database(XTThreadPtr self, XTDatabaseHPtr db);
261
void xt_db_init_thread_ns(XTThreadPtr new_thread);
262
void xt_db_exit_thread(XTThreadPtr self);
264
void xt_db_pool_init(XTThreadPtr self, struct XTDatabase *db);
265
void xt_db_pool_exit(XTThreadPtr self, struct XTDatabase *db);
266
XTOpenTablePoolPtr xt_db_lock_table_pool_by_name(XTThreadPtr self, XTDatabaseHPtr db, XTPathStrPtr name, xtBool no_load, xtBool flush_table, xtBool missing_ok, XTTableHPtr *ret_tab);
267
void xt_db_unlock_table_pool(struct XTThread *self, XTOpenTablePoolPtr table_pool);
268
XTOpenTablePtr xt_db_open_pool_table(XTThreadPtr self, XTDatabaseHPtr db, xtTableID tab_id, int *result, xtBool i_am_background);
269
XTOpenTablePtr xt_db_open_table_using_tab(XTTableHPtr tab, XTThreadPtr thread);
270
xtBool xt_db_open_pool_table_ns(XTOpenTablePtr *ret_ot, XTDatabaseHPtr db, xtTableID tab_id);
271
void xt_db_return_table_to_pool(XTThreadPtr self, XTOpenTablePtr ot);
272
void xt_db_return_table_to_pool_ns(XTOpenTablePtr ot);
273
void xt_db_free_unused_open_tables(XTThreadPtr self, XTDatabaseHPtr db);
275
void xt_db_thread_pool_init(XTThreadPtr self, struct XTDatabase *db);
276
void xt_db_thread_pool_exit(XTThreadPtr self, struct XTDatabase *db);
277
void xt_db_stop_pool_threads(XTThreadPtr self, struct XTDatabase *db);
278
xtBool xt_run_async_task(XTTask *task_data, xtBool notify_complete, xtBool notify_early, XTThreadPtr thread, struct XTDatabase *db);
279
void xt_wait_for_async_tasks(XTThreadPtr thread);
280
XTTask *xt_get_task_result(XTThreadPtr thread);
281
xtBool xt_wait_for_async_task_results(XTThreadPtr thread);
282
void xt_async_task_notify(XTTask *tk);
283
void xt_unit_test_async_task(XTThreadPtr self);
286
#define XT_LONG_RUNNING_TIME 2
288
inline void xt_xlog_check_long_writer(XTThreadPtr thread)
290
if (thread->st_xact_writer) {
291
if (xt_db_approximate_time - thread->st_xact_write_time > XT_LONG_RUNNING_TIME) {
292
if (!thread->st_xact_long_running) {
293
thread->st_xact_long_running = TRUE;
294
thread->st_database->db_xn_long_running_count++;
300
extern XTDatabaseHPtr pbxt_database; // The global open database