Merge lp:~jaypipes/drizzle/split-xa-resource-manager into lp:~drizzle-trunk/drizzle/development

Proposed by Jay Pipes
Status: Merged
Merged at revision: not available
Proposed branch: lp:~jaypipes/drizzle/split-xa-resource-manager
Merge into: lp:~drizzle-trunk/drizzle/development
Diff against target: 1256 lines (+568/-375)
12 files modified
drizzled/plugin/transaction_reader.h (+2/-1)
plugin/transaction_log/data_dictionary_schema.cc (+1/-1)
plugin/transaction_log/module.cc (+279/-0)
plugin/transaction_log/plugin.ini (+3/-3)
plugin/transaction_log/transaction_log.cc (+28/-332)
plugin/transaction_log/transaction_log.h (+23/-34)
plugin/transaction_log/transaction_log_applier.cc (+146/-0)
plugin/transaction_log/transaction_log_applier.h (+83/-0)
plugin/transaction_log/transaction_log_index.cc (+0/-1)
plugin/transaction_log/transaction_log_index.h (+0/-1)
plugin/transaction_log/transaction_log_reader.cc (+1/-0)
plugin/transaction_log/transaction_log_reader.h (+2/-2)
To merge this branch: bzr merge lp:~jaypipes/drizzle/split-xa-resource-manager
Reviewer Review Type Date Requested Status
Drizzle Developers Pending
Review via email: mp+20600@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Jay Pipes (jaypipes) wrote :

    * Completes the blueprint for splitting the XA Resource Manager
      API from the storage engine API:

    We add a new plugin::XaResourceManager abstract interface class
    which exposes the X/Open XA distributed transaction protocol for
    resource managers.

    We add a new plugin::MonitoredInTransaction base class from
    which all plugins that need monitored by Drizzle's transaction
    manager (drizzled::TransactionServices component) derive.

    All plugin::StorageEngine's now derive from plugin::MonitoredInTransaction
    since all storage engines a monitored by the transaction manager
    and the Session keeps a "slot" available for keeping the engine's
    per-session data state. In a future patch, the transaction log's
    XaApplier plugin will also derive from MonitoredInTransaction, as
    the transaction log, in XA mode, is also monitored by Drizzle's
    transaction manager and automatically enlisted in XA transactions.

    * Updates all documentation in /drizzled/transaction_services.cc
      to accurately reflect Drizzle's new transaction management
      process and explicit transaction and statement boundaries.

    * Kills off dead code:

      binlog_format_names
      ha_init()
      total_ha, total_ha_2pc (no longer necessary, as the above-mentioned
      abstract base classes provide all of this functionality)
      StorageEngine::slot (now plugin::MonitoredInTransaction::getId())
      TransactionalStorageEngine::two_phase_commit (same as above)

1304. By Jay Pipes <jpipes@serialcoder>

Merge trunk

1305. By Jay Pipes <jpipes@serialcoder>

Merge fixes for LP Bug 530870

1306. By Jay Pipes <jpipes@serialcoder>

Merge trunk and add in data dictionary fix for OSX/FreeBSD

1307. By Jay Pipes <jpipes@serialcoder>

Add errno.h to a few files. Apparently, this is necessary on OSX.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'drizzled/plugin/transaction_reader.h'
2--- drizzled/plugin/transaction_reader.h 2010-02-04 08:14:46 +0000
3+++ drizzled/plugin/transaction_reader.h 2010-03-05 19:18:29 +0000
4@@ -24,7 +24,8 @@
5 #ifndef DRIZZLED_PLUGIN_TRANSACTION_READER_H
6 #define DRIZZLED_PLUGIN_TRANSACTION_READER_H
7
8-#include <drizzled/replication_services.h> /* For global transaction ID typedef */
9+#include "drizzled/plugin/plugin.h"
10+#include "drizzled/replication_services.h" /* For global transaction ID typedef */
11
12 /**
13 * @file Defines the API for a TransactionReader
14
15=== modified file 'plugin/transaction_log/data_dictionary_schema.cc'
16--- plugin/transaction_log/data_dictionary_schema.cc 2010-03-05 04:44:58 +0000
17+++ plugin/transaction_log/data_dictionary_schema.cc 2010-03-05 19:18:29 +0000
18@@ -121,7 +121,7 @@
19 push(transaction_log_index->getMaxTransactionId());
20 push(transaction_log_index->getMinEndTimestamp());
21 push(transaction_log_index->getMaxEndTimestamp());
22- push(transaction_log_index->getSizeInBytes());
23+ push(static_cast<uint64_t>(transaction_log_index->getSizeInBytes()));
24
25 is_done= true;
26 return true;
27
28=== added file 'plugin/transaction_log/module.cc'
29--- plugin/transaction_log/module.cc 1970-01-01 00:00:00 +0000
30+++ plugin/transaction_log/module.cc 2010-03-05 19:18:29 +0000
31@@ -0,0 +1,279 @@
32+/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
33+ * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
34+ *
35+ * Copyright (C) 2008-2009 Sun Microsystems
36+ * Copyright (c) 2010 Jay Pipes <jaypipes@gmail.com>
37+ *
38+ * Authors:
39+ *
40+ * Jay Pipes <jaypipes@gmail.com.com>
41+ *
42+ * This program is free software; you can redistribute it and/or modify
43+ * it under the terms of the GNU General Public License as published by
44+ * the Free Software Foundation; either version 2 of the License, or
45+ * (at your option) any later version.
46+ *
47+ * This program is distributed in the hope that it will be useful,
48+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
49+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50+ * GNU General Public License for more details.
51+ *
52+ * You should have received a copy of the GNU General Public License
53+ * along with this program; if not, write to the Free Software
54+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
55+ */
56+
57+/**
58+ * @file
59+ *
60+ * Transaction log module initialization and plugin
61+ * registration.
62+ */
63+
64+#include "config.h"
65+
66+#include "transaction_log.h"
67+#include "transaction_log_applier.h"
68+#include "transaction_log_index.h"
69+#include "data_dictionary_schema.h"
70+#include "print_transaction_message.h"
71+#include "hexdump_transaction_message.h"
72+#include "background_worker.h"
73+
74+#include <drizzled/plugin/plugin.h>
75+#include <drizzled/session.h>
76+#include <drizzled/set_var.h>
77+#include <drizzled/gettext.h>
78+
79+using namespace std;
80+using namespace drizzled;
81+
82+/**
83+ * Transaction Log plugin system variable - Is the log enabled? Only used on init().
84+ * The enable() and disable() methods of the TransactionLog class control online
85+ * disabling.
86+ */
87+static bool sysvar_transaction_log_enabled= false;
88+/** Transaction Log plugin system variable - The path to the log file used */
89+static char* sysvar_transaction_log_file= NULL;
90+/**
91+ * Transaction Log plugin system variable - A debugging variable to assist
92+ * in truncating the log file.
93+ */
94+static bool sysvar_transaction_log_truncate_debug= false;
95+static const char DEFAULT_LOG_FILE_PATH[]= "transaction.log"; /* In datadir... */
96+/**
97+ * Transaction Log plugin system variable - Should we write a CRC32 checksum for
98+ * each written Transaction message?
99+ */
100+static bool sysvar_transaction_log_checksum_enabled= false;
101+/**
102+ * Numeric option controlling the sync/flush behaviour of the transaction
103+ * log. Options are:
104+ *
105+ * TransactionLog::SYNC_METHOD_OS == 0 ... let OS do sync'ing
106+ * TransactionLog::SYNC_METHOD_EVERY_WRITE == 1 ... sync on every write
107+ * TransactionLog::SYNC_METHOD_EVERY_SECOND == 2 ... sync at most once a second
108+ */
109+static uint32_t sysvar_transaction_log_sync_method= 0;
110+
111+/** DATA_DICTIONARY views */
112+static TransactionLogTool *transaction_log_tool;
113+static TransactionLogEntriesTool *transaction_log_entries_tool;
114+static TransactionLogTransactionsTool *transaction_log_transactions_tool;
115+
116+/** Index defined in transaction_log_index.cc */
117+extern TransactionLogIndex *transaction_log_index;
118+/** Transaction Log descriptor defined in transaction_log.cc */
119+extern TransactionLog *transaction_log;
120+/** Transaction Log descriptor defined in transaction_log.cc */
121+extern TransactionLogApplier *transaction_log_applier;
122+
123+/** Defined in print_transaction_message.cc */
124+extern plugin::Create_function<PrintTransactionMessageFunction> *print_transaction_message_func_factory;
125+extern plugin::Create_function<HexdumpTransactionMessageFunction> *hexdump_transaction_message_func_factory;
126+
127+static int init(drizzled::plugin::Registry &registry)
128+{
129+ /* Create and initialize the transaction log itself */
130+ if (sysvar_transaction_log_enabled)
131+ {
132+ transaction_log= new (nothrow) TransactionLog(string(sysvar_transaction_log_file),
133+ sysvar_transaction_log_sync_method);
134+
135+ if (transaction_log == NULL)
136+ {
137+ errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the TransactionLog instance. Got error: %s\n"),
138+ strerror(errno));
139+ return 1;
140+ }
141+ else
142+ {
143+ /* Check to see if the log was not created properly */
144+ if (transaction_log->hasError())
145+ {
146+ errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize the Transaction Log. Got error: %s\n"),
147+ transaction_log->getErrorMessage().c_str());
148+ return 1;
149+ }
150+ }
151+ /* Create the applier plugin and register it */
152+ transaction_log_applier= new (nothrow) TransactionLogApplier("transaction_log_applier",
153+ *transaction_log,
154+ sysvar_transaction_log_checksum_enabled);
155+ if (transaction_log_applier == NULL)
156+ {
157+ errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the TransactionLogApplier instance. Got error: %s\n"),
158+ strerror(errno));
159+ return 1;
160+ }
161+ registry.add(transaction_log_applier);
162+
163+ /* Setup DATA_DICTIONARY views */
164+
165+ transaction_log_tool= new (nothrow) TransactionLogTool;
166+ registry.add(transaction_log_tool);
167+ transaction_log_entries_tool= new (nothrow) TransactionLogEntriesTool;
168+ registry.add(transaction_log_entries_tool);
169+ transaction_log_transactions_tool= new (nothrow) TransactionLogTransactionsTool;
170+ registry.add(transaction_log_transactions_tool);
171+
172+ /* Setup the module's UDFs */
173+ print_transaction_message_func_factory=
174+ new plugin::Create_function<PrintTransactionMessageFunction>("print_transaction_message");
175+ registry.add(print_transaction_message_func_factory);
176+
177+ hexdump_transaction_message_func_factory=
178+ new plugin::Create_function<HexdumpTransactionMessageFunction>("hexdump_transaction_message");
179+ registry.add(hexdump_transaction_message_func_factory);
180+
181+ /* Create and initialize the transaction log index */
182+ transaction_log_index= new (nothrow) TransactionLogIndex(*transaction_log);
183+ if (transaction_log_index == NULL)
184+ {
185+ errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the TransactionLogIndex instance. Got error: %s\n"),
186+ strerror(errno));
187+ return 1;
188+ }
189+ else
190+ {
191+ /* Check to see if the index was not created properly */
192+ if (transaction_log_index->hasError())
193+ {
194+ errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize the Transaction Log Index. Got error: %s\n"),
195+ transaction_log_index->getErrorMessage().c_str());
196+ return 1;
197+ }
198+ }
199+
200+ /*
201+ * Setup the background worker thread which maintains
202+ * summary information about the transaction log.
203+ */
204+ if (initTransactionLogBackgroundWorker())
205+ return 1; /* Error message output handled in function above */
206+ }
207+ return 0;
208+}
209+
210+static int deinit(drizzled::plugin::Registry &registry)
211+{
212+ /* Cleanup the transaction log itself */
213+ if (transaction_log)
214+ {
215+ registry.remove(transaction_log_applier);
216+ delete transaction_log;
217+ delete transaction_log_index;
218+
219+ /* Cleanup the DATA_DICTIONARY views */
220+ registry.remove(transaction_log_tool);
221+ delete transaction_log_tool;
222+ registry.remove(transaction_log_entries_tool);
223+ delete transaction_log_entries_tool;
224+ registry.remove(transaction_log_transactions_tool);
225+ delete transaction_log_transactions_tool;
226+
227+ /* Cleanup module UDFs */
228+ registry.remove(print_transaction_message_func_factory);
229+ delete print_transaction_message_func_factory;
230+ registry.remove(hexdump_transaction_message_func_factory);
231+ delete hexdump_transaction_message_func_factory;
232+ }
233+
234+ return 0;
235+}
236+
237+static void set_truncate_debug(Session *,
238+ drizzle_sys_var *,
239+ void *,
240+ const void *save)
241+{
242+ /*
243+ * The const void * save comes directly from the check function,
244+ * which should simply return the result from the set statement.
245+ */
246+ if (transaction_log)
247+ {
248+ if (*(bool *)save != false)
249+ {
250+ transaction_log->truncate();
251+ transaction_log_index->clear();
252+ }
253+ }
254+}
255+
256+static DRIZZLE_SYSVAR_BOOL(enable,
257+ sysvar_transaction_log_enabled,
258+ PLUGIN_VAR_NOCMDARG,
259+ N_("Enable transaction log"),
260+ NULL, /* check func */
261+ NULL, /* update func */
262+ false /* default */);
263+
264+static DRIZZLE_SYSVAR_BOOL(truncate_debug,
265+ sysvar_transaction_log_truncate_debug,
266+ PLUGIN_VAR_NOCMDARG,
267+ N_("DEBUGGING - Truncate transaction log"),
268+ NULL, /* check func */
269+ set_truncate_debug, /* update func */
270+ false /* default */);
271+
272+static DRIZZLE_SYSVAR_STR(log_file,
273+ sysvar_transaction_log_file,
274+ PLUGIN_VAR_READONLY,
275+ N_("Path to the file to use for transaction log"),
276+ NULL, /* check func */
277+ NULL, /* update func*/
278+ DEFAULT_LOG_FILE_PATH /* default */);
279+
280+static DRIZZLE_SYSVAR_BOOL(enable_checksum,
281+ sysvar_transaction_log_checksum_enabled,
282+ PLUGIN_VAR_NOCMDARG,
283+ N_("Enable CRC32 Checksumming of each written transaction log entry"),
284+ NULL, /* check func */
285+ NULL, /* update func */
286+ false /* default */);
287+
288+static DRIZZLE_SYSVAR_UINT(sync_method,
289+ sysvar_transaction_log_sync_method,
290+ PLUGIN_VAR_OPCMDARG,
291+ N_("0 == rely on operating system to sync log file (default), "
292+ "1 == sync file at each transaction write, "
293+ "2 == sync log file once per second"),
294+ NULL, /* check func */
295+ NULL, /* update func */
296+ 0, /* default */
297+ 0,
298+ 2,
299+ 0);
300+
301+static drizzle_sys_var* sys_variables[]= {
302+ DRIZZLE_SYSVAR(enable),
303+ DRIZZLE_SYSVAR(truncate_debug),
304+ DRIZZLE_SYSVAR(log_file),
305+ DRIZZLE_SYSVAR(enable_checksum),
306+ DRIZZLE_SYSVAR(sync_method),
307+ NULL
308+};
309+
310+DRIZZLE_PLUGIN(init, deinit, sys_variables);
311
312=== modified file 'plugin/transaction_log/plugin.ini'
313--- plugin/transaction_log/plugin.ini 2010-02-11 04:18:03 +0000
314+++ plugin/transaction_log/plugin.ini 2010-03-05 19:18:29 +0000
315@@ -1,13 +1,13 @@
316 [plugin]
317 name=transaction_log
318-version=0.1
319+version=0.1.1
320 author=Jay Pipes
321 license=PLUGIN_LICENSE_GPL
322 title=Transaction Log
323 description=Log of Transaction Messages
324 load_by_default=yes
325-sources= background_worker.cc hexdump_transaction_message.cc print_transaction_message.cc transaction_log.cc transaction_log_entry.cc transaction_log_index.cc transaction_log_reader.cc data_dictionary_schema.cc
326-headers= background_worker.h hexdump_transaction_message.h print_transaction_message.h transaction_log.h transaction_log_entry.h transaction_log_index.h transaction_log_reader.h data_dictionary_schema.h
327+sources= background_worker.cc hexdump_transaction_message.cc module.cc print_transaction_message.cc transaction_log.cc transaction_log_applier.cc transaction_log_entry.cc transaction_log_index.cc transaction_log_reader.cc data_dictionary_schema.cc
328+headers= background_worker.h hexdump_transaction_message.h print_transaction_message.h transaction_log.h transaction_log_applier.h transaction_log_entry.h transaction_log_index.h transaction_log_reader.h data_dictionary_schema.h
329 libs=${top_builddir}/drizzled/algorithm/libhash.la
330 libadd=$(LIBZ)
331 cxxflags=${PROTOSKIP_WARNINGS}
332
333=== modified file 'plugin/transaction_log/transaction_log.cc'
334--- plugin/transaction_log/transaction_log.cc 2010-03-05 04:44:58 +0000
335+++ plugin/transaction_log/transaction_log.cc 2010-03-05 19:18:29 +0000
336@@ -2,10 +2,11 @@
337 * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
338 *
339 * Copyright (C) 2008-2009 Sun Microsystems
340+ * Copyright (c) 2010 Jay Pipes <jaypipes@gmail.com>
341 *
342 * Authors:
343 *
344- * Jay Pipes <joinfu@sun.com>
345+ * Jay Pipes <jaypipes@gmail.com.com>
346 *
347 * This program is free software; you can redistribute it and/or modify
348 * it under the terms of the GNU General Public License as published by
349@@ -25,10 +26,7 @@
350 /**
351 * @file
352 *
353- * Defines the implementation of the default transaction log.
354- *
355- * @see drizzled/plugin/transaction_replicator.h
356- * @see drizzled/plugin/transaction_applier.h
357+ * Defines the implementation of the transaction log file descriptor.
358 *
359 * @details
360 *
361@@ -37,7 +35,7 @@
362 * We have an atomic off_t called log_offset which keeps track of the
363 * offset into the log file for writing the next Transaction.
364 *
365- * We write Transaction message encapsulated in an 8-byte length header and a
366+ * We write Transaction message encapsulated in an 8-byte length/type header and a
367 * 4-byte checksum trailer.
368 *
369 * When writing a Transaction to the log, we calculate the length of the
370@@ -63,93 +61,36 @@
371 * Possibly look at a scoreboard approach with multiple file segments. For
372 * right now, though, this is just a quick simple implementation to serve
373 * as a skeleton and a springboard.
374- *
375- * @todo
376- *
377- * Move the Applier piece of this code out into its own source file and leave
378- * this for all the glue code of the module.
379 */
380
381 #include "config.h"
382 #include "transaction_log.h"
383-#include "transaction_log_index.h"
384-#include "data_dictionary_schema.h"
385-#include "print_transaction_message.h"
386-#include "hexdump_transaction_message.h"
387-#include "background_worker.h"
388
389 #include <sys/stat.h>
390 #include <fcntl.h>
391 #include <unistd.h>
392+#include <errno.h>
393
394 #include <vector>
395 #include <string>
396
397-#include "drizzled/internal/my_sys.h" /* for internal::my_sync */
398-
399-#include <drizzled/session.h>
400-#include <drizzled/set_var.h>
401+#include <drizzled/internal/my_sys.h> /* for internal::my_sync */
402+#include <drizzled/errmsg_print.h>
403 #include <drizzled/gettext.h>
404-#include <drizzled/algorithm/crc32.h>
405-#include <drizzled/message/transaction.pb.h>
406-#include <google/protobuf/io/coded_stream.h>
407
408 using namespace std;
409 using namespace drizzled;
410-using namespace google;
411-
412-/**
413- * Transaction Log plugin system variable - Is the log enabled? Only used on init().
414- * The enable() and disable() methods of the TransactionLog class control online
415- * disabling.
416- */
417-static bool sysvar_transaction_log_enabled= false;
418-/** Transaction Log plugin system variable - The path to the log file used */
419-static char* sysvar_transaction_log_file= NULL;
420-/**
421- * Transaction Log plugin system variable - A debugging variable to assist
422- * in truncating the log file.
423- */
424-static bool sysvar_transaction_log_truncate_debug= false;
425-static const char DEFAULT_LOG_FILE_PATH[]= "transaction.log"; /* In datadir... */
426-/**
427- * Transaction Log plugin system variable - Should we write a CRC32 checksum for
428- * each written Transaction message?
429- */
430-static bool sysvar_transaction_log_checksum_enabled= false;
431-/**
432- * Numeric option controlling the sync/flush behaviour of the transaction
433- * log. Options are:
434- *
435- * TransactionLog::SYNC_METHOD_OS == 0 ... let OS do sync'ing
436- * TransactionLog::SYNC_METHOD_EVERY_WRITE == 1 ... sync on every write
437- * TransactionLog::SYNC_METHOD_EVERY_SECOND == 2 ... sync at most once a second
438- */
439-static uint32_t sysvar_transaction_log_sync_method= 0;
440-
441-/** DATA_DICTIONARY views */
442-static TransactionLogTool *transaction_log_tool;
443-static TransactionLogEntriesTool *transaction_log_entries_tool;
444-static TransactionLogTransactionsTool *transaction_log_transactions_tool;
445-
446-/** Index defined in transaction_log_index.cc */
447-extern TransactionLogIndex *transaction_log_index;
448-
449-/** Defined in print_transaction_message.cc */
450-extern plugin::Create_function<PrintTransactionMessageFunction> *print_transaction_message_func_factory;
451-extern plugin::Create_function<HexdumpTransactionMessageFunction> *hexdump_transaction_message_func_factory;
452-
453-TransactionLog::TransactionLog(string name_arg,
454- const string &in_log_file_path,
455- bool in_do_checksum)
456- : plugin::TransactionApplier(name_arg),
457+
458+TransactionLog *transaction_log= NULL; /* The singleton transaction log */
459+
460+TransactionLog::TransactionLog(const string in_log_file_path,
461+ uint32_t in_sync_method) :
462 state(OFFLINE),
463 log_file_path(in_log_file_path),
464 has_error(false),
465- error_message()
466+ error_message(),
467+ sync_method(in_sync_method)
468 {
469- do_checksum= in_do_checksum; /* Have to do here, not in initialization list b/c atomic<> */
470-
471 /* Setup our log file and determine the next write offset... */
472 log_file= open(log_file_path.c_str(), O_APPEND|O_CREAT|O_SYNC|O_WRONLY, S_IRWXU);
473 if (log_file == -1)
474@@ -160,7 +101,6 @@
475 error_message.append(strerror(errno));
476 error_message.push_back('\n');
477 has_error= true;
478- deactivate();
479 return;
480 }
481
482@@ -187,74 +127,26 @@
483 TransactionLog::~TransactionLog()
484 {
485 /* Clear up any resources we've consumed */
486- if (isEnabled() && log_file != -1)
487+ if (log_file != -1)
488 {
489 (void) close(log_file);
490 }
491 }
492
493-void TransactionLog::apply(const message::Transaction &to_apply)
494+off_t TransactionLog::writeEntry(const uint8_t *data, size_t data_length)
495 {
496- uint8_t *buffer; /* Buffer we will write serialized header,
497- message and trailing checksum to */
498- uint8_t *orig_buffer;
499-
500- size_t message_byte_length= to_apply.ByteSize();
501- ssize_t written;
502- off_t cur_offset;
503- size_t total_envelope_length= HEADER_TRAILER_BYTES + message_byte_length;
504-
505- /*
506- * Attempt allocation of raw memory buffer for the header,
507- * message and trailing checksum bytes.
508- */
509- buffer= static_cast<uint8_t *>(malloc(total_envelope_length));
510- if (buffer == NULL)
511- {
512- errmsg_printf(ERRMSG_LVL_ERROR,
513- _("Failed to allocate enough memory to buffer header, transaction message, and trailing checksum bytes. Tried to allocate %" PRId64
514- " bytes. Error: %s\n"),
515- static_cast<int64_t>(total_envelope_length),
516- strerror(errno));
517- state= CRASHED;
518- deactivate();
519- return;
520- }
521- else
522- orig_buffer= buffer; /* We will free() orig_buffer, as buffer is moved during write */
523+ ssize_t written= 0;
524
525 /*
526 * Do an atomic increment on the offset of the log file position
527 */
528- cur_offset= log_offset.fetch_and_add(static_cast<off_t>(total_envelope_length));
529+ off_t cur_offset= log_offset.fetch_and_add(static_cast<off_t>(data_length));
530
531 /*
532 * We adjust cur_offset back to the original log_offset before
533 * the increment above...
534 */
535- cur_offset-= static_cast<off_t>((total_envelope_length));
536-
537- /*
538- * Write the header information, which is the message type and
539- * the length of the transaction message into the buffer
540- */
541- buffer= protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray(static_cast<uint32_t>(ReplicationServices::TRANSACTION), buffer);
542- buffer= protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray(static_cast<uint32_t>(message_byte_length), buffer);
543-
544- /*
545- * Now write the serialized transaction message, followed
546- * by the optional checksum into the buffer.
547- */
548- buffer= to_apply.SerializeWithCachedSizesToArray(buffer);
549-
550- uint32_t checksum= 0;
551- if (do_checksum)
552- {
553- checksum= drizzled::algorithm::crc32(reinterpret_cast<char *>(buffer) - message_byte_length, message_byte_length);
554- }
555-
556- /* We always write in network byte order */
557- buffer= protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray(checksum, buffer);
558+ cur_offset-= static_cast<off_t>(data_length);
559
560 /*
561 * Quick safety...if an error occurs above in another writer, the log
562@@ -267,23 +159,22 @@
563 * the original offset where an error occurred.
564 */
565 log_offset= cur_offset;
566- free(orig_buffer);
567- return;
568+ return log_offset;
569 }
570
571 /* Write the full buffer in one swoop */
572 do
573 {
574- written= pwrite(log_file, orig_buffer, total_envelope_length, cur_offset);
575+ written= pwrite(log_file, data, data_length, cur_offset);
576 }
577 while (written == -1 && errno == EINTR); /* Just retry the write when interrupted by a signal... */
578
579- if (unlikely(written != static_cast<ssize_t>(total_envelope_length)))
580+ if (unlikely(written != static_cast<ssize_t>(data_length)))
581 {
582 errmsg_printf(ERRMSG_LVL_ERROR,
583- _("Failed to write full size of transaction. Tried to write %" PRId64
584+ _("Failed to write full size of log entry. Tried to write %" PRId64
585 " bytes at offset %" PRId64 ", but only wrote %" PRId32 " bytes. Error: %s\n"),
586- static_cast<int64_t>(total_envelope_length),
587+ static_cast<int64_t>(data_length),
588 static_cast<int64_t>(cur_offset),
589 static_cast<int64_t>(written),
590 strerror(errno));
591@@ -293,29 +184,22 @@
592 * the original offset where an error occurred.
593 */
594 log_offset= cur_offset;
595- deactivate();
596 }
597- free(orig_buffer);
598
599 int error_code= syncLogFile();
600
601- transaction_log_index->addEntry(TransactionLogEntry(ReplicationServices::TRANSACTION,
602- cur_offset,
603- total_envelope_length),
604- to_apply,
605- checksum);
606-
607 if (unlikely(error_code != 0))
608 {
609 errmsg_printf(ERRMSG_LVL_ERROR,
610 _("Failed to sync log file. Got error: %s\n"),
611 strerror(errno));
612 }
613+ return cur_offset;
614 }
615
616 int TransactionLog::syncLogFile()
617 {
618- switch (sysvar_transaction_log_sync_method)
619+ switch (sync_method)
620 {
621 case SYNC_METHOD_EVERY_WRITE:
622 return internal::my_sync(log_file, 0);
623@@ -347,20 +231,11 @@
624
625 void TransactionLog::truncate()
626 {
627- bool orig_is_enabled= isEnabled();
628- disable();
629-
630 /*
631- * Wait a short amount of time before truncating. This just prevents error messages
632- * from being produced during a call to apply(). Calling disable() above
633- * means that once the current caller to apply() is done, no other calls are made to
634- * apply() before enable is reset to its original state
635- *
636 * @note
637 *
638- * This is DEBUG code only!
639+ * This is NOT THREAD SAFE! DEBUG/TEST code only!
640 */
641- usleep(500); /* Sleep for half a second */
642 log_offset= (off_t) 0;
643 int result;
644 do
645@@ -368,12 +243,6 @@
646 result= ftruncate(log_file, log_offset);
647 }
648 while (result == -1 && errno == EINTR);
649-
650- /* Clear the transaction log index data */
651- transaction_log_index->clear();
652-
653- if (orig_is_enabled)
654- enable();
655 }
656
657 bool TransactionLog::findLogFilenameContainingTransactionId(const ReplicationServices::GlobalTransactionId&,
658@@ -399,180 +268,7 @@
659 error_message.clear();
660 }
661
662-const std::string &TransactionLog::getErrorMessage() const
663+const string &TransactionLog::getErrorMessage() const
664 {
665 return error_message;
666 }
667-
668-TransactionLog *transaction_log= NULL; /* The singleton transaction log */
669-
670-static int init(drizzled::plugin::Registry &registry)
671-{
672- /* Create and initialize the transaction log itself */
673- if (sysvar_transaction_log_enabled)
674- {
675- transaction_log= new (nothrow) TransactionLog("transaction_log_applier",
676- string(sysvar_transaction_log_file),
677- sysvar_transaction_log_checksum_enabled);
678-
679- if (transaction_log == NULL)
680- {
681- errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the TransactionLog instance. Got error: %s\n"),
682- strerror(errno));
683- return 1;
684- }
685- else
686- {
687- /* Check to see if the log was not created properly */
688- if (transaction_log->hasError())
689- {
690- errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize the Transaction Log. Got error: %s\n"),
691- transaction_log->getErrorMessage().c_str());
692- return 1;
693- }
694- }
695- registry.add(transaction_log);
696-
697- /* Setup DATA_DICTIONARY views */
698-
699- transaction_log_tool= new(std::nothrow)TransactionLogTool;
700- registry.add(transaction_log_tool);
701- transaction_log_entries_tool= new(std::nothrow)TransactionLogEntriesTool;
702- registry.add(transaction_log_entries_tool);
703- transaction_log_transactions_tool= new(std::nothrow)TransactionLogTransactionsTool;
704- registry.add(transaction_log_transactions_tool);
705-
706- /* Setup the module's UDFs */
707- print_transaction_message_func_factory=
708- new plugin::Create_function<PrintTransactionMessageFunction>("print_transaction_message");
709- registry.add(print_transaction_message_func_factory);
710-
711- hexdump_transaction_message_func_factory=
712- new plugin::Create_function<HexdumpTransactionMessageFunction>("hexdump_transaction_message");
713- registry.add(hexdump_transaction_message_func_factory);
714-
715- /* Create and initialize the transaction log index */
716- transaction_log_index= new (nothrow) TransactionLogIndex(*transaction_log);
717- if (transaction_log_index == NULL)
718- {
719- errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the TransactionLogIndex instance. Got error: %s\n"),
720- strerror(errno));
721- return 1;
722- }
723- else
724- {
725- /* Check to see if the index was not created properly */
726- if (transaction_log_index->hasError())
727- {
728- errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize the Transaction Log Index. Got error: %s\n"),
729- transaction_log_index->getErrorMessage().c_str());
730- return 1;
731- }
732- }
733-
734- /*
735- * Setup the background worker thread which maintains
736- * summary information about the transaction log.
737- */
738- if (initTransactionLogBackgroundWorker())
739- return 1; /* Error message output handled in function above */
740- }
741- return 0;
742-}
743-
744-static int deinit(drizzled::plugin::Registry &registry)
745-{
746- /* Cleanup the transaction log itself */
747- if (transaction_log)
748- {
749- registry.remove(transaction_log);
750- delete transaction_log;
751- delete transaction_log_index;
752-
753- /* Cleanup the DATA_DICTIONARY views */
754- registry.remove(transaction_log_tool);
755- delete transaction_log_tool;
756- registry.remove(transaction_log_entries_tool);
757- delete transaction_log_entries_tool;
758- registry.remove(transaction_log_transactions_tool);
759- delete transaction_log_transactions_tool;
760-
761- /* Cleanup module UDFs */
762- registry.remove(print_transaction_message_func_factory);
763- delete print_transaction_message_func_factory;
764- registry.remove(hexdump_transaction_message_func_factory);
765- delete hexdump_transaction_message_func_factory;
766- }
767-
768- return 0;
769-}
770-
771-static void set_truncate_debug(Session *,
772- drizzle_sys_var *,
773- void *,
774- const void *save)
775-{
776- /*
777- * The const void * save comes directly from the check function,
778- * which should simply return the result from the set statement.
779- */
780- if (transaction_log)
781- if (*(bool *)save != false)
782- transaction_log->truncate();
783-}
784-
785-static DRIZZLE_SYSVAR_BOOL(enable,
786- sysvar_transaction_log_enabled,
787- PLUGIN_VAR_NOCMDARG,
788- N_("Enable transaction log"),
789- NULL, /* check func */
790- NULL, /* update func */
791- false /* default */);
792-
793-static DRIZZLE_SYSVAR_BOOL(truncate_debug,
794- sysvar_transaction_log_truncate_debug,
795- PLUGIN_VAR_NOCMDARG,
796- N_("DEBUGGING - Truncate transaction log"),
797- NULL, /* check func */
798- set_truncate_debug, /* update func */
799- false /* default */);
800-
801-static DRIZZLE_SYSVAR_STR(log_file,
802- sysvar_transaction_log_file,
803- PLUGIN_VAR_READONLY,
804- N_("Path to the file to use for transaction log"),
805- NULL, /* check func */
806- NULL, /* update func*/
807- DEFAULT_LOG_FILE_PATH /* default */);
808-
809-static DRIZZLE_SYSVAR_BOOL(enable_checksum,
810- sysvar_transaction_log_checksum_enabled,
811- PLUGIN_VAR_NOCMDARG,
812- N_("Enable CRC32 Checksumming of each written transaction log entry"),
813- NULL, /* check func */
814- NULL, /* update func */
815- false /* default */);
816-
817-static DRIZZLE_SYSVAR_UINT(sync_method,
818- sysvar_transaction_log_sync_method,
819- PLUGIN_VAR_OPCMDARG,
820- N_("0 == rely on operating system to sync log file (default), "
821- "1 == sync file at each transaction write, "
822- "2 == sync log file once per second"),
823- NULL, /* check func */
824- NULL, /* update func */
825- 0, /* default */
826- 0,
827- 2,
828- 0);
829-
830-static drizzle_sys_var* sys_variables[]= {
831- DRIZZLE_SYSVAR(enable),
832- DRIZZLE_SYSVAR(truncate_debug),
833- DRIZZLE_SYSVAR(log_file),
834- DRIZZLE_SYSVAR(enable_checksum),
835- DRIZZLE_SYSVAR(sync_method),
836- NULL
837-};
838-
839-DRIZZLE_PLUGIN(init, deinit, sys_variables);
840
841=== modified file 'plugin/transaction_log/transaction_log.h'
842--- plugin/transaction_log/transaction_log.h 2009-12-11 18:39:37 +0000
843+++ plugin/transaction_log/transaction_log.h 2010-03-05 19:18:29 +0000
844@@ -2,10 +2,11 @@
845 * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
846 *
847 * Copyright (C) 2008-2009 Sun Microsystems
848+ * Copyright (c) 2010 Jay Pipes <jaypipes@gmail.com>
849 *
850 * Authors:
851 *
852- * Jay Pipes <joinfu@sun.com>
853+ * Jay Pipes <jaypipes@gmail.com.com>
854 *
855 * This program is free software; you can redistribute it and/or modify
856 * it under the terms of the GNU General Public License as published by
857@@ -25,18 +26,13 @@
858 /**
859 * @file
860 *
861- * Defines the API of the default transaction log.
862- *
863- * @see drizzled/plugin/replicator.h
864- * @see drizzled/plugin/applier.h
865+ * Defines the API of the transaction log file descriptor.
866 *
867 * @details
868 *
869- * The TransactionLog applies events it receives from the ReplicationServices
870- * server component to a simple log file on disk.
871- *
872- * Transactions are received in no guaranteed order and the command log
873- * is in charge of writing these events to the log as they are received.
874+ * Basically, the TransactionLog is a descriptor for a log
875+ * file containing transaction messages that is written by
876+ * the TransactionLogApplier plugin(s).
877 */
878
879 #ifndef PLUGIN_TRANSACTION_LOG_TRANSACTION_LOG_H
880@@ -44,15 +40,13 @@
881
882 #include <drizzled/atomics.h>
883 #include <drizzled/replication_services.h>
884-#include <drizzled/plugin/transaction_replicator.h>
885-#include <drizzled/plugin/transaction_applier.h>
886
887 #include "transaction_log_entry.h"
888
889 #include <vector>
890 #include <string>
891
892-class TransactionLog: public drizzled::plugin::TransactionApplier
893+class TransactionLog
894 {
895 public:
896 static const uint32_t HEADER_TRAILER_BYTES= sizeof(uint32_t) + /* 4-byte msg type header */
897@@ -75,31 +69,13 @@
898 static const uint32_t SYNC_METHOD_EVERY_WRITE= 1; //< Sync on every write to the log file
899 static const uint32_t SYNC_METHOD_EVERY_SECOND= 2; ///< Sync no more than once a second
900 public:
901- TransactionLog(std::string name_arg,
902- const std::string &in_log_file_path,
903- bool in_do_checksum);
904+ TransactionLog(const std::string in_log_file_path,
905+ uint32_t in_sync_method);
906
907 /** Destructor */
908 ~TransactionLog();
909
910 /**
911- * Applies a Transaction to the serial log
912- *
913- * @note
914- *
915- * It is important to note that memory allocation for the
916- * supplied pointer is not guaranteed after the completion
917- * of this function -- meaning the caller can dispose of the
918- * supplied message. Therefore, appliers which are
919- * implementing an asynchronous replication system must copy
920- * the supplied message to their own controlled memory storage
921- * area.
922- *
923- * @param Transaction message to be replicated
924- */
925- void apply(const drizzled::message::Transaction &to_apply);
926-
927- /**
928 * Returns the current offset into the log
929 */
930 inline off_t getLogOffset()
931@@ -126,6 +102,19 @@
932 }
933
934 /**
935+ * Writes a chunk of data to the log file of a specified
936+ * length and returns the offset at which the chunk of
937+ * data was written.
938+ *
939+ * @param[in] Bytes to write
940+ * @param[in[ Length of bytes to write
941+ *
942+ * @retval
943+ * Returns the write offset if the write succeeded, OFF_T_MAX otherwise.
944+ */
945+ off_t writeEntry(const uint8_t *data, size_t data_length);
946+
947+ /**
948 * Truncates the existing log file
949 *
950 * @note
951@@ -185,12 +174,12 @@
952
953 int log_file; ///< Handle for our log file
954 Status state; ///< The state the log is in
955- drizzled::atomic<bool> do_checksum; ///< Do a CRC32 checksum when writing Transaction message to log?
956 const std::string log_file_path; ///< Full path to the log file
957 std::string log_file_name; ///< Name of the log file
958 drizzled::atomic<off_t> log_offset; ///< Offset in log file where log will write next command
959 bool has_error; ///< Is the log in error?
960 std::string error_message; ///< Current error message
961+ uint32_t sync_method; ///< Determines behaviour of syncing log file
962 time_t last_sync_time; ///< Last time the log file was synced (only set in SYNC_METHOD_EVERY_SECOND)
963 };
964
965
966=== added file 'plugin/transaction_log/transaction_log_applier.cc'
967--- plugin/transaction_log/transaction_log_applier.cc 1970-01-01 00:00:00 +0000
968+++ plugin/transaction_log/transaction_log_applier.cc 2010-03-05 19:18:29 +0000
969@@ -0,0 +1,146 @@
970+/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
971+ * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
972+ *
973+ * Copyright (C) 2008-2009 Sun Microsystems
974+ * Copyright (c) 2010 Jay Pipes <jaypipes@gmail.com>
975+ *
976+ * Authors:
977+ *
978+ * Jay Pipes <jaypipes@gmail.com.com>
979+ *
980+ * This program is free software; you can redistribute it and/or modify
981+ * it under the terms of the GNU General Public License as published by
982+ * the Free Software Foundation; either version 2 of the License, or
983+ * (at your option) any later version.
984+ *
985+ * This program is distributed in the hope that it will be useful,
986+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
987+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
988+ * GNU General Public License for more details.
989+ *
990+ * You should have received a copy of the GNU General Public License
991+ * along with this program; if not, write to the Free Software
992+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
993+ */
994+
995+/**
996+ * @file
997+ *
998+ * Defines the implementation of the transaction applier plugin
999+ * for the transaction log.
1000+ *
1001+ * @see drizzled/plugin/transaction_replicator.h
1002+ * @see drizzled/plugin/transaction_applier.h
1003+ *
1004+ * @details
1005+ *
1006+ * The TransactionLogApplier::apply() method constructs the entry
1007+ * in the transaction log from the supplied Transaction message and
1008+ * asks its associated TransactionLog object to write this entry.
1009+ *
1010+ * Upon a successful write, the applier adds some information about
1011+ * the written transaction to the transaction log index.
1012+ */
1013+
1014+#include "config.h"
1015+#include "transaction_log.h"
1016+#include "transaction_log_applier.h"
1017+#include "transaction_log_index.h"
1018+
1019+#include <sys/stat.h>
1020+#include <fcntl.h>
1021+#include <unistd.h>
1022+#include <errno.h>
1023+
1024+#include <drizzled/errmsg_print.h>
1025+#include <drizzled/gettext.h>
1026+#include <drizzled/algorithm/crc32.h>
1027+#include <drizzled/message/transaction.pb.h>
1028+#include <google/protobuf/io/coded_stream.h>
1029+
1030+using namespace std;
1031+using namespace drizzled;
1032+using namespace google;
1033+
1034+TransactionLogApplier *transaction_log_applier= NULL; /* The singleton transaction log applier */
1035+
1036+extern TransactionLogIndex *transaction_log_index;
1037+
1038+TransactionLogApplier::TransactionLogApplier(const string name_arg,
1039+ TransactionLog &in_transaction_log,
1040+ bool in_do_checksum) :
1041+ plugin::TransactionApplier(name_arg),
1042+ transaction_log(in_transaction_log),
1043+ do_checksum(in_do_checksum)
1044+{
1045+}
1046+
1047+TransactionLogApplier::~TransactionLogApplier()
1048+{
1049+}
1050+
1051+void TransactionLogApplier::apply(const message::Transaction &to_apply)
1052+{
1053+ uint8_t *buffer; /* Buffer we will write serialized header,
1054+ message and trailing checksum to */
1055+ uint8_t *orig_buffer;
1056+
1057+ size_t message_byte_length= to_apply.ByteSize();
1058+ size_t total_envelope_length= TransactionLog::HEADER_TRAILER_BYTES + message_byte_length;
1059+
1060+ /*
1061+ * Attempt allocation of raw memory buffer for the header,
1062+ * message and trailing checksum bytes.
1063+ */
1064+ buffer= static_cast<uint8_t *>(malloc(total_envelope_length));
1065+ if (buffer == NULL)
1066+ {
1067+ errmsg_printf(ERRMSG_LVL_ERROR,
1068+ _("Failed to allocate enough memory to buffer header, "
1069+ "transaction message, and trailing checksum bytes. Tried to allocate %" PRId64
1070+ " bytes. Error: %s\n"),
1071+ static_cast<int64_t>(total_envelope_length),
1072+ strerror(errno));
1073+ return;
1074+ }
1075+ else
1076+ orig_buffer= buffer; /* We will free() orig_buffer, as buffer is moved during write */
1077+
1078+ /*
1079+ * Write the header information, which is the message type and
1080+ * the length of the transaction message into the buffer
1081+ */
1082+ buffer= protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray(
1083+ static_cast<uint32_t>(ReplicationServices::TRANSACTION), buffer);
1084+ buffer= protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray(
1085+ static_cast<uint32_t>(message_byte_length), buffer);
1086+
1087+ /*
1088+ * Now write the serialized transaction message, followed
1089+ * by the optional checksum into the buffer.
1090+ */
1091+ buffer= to_apply.SerializeWithCachedSizesToArray(buffer);
1092+
1093+ uint32_t checksum= 0;
1094+ if (do_checksum)
1095+ {
1096+ checksum= drizzled::algorithm::crc32(
1097+ reinterpret_cast<char *>(buffer) - message_byte_length, message_byte_length);
1098+ }
1099+
1100+ /* We always write in network byte order */
1101+ buffer= protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray(checksum, buffer);
1102+
1103+ /* Ask the transaction log to write the entry and return where it wrote it */
1104+ off_t written_to= transaction_log.writeEntry(orig_buffer, total_envelope_length);
1105+
1106+ free(orig_buffer);
1107+
1108+ /* Add an entry to the index describing what was just applied */
1109+ transaction_log_index->addEntry(TransactionLogEntry(ReplicationServices::TRANSACTION,
1110+ written_to,
1111+ total_envelope_length),
1112+ to_apply,
1113+ checksum);
1114+
1115+}
1116
1117=== added file 'plugin/transaction_log/transaction_log_applier.h'
1118--- plugin/transaction_log/transaction_log_applier.h 1970-01-01 00:00:00 +0000
1119+++ plugin/transaction_log/transaction_log_applier.h 2010-03-05 19:18:29 +0000
1120@@ -0,0 +1,83 @@
1121+/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
1122+ * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
1123+ *
1124+ * Copyright (C) 2008-2009 Sun Microsystems
1125+ * Copyright (c) 2010 Jay Pipes <jaypipes@gmail.com>
1126+ *
1127+ * Authors:
1128+ *
1129+ * Jay Pipes <jaypipes@gmail.com.com>
1130+ *
1131+ * This program is free software; you can redistribute it and/or modify
1132+ * it under the terms of the GNU General Public License as published by
1133+ * the Free Software Foundation; either version 2 of the License, or
1134+ * (at your option) any later version.
1135+ *
1136+ * This program is distributed in the hope that it will be useful,
1137+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1138+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1139+ * GNU General Public License for more details.
1140+ *
1141+ * You should have received a copy of the GNU General Public License
1142+ * along with this program; if not, write to the Free Software
1143+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1144+ */
1145+
1146+/**
1147+ * @file
1148+ *
1149+ * Defines the API of the transaction log applier.
1150+ *
1151+ * @see drizzled/plugin/replicator.h
1152+ * @see drizzled/plugin/applier.h
1153+ */
1154+
1155+#ifndef PLUGIN_TRANSACTION_LOG_TRANSACTION_LOG_APPLIER_H
1156+#define PLUGIN_TRANSACTION_LOG_TRANSACTION_LOG_APPLIER_H
1157+
1158+#include <drizzled/replication_services.h>
1159+#include <drizzled/plugin/transaction_applier.h>
1160+
1161+#include "transaction_log_entry.h"
1162+
1163+#include <vector>
1164+#include <string>
1165+
1166+class TransactionLog;
1167+
1168+class TransactionLogApplier: public drizzled::plugin::TransactionApplier
1169+{
1170+public:
1171+ TransactionLogApplier(const std::string name_arg,
1172+ TransactionLog &in_transaction_log,
1173+ bool in_do_checksum);
1174+
1175+ /** Destructor */
1176+ ~TransactionLogApplier();
1177+
1178+ /**
1179+ * Applies a Transaction to the serial log
1180+ *
1181+ * @note
1182+ *
1183+ * It is important to note that memory allocation for the
1184+ * supplied pointer is not guaranteed after the completion
1185+ * of this function -- meaning the caller can dispose of the
1186+ * supplied message. Therefore, appliers which are
1187+ * implementing an asynchronous replication system must copy
1188+ * the supplied message to their own controlled memory storage
1189+ * area.
1190+ *
1191+ * @param Transaction message to be replicated
1192+ */
1193+ void apply(const drizzled::message::Transaction &to_apply);
1194+private:
1195+ /* Don't allows these */
1196+ TransactionLogApplier();
1197+ TransactionLogApplier(const TransactionLogApplier &other);
1198+ TransactionLogApplier &operator=(const TransactionLogApplier &other);
1199+ TransactionLog &transaction_log;
1200+ bool do_checksum; ///< Do a CRC32 checksum when writing Transaction message to log?
1201+};
1202+
1203+#endif /* PLUGIN_TRANSACTION_LOG_TRANSACTION_LOG_APPLIER_H */
1204
1205=== modified file 'plugin/transaction_log/transaction_log_index.cc'
1206--- plugin/transaction_log/transaction_log_index.cc 2010-03-05 04:44:58 +0000
1207+++ plugin/transaction_log/transaction_log_index.cc 2010-03-05 19:18:29 +0000
1208@@ -42,7 +42,6 @@
1209
1210 TransactionLogIndex::TransactionLogIndex(TransactionLog &in_log) :
1211 log(in_log),
1212- log_file(-1),
1213 index_file(-1),
1214 index_file_path(),
1215 has_error(false),
1216
1217=== modified file 'plugin/transaction_log/transaction_log_index.h'
1218--- plugin/transaction_log/transaction_log_index.h 2010-03-05 04:44:58 +0000
1219+++ plugin/transaction_log/transaction_log_index.h 2010-03-05 19:18:29 +0000
1220@@ -131,7 +131,6 @@
1221 void clearError();
1222
1223 TransactionLog &log; ///< The transaction log instance
1224- int log_file; ///< File descriptor for the transaction log file
1225 int index_file; ///< File descriptor for the transaction log on-disk index file
1226 const std::string index_file_path; ///< Filename of the on-disk transaction log index
1227 bool has_error; ///< Index is in error mode?
1228
1229=== modified file 'plugin/transaction_log/transaction_log_reader.cc'
1230--- plugin/transaction_log/transaction_log_reader.cc 2010-01-06 02:20:42 +0000
1231+++ plugin/transaction_log/transaction_log_reader.cc 2010-03-05 19:18:29 +0000
1232@@ -49,6 +49,7 @@
1233 #include <cerrno>
1234
1235 #include "transaction_log_reader.h"
1236+#include "transaction_log.h"
1237
1238 #include <drizzled/gettext.h>
1239 #include <drizzled/message/transaction.pb.h>
1240
1241=== modified file 'plugin/transaction_log/transaction_log_reader.h'
1242--- plugin/transaction_log/transaction_log_reader.h 2009-10-20 03:04:07 +0000
1243+++ plugin/transaction_log/transaction_log_reader.h 2010-03-05 19:18:29 +0000
1244@@ -38,10 +38,10 @@
1245 #ifndef PLUGIN_TRANSACTION_LOG_TRANSACTION_LOG_READER_H
1246 #define PLUGIN_TRANSACTION_LOG_TRANSACTION_LOG_READER_H
1247
1248-#include "transaction_log.h"
1249-
1250 #include <drizzled/plugin/transaction_reader.h>
1251
1252+class TransactionLog;
1253+
1254 /**
1255 * A class which reads Transaction messages from the Transaction log file
1256 */