40
40
#include "hexdump_transaction_message.h"
41
41
#include "background_worker.h"
43
45
#include <drizzled/plugin/plugin.h>
44
46
#include <drizzled/session.h>
45
#include <drizzled/set_var.h>
46
47
#include <drizzled/gettext.h>
48
#include <boost/program_options.hpp>
49
#include <drizzled/module/option_map.h>
51
namespace po= boost::program_options;
48
52
using namespace std;
49
53
using namespace drizzled;
56
* The name of the main transaction log file on disk. With no prefix,
57
* this goes into Drizzle's $datadir.
59
static const char DEFAULT_LOG_FILE_PATH[]= "transaction.log"; /* In datadir... */
52
61
* Transaction Log plugin system variable - Is the log enabled? Only used on init().
53
* The enable() and disable() methods of the TransactionLog class control online
56
63
static bool sysvar_transaction_log_enabled= false;
57
65
/** Transaction Log plugin system variable - The path to the log file used */
58
static char* sysvar_transaction_log_file= NULL;
66
static char* sysvar_transaction_log_file= (char *)DEFAULT_LOG_FILE_PATH;
60
69
* Transaction Log plugin system variable - A debugging variable to assist
61
70
* in truncating the log file.
63
72
static bool sysvar_transaction_log_truncate_debug= false;
64
static const char DEFAULT_LOG_FILE_PATH[]= "transaction.log"; /* In datadir... */
66
74
* Transaction Log plugin system variable - Should we write a CRC32 checksum for
67
75
* each written Transaction message?
71
79
* Numeric option controlling the sync/flush behaviour of the transaction
72
80
* log. Options are:
74
* TransactionLog::SYNC_METHOD_OS == 0 ... let OS do sync'ing
75
* TransactionLog::SYNC_METHOD_EVERY_WRITE == 1 ... sync on every write
76
* TransactionLog::SYNC_METHOD_EVERY_SECOND == 2 ... sync at most once a second
78
static uint32_t sysvar_transaction_log_sync_method= 0;
82
* TransactionLog::FLUSH_FREQUENCY_OS == 0 ... let OS do sync'ing
83
* TransactionLog::FLUSH_FREQUENCY_EVERY_WRITE == 1 ... sync on every write
84
* TransactionLog::FLUSH_FREQUENCY_EVERY_SECOND == 2 ... sync at most once a second
86
static uint32_t sysvar_transaction_log_flush_frequency= 0;
88
* Transaction Log plugin system variable - Number of slots to create
89
* for managing write buffers
91
static uint32_t sysvar_transaction_log_num_write_buffers= 8;
93
* Transaction Log plugin system variable - The name of the replicator plugin
94
* to pair the transaction log's applier with. Defaults to "default"
96
static const char DEFAULT_USE_REPLICATOR[]= "default";
97
static char *sysvar_transaction_log_use_replicator= (char *)DEFAULT_USE_REPLICATOR;
80
99
/** DATA_DICTIONARY views */
81
100
static TransactionLogTool *transaction_log_tool;
93
112
extern plugin::Create_function<PrintTransactionMessageFunction> *print_transaction_message_func_factory;
94
113
extern plugin::Create_function<HexdumpTransactionMessageFunction> *hexdump_transaction_message_func_factory;
96
static int init(drizzled::plugin::Context &context)
115
TransactionLog::~TransactionLog()
117
/* Clear up any resources we've consumed */
120
(void) close(log_file);
123
/* These get strdup'd below */
124
free(sysvar_transaction_log_file);
125
free(sysvar_transaction_log_use_replicator);
128
static int init(drizzled::module::Context &context)
130
const module::option_map &vm= context.getOptions();
132
if (vm.count("flush-frequency"))
134
if (sysvar_transaction_log_flush_frequency > 2)
136
errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for sync-method\n"));
141
if (vm.count("num-write-buffers"))
143
if (sysvar_transaction_log_num_write_buffers < 4 || sysvar_transaction_log_num_write_buffers > 8192)
145
errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for num-write-buffers\n"));
98
151
/* Create and initialize the transaction log itself */
99
152
if (sysvar_transaction_log_enabled)
154
if (vm.count("file"))
156
sysvar_transaction_log_file= strdup(vm["file"].as<string>().c_str());
160
sysvar_transaction_log_file= strdup(DEFAULT_LOG_FILE_PATH);
163
if (vm.count("use-replicator"))
165
sysvar_transaction_log_use_replicator= strdup(vm["use-replicator"].as<string>().c_str());
169
sysvar_transaction_log_use_replicator= strdup(DEFAULT_USE_REPLICATOR);
101
171
transaction_log= new (nothrow) TransactionLog(string(sysvar_transaction_log_file),
102
sysvar_transaction_log_sync_method);
172
sysvar_transaction_log_flush_frequency,
173
sysvar_transaction_log_checksum_enabled);
104
175
if (transaction_log == NULL)
177
char errmsg[STRERROR_MAX];
178
strerror_r(errno, errmsg, sizeof(errmsg));
106
179
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the TransactionLog instance. Got error: %s\n"),
194
/* Create and initialize the transaction log index */
195
transaction_log_index= new (nothrow) TransactionLogIndex(*transaction_log);
196
if (transaction_log_index == NULL)
198
char errmsg[STRERROR_MAX];
199
strerror_r(errno, errmsg, sizeof(errmsg));
200
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the TransactionLogIndex instance. Got error: %s\n"),
206
/* Check to see if the index was not created properly */
207
if (transaction_log_index->hasError())
209
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize the Transaction Log Index. Got error: %s\n"),
210
transaction_log_index->getErrorMessage().c_str());
120
215
/* Create the applier plugin and register it */
121
216
transaction_log_applier= new (nothrow) TransactionLogApplier("transaction_log_applier",
123
sysvar_transaction_log_checksum_enabled);
218
transaction_log_index,
219
sysvar_transaction_log_num_write_buffers);
124
220
if (transaction_log_applier == NULL)
222
char errmsg[STRERROR_MAX];
223
strerror_r(errno, errmsg, sizeof(errmsg));
126
224
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the TransactionLogApplier instance. Got error: %s\n"),
130
228
context.add(transaction_log_applier);
229
ReplicationServices &replication_services= ReplicationServices::singleton();
230
string replicator_name(sysvar_transaction_log_use_replicator);
231
replication_services.attachApplier(transaction_log_applier, replicator_name);
132
233
/* Setup DATA_DICTIONARY views */
147
248
new plugin::Create_function<HexdumpTransactionMessageFunction>("hexdump_transaction_message");
148
249
context.add(hexdump_transaction_message_func_factory);
150
/* Create and initialize the transaction log index */
151
transaction_log_index= new (nothrow) TransactionLogIndex(*transaction_log);
152
if (transaction_log_index == NULL)
154
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the TransactionLogIndex instance. Got error: %s\n"),
160
/* Check to see if the index was not created properly */
161
if (transaction_log_index->hasError())
163
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize the Transaction Log Index. Got error: %s\n"),
164
transaction_log_index->getErrorMessage().c_str());
170
252
* Setup the background worker thread which maintains
171
253
* summary information about the transaction log.
199
281
static DRIZZLE_SYSVAR_BOOL(enable,
200
282
sysvar_transaction_log_enabled,
283
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
202
284
N_("Enable transaction log"),
203
285
NULL, /* check func */
204
286
NULL, /* update func */
212
294
set_truncate_debug, /* update func */
213
295
false /* default */);
215
static DRIZZLE_SYSVAR_STR(log_file,
297
static DRIZZLE_SYSVAR_STR(file,
216
298
sysvar_transaction_log_file,
217
299
PLUGIN_VAR_READONLY,
218
300
N_("Path to the file to use for transaction log"),
220
302
NULL, /* update func*/
221
303
DEFAULT_LOG_FILE_PATH /* default */);
305
static DRIZZLE_SYSVAR_STR(use_replicator,
306
sysvar_transaction_log_use_replicator,
308
N_("Name of the replicator plugin to use (default='default_replicator')"),
309
NULL, /* check func */
310
NULL, /* update func*/
311
DEFAULT_USE_REPLICATOR /* default */);
223
313
static DRIZZLE_SYSVAR_BOOL(enable_checksum,
224
314
sysvar_transaction_log_checksum_enabled,
225
315
PLUGIN_VAR_NOCMDARG,
228
318
NULL, /* update func */
229
319
false /* default */);
231
static DRIZZLE_SYSVAR_UINT(sync_method,
232
sysvar_transaction_log_sync_method,
321
static DRIZZLE_SYSVAR_UINT(flush_frequency,
322
sysvar_transaction_log_flush_frequency,
233
323
PLUGIN_VAR_OPCMDARG,
234
324
N_("0 == rely on operating system to sync log file (default), "
235
325
"1 == sync file at each transaction write, "
334
static DRIZZLE_SYSVAR_UINT(num_write_buffers,
335
sysvar_transaction_log_num_write_buffers,
337
N_("Number of slots for in-memory write buffers (default=8)."),
338
NULL, /* check func */
339
NULL, /* update func */
345
static void init_options(drizzled::module::option_context &context)
347
context("truncate-debug",
348
po::value<bool>(&sysvar_transaction_log_truncate_debug)->default_value(false)->zero_tokens(),
349
N_("DEBUGGING - Truncate transaction log"));
350
context("enable-checksum",
351
po::value<bool>(&sysvar_transaction_log_checksum_enabled)->default_value(false)->zero_tokens(),
352
N_("Enable CRC32 Checksumming of each written transaction log entry"));
354
po::value<bool>(&sysvar_transaction_log_enabled)->default_value(false)->zero_tokens(),
355
N_("Enable transaction log"));
358
N_("Path to the file to use for transaction log"));
359
context("use-replicator",
361
N_("Name of the replicator plugin to use (default='default_replicator')"));
362
context("flush-frequency",
363
po::value<uint32_t>(&sysvar_transaction_log_flush_frequency)->default_value(0),
364
N_("0 == rely on operating system to sync log file (default), 1 == sync file at each transaction write, 2 == sync log file once per second"));
365
context("num-write-buffers",
366
po::value<uint32_t>(&sysvar_transaction_log_num_write_buffers)->default_value(8),
367
N_("Number of slots for in-memory write buffers (default=8)."));
244
370
static drizzle_sys_var* sys_variables[]= {
245
371
DRIZZLE_SYSVAR(enable),
246
372
DRIZZLE_SYSVAR(truncate_debug),
247
DRIZZLE_SYSVAR(log_file),
373
DRIZZLE_SYSVAR(file),
248
374
DRIZZLE_SYSVAR(enable_checksum),
249
DRIZZLE_SYSVAR(sync_method),
375
DRIZZLE_SYSVAR(flush_frequency),
376
DRIZZLE_SYSVAR(num_write_buffers),
377
DRIZZLE_SYSVAR(use_replicator),
253
DRIZZLE_PLUGIN(init, sys_variables);
381
DRIZZLE_PLUGIN(init, sys_variables, init_options);