63
63
* Possibly look at a scoreboard approach with multiple file segments. For
64
64
* right now, though, this is just a quick simple implementation to serve
65
65
* as a skeleton and a springboard.
69
* Move the Applier piece of this code out into its own source file and leave
70
* this for all the glue code of the module.
68
73
#include <drizzled/server_includes.h>
69
74
#include "transaction_log.h"
75
#include "transaction_log_index.h"
76
#include "info_schema.h"
77
#include "print_transaction_message.h"
78
#include "hexdump_transaction_message.h"
79
#include "background_worker.h"
71
81
#include <unistd.h>
107
117
static bool sysvar_transaction_log_checksum_enabled= false;
119
/** Views defined in info_schema.cc */
120
extern plugin::InfoSchemaTable *transaction_log_view;
121
extern plugin::InfoSchemaTable *transaction_log_entries_view;
122
extern plugin::InfoSchemaTable *transaction_log_transactions_view;
124
/** Index defined in transaction_log_index.cc */
125
extern TransactionLogIndex *transaction_log_index;
127
/** Defined in print_transaction_message.cc */
128
extern plugin::Create_function<PrintTransactionMessageFunction> *print_transaction_message_func_factory;
129
extern plugin::Create_function<HexdumpTransactionMessageFunction> *hexdump_transaction_message_func_factory;
109
131
TransactionLog::TransactionLog(string name_arg,
110
const char *in_log_file_path,
132
const string &in_log_file_path,
111
133
bool in_do_checksum)
112
134
: plugin::TransactionApplier(name_arg),
114
log_file_path(in_log_file_path)
136
log_file_path(in_log_file_path),
116
140
do_checksum= in_do_checksum; /* Have to do here, not in initialization list b/c atomic<> */
118
142
/* Setup our log file and determine the next write offset... */
119
log_file= open(log_file_path, O_APPEND|O_CREAT|O_SYNC|O_WRONLY, S_IRWXU);
143
log_file= open(log_file_path.c_str(), O_APPEND|O_CREAT|O_SYNC|O_WRONLY, S_IRWXU);
120
144
if (log_file == -1)
122
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to open transaction log file %s. Got error: %s\n"),
146
error_message.assign(_("Failed to open transaction log file "));
147
error_message.append(log_file_path);
148
error_message.append(" Got error: ");
149
error_message.append(strerror(errno));
150
error_message.push_back('\n');
156
/* For convenience, grab the log file name from the path */
157
if (log_file_path.find_first_of('/') != string::npos)
159
/* Strip to last / */
161
tmp= log_file_path.substr(log_file_path.find_last_of('/') + 1);
162
log_file_name.assign(tmp);
165
log_file_name.assign(log_file_path);
130
168
* The offset of the next write is the current position of the log
131
169
* file, since it's opened in append mode...
302
static TransactionLog *transaction_log= NULL; /* The singleton transaction log */
356
bool TransactionLog::hasError() const
361
void TransactionLog::clearError()
364
error_message.clear();
367
const std::string &TransactionLog::getErrorMessage() const
369
return error_message;
372
TransactionLog *transaction_log= NULL; /* The singleton transaction log */
304
374
static int init(drizzled::plugin::Registry ®istry)
376
/* Create and initialize the transaction log itself */
306
377
if (sysvar_transaction_log_enabled)
308
transaction_log= new TransactionLog("transaction_log",
309
sysvar_transaction_log_file,
310
sysvar_transaction_log_checksum_enabled);
379
transaction_log= new (nothrow) TransactionLog("transaction_log_applier",
380
string(sysvar_transaction_log_file),
381
sysvar_transaction_log_checksum_enabled);
383
if (transaction_log == NULL)
385
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the TransactionLog instance. Got error: %s\n"),
391
/* Check to see if the log was not created properly */
392
if (transaction_log->hasError())
394
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize the Transaction Log. Got error: %s\n"),
395
transaction_log->getErrorMessage().c_str());
311
399
registry.add(transaction_log);
401
/* Setup the INFORMATION_SCHEMA views for the transaction log */
402
if (initViewMethods() ||
405
return 1; /* Error message output handled in functions above */
407
registry.add(transaction_log_view);
408
registry.add(transaction_log_entries_view);
409
registry.add(transaction_log_transactions_view);
411
/* Setup the module's UDFs */
412
print_transaction_message_func_factory=
413
new plugin::Create_function<PrintTransactionMessageFunction>("print_transaction_message");
414
registry.add(print_transaction_message_func_factory);
416
hexdump_transaction_message_func_factory=
417
new plugin::Create_function<HexdumpTransactionMessageFunction>("hexdump_transaction_message");
418
registry.add(hexdump_transaction_message_func_factory);
420
/* Create and initialize the transaction log index */
421
transaction_log_index= new (nothrow) TransactionLogIndex(*transaction_log);
422
if (transaction_log_index == NULL)
424
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the TransactionLogIndex instance. Got error: %s\n"),
430
/* Check to see if the index was not created properly */
431
if (transaction_log_index->hasError())
433
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize the Transaction Log Index. Got error: %s\n"),
434
transaction_log_index->getErrorMessage().c_str());
440
* Setup the background worker thread which maintains
441
* summary information about the transaction log.
443
if (initTransactionLogBackgroundWorker())
444
return 1; /* Error message output handled in function above */
316
449
static int deinit(drizzled::plugin::Registry ®istry)
451
/* Cleanup the transaction log itself */
318
452
if (transaction_log)
320
454
registry.remove(transaction_log);
321
455
delete transaction_log;
456
delete transaction_log_index;
458
/* Cleanup the INFORMATION_SCHEMA views */
459
registry.remove(transaction_log_view);
460
registry.remove(transaction_log_entries_view);
461
registry.remove(transaction_log_transactions_view);
463
cleanupViewMethods();
464
cleanupViewColumns();
467
/* Cleanup module UDFs */
468
registry.remove(print_transaction_message_func_factory);
469
delete print_transaction_message_func_factory;
470
registry.remove(hexdump_transaction_message_func_factory);
471
delete hexdump_transaction_message_func_factory;