1455.3.1
by Vladimir Kolesnikov
lp:drizzle + pbxt 1.1 + test results |
1 |
/* Copyright (c) 2005 PrimeBase Technologies GmbH
|
2 |
*
|
|
3 |
* PrimeBase XT
|
|
4 |
*
|
|
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.
|
|
9 |
*
|
|
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.
|
|
14 |
*
|
|
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
18 |
*
|
|
19 |
* 2005-01-15 Paul McCullagh
|
|
20 |
*
|
|
21 |
* H&G2JCtL
|
|
22 |
*/
|
|
23 |
#ifndef __xt_database_h__
|
|
24 |
#define __xt_database_h__
|
|
25 |
||
26 |
#include <time.h> |
|
27 |
||
28 |
#include "thread_xt.h" |
|
29 |
#include "hashtab_xt.h" |
|
30 |
#include "table_xt.h" |
|
31 |
#include "sortedlist_xt.h" |
|
32 |
#include "xaction_xt.h" |
|
33 |
#include "heap_xt.h" |
|
34 |
#include "xactlog_xt.h" |
|
35 |
#include "restart_xt.h" |
|
36 |
#include "index_xt.h" |
|
37 |
||
38 |
#ifdef DEBUG
|
|
39 |
//#define XT_USE_XACTION_DEBUG_SIZES
|
|
40 |
#endif
|
|
41 |
||
42 |
#ifdef XT_USE_XACTION_DEBUG_SIZES
|
|
43 |
#define XT_DB_TABLE_POOL_SIZE 2
|
|
44 |
#else
|
|
45 |
#define XT_DB_TABLE_POOL_SIZE 10 // The number of open tables maintained by the sweeper |
|
46 |
#endif
|
|
47 |
||
48 |
#define XT_ASYNC_THREAD_COUNT 10
|
|
49 |
||
50 |
/* Turn this switch on to enable spin lock based wait-for logic: */
|
|
51 |
#define XT_USE_SPINLOCK_WAIT_FOR
|
|
52 |
||
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; |
|
69 |
||
70 |
extern XTSortedListPtr xt_db_open_db_by_id; |
|
71 |
extern XTHashTabPtr xt_db_open_databases; |
|
72 |
extern time_t xt_db_approximate_time; |
|
73 |
||
74 |
#define XT_OPEN_TABLE_POOL_HASH_SIZE 223
|
|
75 |
||
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! */ |
|
80 |
||
81 |
#ifdef XT_SWEEPER_SORT_XACTS
|
|
82 |
#define XT_SW_XACT_SORT_LIST_SIZE 100 /* Size of the list of transactions sorted for sweeping. */ |
|
83 |
#endif
|
|
84 |
||
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
|
|
89 |
||
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. */ |
|
95 |
u_int opt_flushing; |
|
96 |
XTOpenTablePtr opt_free_list; /* A list of free, unused open tables. */ |
|
97 |
struct XTOpenTablePool *opt_next_hash; |
|
98 |
} XTOpenTablePoolRec, *XTOpenTablePoolPtr; |
|
99 |
||
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. */ |
|
103 |
||
104 |
u_int otp_total_free; /* This is the total number of free open tables (not in use): */ |
|
105 |
||
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. */ |
|
110 |
||
111 |
XTOpenTablePoolPtr otp_hash[XT_OPEN_TABLE_POOL_HASH_SIZE]; |
|
112 |
} XTAllTablePoolsRec, *XTAllTablePoolsPtr; |
|
113 |
||
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; |
|
118 |
||
119 |
#define XT_THREAD_BUSY 0
|
|
120 |
#define XT_THREAD_IDLE 1
|
|
121 |
#define XT_THREAD_INERR 2
|
|
122 |
||
123 |
#define XT_XA_HASH_TAB_SIZE 223
|
|
124 |
||
125 |
typedef struct XTDatabase : public XTHeap { |
|
126 |
char *db_name; /* The name of the database, last component of the path! */ |
|
127 |
char *db_main_path; |
|
128 |
xtDatabaseID db_id; |
|
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 |
||
135 |
/* The open table pool: */
|
|
136 |
XTAllTablePoolsRec db_ot_pool; |
|
137 |
||
138 |
/* Transaction related stuff: */
|
|
139 |
XTSpinLockRec db_xn_id_lock; /* Lock for next transaction ID. */ |
|
140 |
xtXactID db_xn_curr_id; /* The ID of the last transaction started. */ |
|
141 |
xtXactID db_xn_min_ram_id; /* The lowest ID of the transactions in memory (RAM). */ |
|
142 |
xtXactID db_xn_to_clean_id; /* The next transaction to be cleaned (>= db_xn_min_ram_id). */ |
|
143 |
xtXactID db_xn_min_run_id; /* The lowest ID of all running transactions (not up-to-date! >= db_xn_to_clean_id) */ |
|
144 |
xtWord4 db_xn_end_time; /* The time of the transaction end. */ |
|
145 |
XTXactSegRec db_xn_idx[XT_XN_NO_OF_SEGMENTS]; /* Index of transactions in RAM. */ |
|
146 |
xtWord1 *db_xn_data; /* Start of the block allocated to contain transaction data. */ |
|
147 |
xtWord1 *db_xn_data_end; /* End of the transaction data block. */ |
|
148 |
u_int db_stat_sweep_waits; /* STATISTICS: count the sweeper waits. */ |
|
149 |
XTDatabaseLogRec db_xlog; /* The transaction log for this database. */ |
|
150 |
XTXactRestartRec db_restart; /* Database recovery stuff. */ |
|
151 |
xt_mutex_type db_init_sweep_lock; /* Lock so that only one thread can does the initial sweep. */ |
|
152 |
xtBool db_init_sweep_done; /* Set to TRUE once the initial sweep has been done. */ |
|
153 |
xt_mutex_type db_xn_xa_lock; |
|
154 |
XTXactPreparePtr db_xn_xa_table[XT_XA_HASH_TAB_SIZE]; |
|
155 |
XTSortedListPtr db_xn_xa_list; /* The "wait-for" list, of transactions waiting for other transactions. */ |
|
156 |
||
157 |
XTSortedListPtr db_xn_wait_for; /* The "wait-for" list, of transactions waiting for other transactions. */ |
|
158 |
u_int db_xn_call_start; /* Start of the post wait calls. */ |
|
159 |
XTSpinLockRec db_xn_wait_spinlock; |
|
160 |
//xt_mutex_type db_xn_wait_lock; /* The lock associated with the wait for list. */
|
|
161 |
//xt_cond_type db_xn_wait_cond; /* This condition is signalled when a transaction quits. */
|
|
162 |
//u_int db_xn_wait_on_cond; /* Number of threads waiting on the condition. */
|
|
163 |
int db_xn_wait_count; /* Number of waiting transactions. */ |
|
164 |
u_int db_xn_total_writer_count; /* The total number of writers. */ |
|
165 |
int db_xn_writer_count; /* The number of writer threads. */ |
|
166 |
int db_xn_writer_wait_count; /* The number of writer threads waiting. */ |
|
167 |
int db_xn_long_running_count; /* The number of long running writer threads. */ |
|
168 |
||
169 |
/* Sweeper stuff: */
|
|
170 |
struct XTThread *db_sw_thread; /* The sweeper thread (cleans up transactions). */ |
|
171 |
xt_mutex_type db_sw_lock; /* The lock associated with the sweeper. */ |
|
172 |
xt_cond_type db_sw_cond; /* The sweeper wakeup condition. */ |
|
173 |
u_int db_sw_check_count; |
|
174 |
int db_sw_idle; /* BUSY/IDLE/INERR depending on the state of the sweeper. */ |
|
175 |
int db_sw_faster; /* non-zero if the sweeper should work faster. */ |
|
176 |
xtBool db_sw_fast; /* TRUE if the sweeper is working faster. */ |
|
177 |
#ifdef XT_SWEEPER_SORT_XACTS
|
|
178 |
xtXactID db_sw_to_add; /* The next transaction to be added. */ |
|
179 |
u_int db_sw_list_size; /* The number of transaction in the list. */ |
|
180 |
XTXactDataPtr db_sw_xact_list[XT_SW_XACT_SORT_LIST_SIZE]; |
|
181 |
#endif
|
|
182 |
||
183 |
/* Writer stuff: */
|
|
184 |
struct XTThread *db_wr_thread; /* The writer thread (write log data to the database). */ |
|
185 |
int db_wr_idle; /* BUSY/IDLE/INERR depending on the state of the writer. */ |
|
186 |
xtBool db_wr_faster; /* Set to TRUE if the writer should work faster. */ |
|
187 |
xtBool db_wr_fast; /* TRUE if the writer is working faster. */ |
|
188 |
u_int db_wr_thread_waiting; /* Count the number of threads waiting for the writer. */ |
|
189 |
xtBool db_wr_freeer_waiting; /* TRUE if the freeer is wating for the writer. */ |
|
190 |
xt_mutex_type db_wr_lock; |
|
191 |
xt_cond_type db_wr_cond; /* Writer condition when idle (must bw woken by log flush! */ |
|
192 |
xtLogID db_wr_log_id; /* Current write log ID. */ |
|
193 |
xtLogOffset db_wr_log_offset; /* Current write log offset. */ |
|
194 |
xtLogID db_wr_flush_point_log_id; /* This is the point to which the writer will write (log ID). */ |
|
195 |
xtLogOffset db_wr_flush_point_log_offset; /* This is the point to which the writer will write (log offset). */ |
|
196 |
||
197 |
/* Data log stuff: */
|
|
198 |
XTDataLogCacheRec db_datalogs; /* The database data log stuff. */ |
|
199 |
XTIndexLogPoolRec db_indlogs; /* Index logs used for consistent write. */ |
|
200 |
||
201 |
/* Compactor stuff: */
|
|
202 |
struct XTThread *db_co_thread; /* The compator thread (compacts data logs). */ |
|
203 |
xt_mutex_type db_co_ext_lock; /* Required when extended data is moved, or removed. */ |
|
204 |
xtBool db_co_busy; /* True of the compactor is busy compacting a data log. */ |
|
205 |
xt_mutex_type db_co_dlog_lock; /* This is the lock required to flusht the compactors data log. */ |
|
206 |
||
207 |
/* Checkpointer stuff: */
|
|
208 |
struct XTThread *db_cp_thread; /* The checkpoint thread (flushes the database data). */ |
|
209 |
xt_mutex_type db_cp_lock; |
|
210 |
xt_cond_type db_cp_cond; /* Writer condition when idle (must bw woken by log flush! */ |
|
211 |
XTCheckPointStateRec db_cp_state; /* The checkpoint state. */ |
|
212 |
||
213 |
/* Thread pool: */
|
|
214 |
xt_mutex_type db_pool_lock; |
|
215 |
xt_cond_type db_pool_cond; |
|
216 |
u_int db_pool_job_count; /* The number of busy threads. */ |
|
217 |
u_int db_pool_thread_count; /* The number of threads in the pool. */ |
|
218 |
XTThreadPtr db_thread_pool; |
|
219 |
XTTask *db_task_queue_front; |
|
220 |
XTTask *db_task_queue_back; |
|
221 |
||
222 |
/* The "flusher" thread (used when pbxt_flush_log_at_trx_commit = 0 or 2) */
|
|
223 |
struct XTThread *db_fl_thread; /* The flusher thread (flushes the transation log). */ |
|
224 |
xt_mutex_type db_fl_lock; |
|
225 |
} XTDatabaseRec, *XTDatabaseHPtr; /* Heap pointer */ |
|
226 |
||
227 |
#define XT_FOR_USER 0
|
|
228 |
#define XT_FOR_COMPACTOR 1
|
|
229 |
#define XT_FOR_SWEEPER 2
|
|
230 |
#define XT_FOR_WRITER 3
|
|
231 |
#define XT_FOR_CHECKPOINTER 4
|
|
232 |
#define XT_FOR_POOL 5
|
|
233 |
||
234 |
void xt_create_database(XTThreadPtr th, char *path); |
|
235 |
XTDatabaseHPtr xt_get_database(XTThreadPtr self, char *path, xtBool multi_path); |
|
236 |
XTDatabaseHPtr xt_get_database_by_id(XTThreadPtr self, xtDatabaseID db_id); |
|
237 |
void xt_drop_database(XTThreadPtr self, XTDatabaseHPtr db); |
|
238 |
||
239 |
void xt_add_pbxt_file(size_t size, char *path, const char *file); |
|
240 |
void xt_add_location_file(size_t size, char *path); |
|
241 |
void xt_add_tables_file(size_t size, char *path); |
|
242 |
void xt_add_pbxt_dir(size_t size, char *path); |
|
243 |
void xt_add_system_dir(size_t size, char *path); |
|
244 |
void xt_add_data_dir(size_t size, char *path); |
|
245 |
||
246 |
void xt_use_database(XTThreadPtr self, XTDatabaseHPtr db, int what_for); |
|
247 |
void xt_unuse_database(XTThreadPtr self, XTThreadPtr other_thr); |
|
248 |
void xt_open_database(XTThreadPtr self, char *path, xtBool multi_path); |
|
249 |
||
250 |
void xt_lock_installation(XTThreadPtr self, char *installation_path); |
|
251 |
void xt_unlock_installation(XTThreadPtr self, char *installation_path); |
|
252 |
void xt_crash_me(void); |
|
253 |
||
254 |
void xt_init_databases(XTThreadPtr self); |
|
255 |
void xt_stop_database_threads(XTThreadPtr self, xtBool sync); |
|
256 |
void xt_exit_databases(XTThreadPtr self); |
|
257 |
||
258 |
void xt_dump_database(XTThreadPtr self, XTDatabaseHPtr db); |
|
259 |
||
260 |
void xt_db_init_thread_ns(XTThreadPtr new_thread); |
|
261 |
void xt_db_exit_thread(XTThreadPtr self); |
|
262 |
||
263 |
void xt_db_pool_init(XTThreadPtr self, struct XTDatabase *db); |
|
264 |
void xt_db_pool_exit(XTThreadPtr self, struct XTDatabase *db); |
|
265 |
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); |
|
266 |
void xt_db_unlock_table_pool(struct XTThread *self, XTOpenTablePoolPtr table_pool); |
|
267 |
XTOpenTablePtr xt_db_open_pool_table(XTThreadPtr self, XTDatabaseHPtr db, xtTableID tab_id, int *result, xtBool i_am_background); |
|
268 |
XTOpenTablePtr xt_db_open_table_using_tab(XTTableHPtr tab, XTThreadPtr thread); |
|
269 |
xtBool xt_db_open_pool_table_ns(XTOpenTablePtr *ret_ot, XTDatabaseHPtr db, xtTableID tab_id); |
|
270 |
void xt_db_return_table_to_pool(XTThreadPtr self, XTOpenTablePtr ot); |
|
271 |
void xt_db_return_table_to_pool_ns(XTOpenTablePtr ot); |
|
272 |
void xt_db_free_unused_open_tables(XTThreadPtr self, XTDatabaseHPtr db); |
|
273 |
||
274 |
void xt_db_thread_pool_init(XTThreadPtr self, struct XTDatabase *db); |
|
275 |
void xt_db_thread_pool_exit(XTThreadPtr self, struct XTDatabase *db); |
|
276 |
void xt_db_stop_pool_threads(XTThreadPtr self, struct XTDatabase *db); |
|
277 |
xtBool xt_run_async_task(XTTask *task_data, xtBool notify_complete, xtBool notify_early, XTThreadPtr thread, struct XTDatabase *db); |
|
278 |
void xt_wait_for_async_tasks(XTThreadPtr thread); |
|
279 |
XTTask *xt_get_task_result(XTThreadPtr thread); |
|
280 |
xtBool xt_wait_for_async_task_results(XTThreadPtr thread); |
|
281 |
void xt_async_task_notify(XTTask *tk); |
|
282 |
void xt_unit_test_async_task(XTThreadPtr self); |
|
283 |
||
284 |
||
285 |
#define XT_LONG_RUNNING_TIME 2
|
|
286 |
||
287 |
inline void xt_xlog_check_long_writer(XTThreadPtr thread) |
|
288 |
{
|
|
289 |
if (thread->st_xact_writer) { |
|
290 |
if (xt_db_approximate_time - thread->st_xact_write_time > XT_LONG_RUNNING_TIME) { |
|
291 |
if (!thread->st_xact_long_running) { |
|
292 |
thread->st_xact_long_running = TRUE; |
|
293 |
thread->st_database->db_xn_long_running_count++; |
|
294 |
}
|
|
295 |
}
|
|
296 |
}
|
|
297 |
}
|
|
298 |
||
299 |
extern XTDatabaseHPtr pbxt_database; // The global open database |
|
300 |
||
301 |
#endif
|