1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008-2009 Sun Microsystems, Inc.
5
* Copyright (C) 2010 Jay Pipes <jaypipes@gmail.com>
9
* Jay Pipes <jaypipes@gmail.com.com>
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; either version 2 of the License, or
14
* (at your option) any later version.
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
21
* You should have received a copy of the GNU General Public License
22
* along with this program; if not, write to the Free Software
23
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29
* Transaction log module initialization and plugin
35
#include "transaction_log.h"
36
#include "transaction_log_applier.h"
37
#include "transaction_log_index.h"
38
#include "data_dictionary_schema.h"
39
#include "print_transaction_message.h"
40
#include "hexdump_transaction_message.h"
44
#include <drizzled/plugin/plugin.h>
45
#include <drizzled/session.h>
46
#include <drizzled/gettext.h>
47
#include <boost/program_options.hpp>
48
#include <drizzled/module/option_map.h>
50
namespace po= boost::program_options;
52
using namespace drizzled;
55
* The name of the main transaction log file on disk. With no prefix,
56
* this goes into Drizzle's $datadir.
58
static const char DEFAULT_LOG_FILE_PATH[]= "transaction.log"; /* In datadir... */
60
* Transaction Log plugin system variable - Is the log enabled? Only used on init().
62
static bool sysvar_transaction_log_enabled= false;
64
/** Transaction Log plugin system variable - The path to the log file used */
65
static string sysvar_transaction_log_file;
68
* Transaction Log plugin system variable - A debugging variable to assist
69
* in truncating the log file.
71
static bool sysvar_transaction_log_truncate_debug= false;
73
* Transaction Log plugin system variable - Should we write a CRC32 checksum for
74
* each written Transaction message?
76
static bool sysvar_transaction_log_checksum_enabled= false;
78
* Numeric option controlling the sync/flush behaviour of the transaction
81
* TransactionLog::FLUSH_FREQUENCY_OS == 0 ... let OS do sync'ing
82
* TransactionLog::FLUSH_FREQUENCY_EVERY_WRITE == 1 ... sync on every write
83
* TransactionLog::FLUSH_FREQUENCY_EVERY_SECOND == 2 ... sync at most once a second
85
typedef constrained_check<uint32_t, 2, 0> flush_constraint;
86
static flush_constraint sysvar_transaction_log_flush_frequency;
88
* Transaction Log plugin system variable - Number of slots to create
89
* for managing write buffers
91
typedef constrained_check<uint32_t, 8192, 4> write_buffers_constraint;
92
static write_buffers_constraint sysvar_transaction_log_num_write_buffers;
94
* Transaction Log plugin system variable - The name of the replicator plugin
95
* to pair the transaction log's applier with. Defaults to "default"
97
static const char DEFAULT_USE_REPLICATOR[]= "default";
98
static string sysvar_transaction_log_use_replicator;
100
/** DATA_DICTIONARY views */
101
static TransactionLogTool *transaction_log_tool;
102
static TransactionLogEntriesTool *transaction_log_entries_tool;
103
static TransactionLogTransactionsTool *transaction_log_transactions_tool;
105
/** Index defined in transaction_log_index.cc */
106
extern TransactionLogIndex *transaction_log_index;
107
/** Transaction Log descriptor defined in transaction_log.cc */
108
extern TransactionLog *transaction_log;
109
/** Transaction Log descriptor defined in transaction_log.cc */
110
extern TransactionLogApplier *transaction_log_applier;
112
/** Defined in print_transaction_message.cc */
113
extern plugin::Create_function<PrintTransactionMessageFunction> *print_transaction_message_func_factory;
114
extern plugin::Create_function<HexdumpTransactionMessageFunction> *hexdump_transaction_message_func_factory;
116
TransactionLog::~TransactionLog()
118
/* Clear up any resources we've consumed */
121
(void) close(log_file);
125
static void set_truncate_debug(Session *, sql_var_t)
129
if (sysvar_transaction_log_truncate_debug)
131
transaction_log->truncate();
132
transaction_log_index->clear();
133
sysvar_transaction_log_truncate_debug= false;
138
static int init(drizzled::module::Context &context)
140
context.registerVariable(new sys_var_bool_ptr_readonly("enable",
141
&sysvar_transaction_log_enabled));
142
context.registerVariable(new sys_var_bool_ptr("truncate-debug",
143
&sysvar_transaction_log_truncate_debug,
144
set_truncate_debug));
146
context.registerVariable(new sys_var_const_string("file",
147
sysvar_transaction_log_file));
148
context.registerVariable(new sys_var_const_string("use-replicator",
149
sysvar_transaction_log_use_replicator));
150
context.registerVariable(new sys_var_bool_ptr_readonly("enable-checksum",
151
&sysvar_transaction_log_checksum_enabled));
152
context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("flush-frequency", sysvar_transaction_log_flush_frequency));
154
context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("num-write-buffers",
155
sysvar_transaction_log_num_write_buffers));
158
/* Create and initialize the transaction log itself */
159
if (sysvar_transaction_log_enabled)
162
transaction_log= new (nothrow) TransactionLog(sysvar_transaction_log_file,
163
static_cast<int>(sysvar_transaction_log_flush_frequency),
164
sysvar_transaction_log_checksum_enabled);
166
if (transaction_log == NULL)
168
sql_perror(_("Failed to allocate the TransactionLog instance"), sysvar_transaction_log_file);
173
/* Check to see if the log was not created properly */
174
if (transaction_log->hasError())
176
errmsg_printf(error::ERROR, _("Failed to initialize the Transaction Log. Got error: %s\n"),
177
transaction_log->getErrorMessage().c_str());
182
/* Create and initialize the transaction log index */
183
transaction_log_index= new (nothrow) TransactionLogIndex(*transaction_log);
184
if (transaction_log_index == NULL)
186
sql_perror(_("Failed to allocate the TransactionLogIndex instance"), sysvar_transaction_log_file);
191
/* Check to see if the index was not created properly */
192
if (transaction_log_index->hasError())
194
errmsg_printf(error::ERROR, _("Failed to initialize the Transaction Log Index. Got error: %s\n"),
195
transaction_log_index->getErrorMessage().c_str());
200
/* Create the applier plugin and register it */
201
transaction_log_applier= new (nothrow) TransactionLogApplier("transaction_log_applier",
203
transaction_log_index,
204
static_cast<uint32_t>(sysvar_transaction_log_num_write_buffers));
205
if (transaction_log_applier == NULL)
207
sql_perror(_("Failed to allocate the TransactionLogApplier instance"), sysvar_transaction_log_file);
210
context.add(transaction_log_applier);
211
ReplicationServices &replication_services= ReplicationServices::singleton();
212
replication_services.attachApplier(transaction_log_applier,
213
sysvar_transaction_log_use_replicator);
215
/* Setup DATA_DICTIONARY views */
217
transaction_log_tool= new (nothrow) TransactionLogTool;
218
context.add(transaction_log_tool);
219
transaction_log_entries_tool= new (nothrow) TransactionLogEntriesTool;
220
context.add(transaction_log_entries_tool);
221
transaction_log_transactions_tool= new (nothrow) TransactionLogTransactionsTool;
222
context.add(transaction_log_transactions_tool);
224
/* Setup the module's UDFs */
225
print_transaction_message_func_factory=
226
new plugin::Create_function<PrintTransactionMessageFunction>("print_transaction_message");
227
context.add(print_transaction_message_func_factory);
229
hexdump_transaction_message_func_factory=
230
new plugin::Create_function<HexdumpTransactionMessageFunction>("hexdump_transaction_message");
231
context.add(hexdump_transaction_message_func_factory);
237
static void init_options(drizzled::module::option_context &context)
239
context("truncate-debug",
240
po::value<bool>(&sysvar_transaction_log_truncate_debug)->default_value(false)->zero_tokens(),
241
_("DEBUGGING - Truncate transaction log"));
242
context("enable-checksum",
243
po::value<bool>(&sysvar_transaction_log_checksum_enabled)->default_value(false)->zero_tokens(),
244
_("Enable CRC32 Checksumming of each written transaction log entry"));
246
po::value<bool>(&sysvar_transaction_log_enabled)->default_value(false)->zero_tokens(),
247
_("Enable transaction log"));
249
po::value<string>(&sysvar_transaction_log_file)->default_value(DEFAULT_LOG_FILE_PATH),
250
_("Path to the file to use for transaction log"));
251
context("use-replicator",
252
po::value<string>(&sysvar_transaction_log_use_replicator)->default_value(DEFAULT_USE_REPLICATOR),
253
_("Name of the replicator plugin to use (default='default_replicator')"));
254
context("flush-frequency",
255
po::value<flush_constraint>(&sysvar_transaction_log_flush_frequency)->default_value(0),
256
_("0 == rely on operating system to sync log file (default), 1 == sync file at each transaction write, 2 == sync log file once per second"));
257
context("num-write-buffers",
258
po::value<write_buffers_constraint>(&sysvar_transaction_log_num_write_buffers)->default_value(8),
259
_("Number of slots for in-memory write buffers (default=8)."));
262
DRIZZLE_PLUGIN(init, NULL, init_options);