Drizzled Public API Documentation

module.cc

Go to the documentation of this file.
00001 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008-2009 Sun Microsystems, Inc.
00005  *  Copyright (C) 2010 Jay Pipes <jaypipes@gmail.com>
00006  *
00007  *  Authors:
00008  *
00009  *  Jay Pipes <jaypipes@gmail.com.com>
00010  *
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License
00022  *  along with this program; if not, write to the Free Software
00023  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00024  */
00025 
00033 #include <config.h>
00034 
00035 #include "transaction_log.h"
00036 #include "transaction_log_applier.h"
00037 #include "transaction_log_index.h"
00038 #include "data_dictionary_schema.h"
00039 #include "print_transaction_message.h"
00040 #include "hexdump_transaction_message.h"
00041 
00042 #include <errno.h>
00043 
00044 #include <drizzled/plugin/plugin.h>
00045 #include <drizzled/session.h>
00046 #include <drizzled/gettext.h>
00047 #include <boost/program_options.hpp>
00048 #include <drizzled/module/option_map.h>
00049 #include <drizzled/plugin/function.h>
00050 
00051 namespace po= boost::program_options;
00052 using namespace std;
00053 using namespace drizzled;
00054 
00059 static const char DEFAULT_LOG_FILE_PATH[]= "transaction.log"; /* In datadir... */
00063 static bool sysvar_transaction_log_enabled= false;
00064 
00066 static string sysvar_transaction_log_file;
00067 
00072 static bool sysvar_transaction_log_truncate_debug= false;
00077 static bool sysvar_transaction_log_checksum_enabled= false;
00086 typedef constrained_check<uint32_t, 2, 0> flush_constraint;
00087 static flush_constraint sysvar_transaction_log_flush_frequency;
00092 typedef constrained_check<uint32_t, 8192, 4> write_buffers_constraint;
00093 static write_buffers_constraint sysvar_transaction_log_num_write_buffers;
00098 static const char DEFAULT_USE_REPLICATOR[]= "default";
00099 static string sysvar_transaction_log_use_replicator;
00100 
00102 static TransactionLogTool *transaction_log_tool;
00103 static TransactionLogEntriesTool *transaction_log_entries_tool;
00104 static TransactionLogTransactionsTool *transaction_log_transactions_tool;
00105 
00107 extern TransactionLogIndex *transaction_log_index;
00109 extern TransactionLog *transaction_log;
00111 extern TransactionLogApplier *transaction_log_applier;
00112 
00114 extern plugin::Create_function<PrintTransactionMessageFunction> *print_transaction_message_func_factory;
00115 extern plugin::Create_function<HexdumpTransactionMessageFunction> *hexdump_transaction_message_func_factory;
00116 
00117 TransactionLog::~TransactionLog()
00118 {
00119   /* Clear up any resources we've consumed */
00120   if (log_file != -1)
00121   {
00122     (void) close(log_file);
00123   }
00124 }
00125 
00126 static void set_truncate_debug(Session *, sql_var_t)
00127 {
00128   if (transaction_log)
00129   {
00130     if (sysvar_transaction_log_truncate_debug)
00131     {
00132       transaction_log->truncate();
00133       transaction_log_index->clear();
00134       sysvar_transaction_log_truncate_debug= false;
00135     }
00136   }
00137 }
00138 
00139 static int init(drizzled::module::Context &context)
00140 {
00141   context.registerVariable(new sys_var_bool_ptr_readonly("enable",
00142                                                          &sysvar_transaction_log_enabled));
00143   context.registerVariable(new sys_var_bool_ptr("truncate-debug",
00144                                                 &sysvar_transaction_log_truncate_debug,
00145                                                 set_truncate_debug));
00146 
00147   context.registerVariable(new sys_var_const_string("file",
00148                                                     sysvar_transaction_log_file));
00149   context.registerVariable(new sys_var_const_string("use-replicator",
00150                                                     sysvar_transaction_log_use_replicator));
00151   context.registerVariable(new sys_var_bool_ptr_readonly("enable-checksum",
00152                                                          &sysvar_transaction_log_checksum_enabled));
00153   context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("flush-frequency", sysvar_transaction_log_flush_frequency));
00154 
00155   context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("num-write-buffers",
00156                                                                             sysvar_transaction_log_num_write_buffers));
00157 
00158 
00159   /* Create and initialize the transaction log itself */
00160   if (sysvar_transaction_log_enabled)
00161   {
00162   
00163     transaction_log= new (nothrow) TransactionLog(sysvar_transaction_log_file,
00164                                                   static_cast<int>(sysvar_transaction_log_flush_frequency),
00165                                                   sysvar_transaction_log_checksum_enabled);
00166 
00167     if (transaction_log == NULL)
00168     {
00169       sql_perror(_("Failed to allocate the TransactionLog instance"), sysvar_transaction_log_file);
00170       return 1;
00171     }
00172     else
00173     {
00174       /* Check to see if the log was not created properly */
00175       if (transaction_log->hasError())
00176       {
00177         errmsg_printf(error::ERROR, _("Failed to initialize the Transaction Log.  Got error: %s\n"), 
00178                       transaction_log->getErrorMessage().c_str());
00179         return 1;
00180       }
00181     }
00182 
00183     /* Create and initialize the transaction log index */
00184     transaction_log_index= new (nothrow) TransactionLogIndex(*transaction_log);
00185     if (transaction_log_index == NULL)
00186     {
00187       sql_perror(_("Failed to allocate the TransactionLogIndex instance"), sysvar_transaction_log_file);
00188       return 1;
00189     }
00190     else
00191     {
00192       /* Check to see if the index was not created properly */
00193       if (transaction_log_index->hasError())
00194       {
00195         errmsg_printf(error::ERROR, _("Failed to initialize the Transaction Log Index.  Got error: %s\n"), 
00196                       transaction_log_index->getErrorMessage().c_str());
00197         return 1;
00198       }
00199     }
00200 
00201     /* Create the applier plugin and register it */
00202     transaction_log_applier= new (nothrow) TransactionLogApplier("transaction_log_applier",
00203                                                                  transaction_log, 
00204                                                                  transaction_log_index, 
00205                                                                  static_cast<uint32_t>(sysvar_transaction_log_num_write_buffers));
00206     if (transaction_log_applier == NULL)
00207     {
00208       sql_perror(_("Failed to allocate the TransactionLogApplier instance"), sysvar_transaction_log_file);
00209       return 1;
00210     }
00211     context.add(transaction_log_applier);
00212     ReplicationServices &replication_services= ReplicationServices::singleton();
00213     replication_services.attachApplier(transaction_log_applier,
00214                                        sysvar_transaction_log_use_replicator);
00215 
00216     /* Setup DATA_DICTIONARY views */
00217 
00218     transaction_log_tool= new (nothrow) TransactionLogTool;
00219     context.add(transaction_log_tool);
00220     transaction_log_entries_tool= new (nothrow) TransactionLogEntriesTool;
00221     context.add(transaction_log_entries_tool);
00222     transaction_log_transactions_tool= new (nothrow) TransactionLogTransactionsTool;
00223     context.add(transaction_log_transactions_tool);
00224 
00225     /* Setup the module's UDFs */
00226     print_transaction_message_func_factory=
00227       new plugin::Create_function<PrintTransactionMessageFunction>("print_transaction_message");
00228     context.add(print_transaction_message_func_factory);
00229 
00230     hexdump_transaction_message_func_factory=
00231       new plugin::Create_function<HexdumpTransactionMessageFunction>("hexdump_transaction_message");
00232     context.add(hexdump_transaction_message_func_factory);
00233   }
00234   return 0;
00235 }
00236 
00237 
00238 static void init_options(drizzled::module::option_context &context)
00239 {
00240   context("truncate-debug",
00241           po::value<bool>(&sysvar_transaction_log_truncate_debug)->default_value(false)->zero_tokens(),
00242           _("DEBUGGING - Truncate transaction log"));
00243   context("enable-checksum",
00244           po::value<bool>(&sysvar_transaction_log_checksum_enabled)->default_value(false)->zero_tokens(),
00245           _("Enable CRC32 Checksumming of each written transaction log entry"));  
00246   context("enable",
00247           po::value<bool>(&sysvar_transaction_log_enabled)->default_value(false)->zero_tokens(),
00248           _("Enable transaction log"));
00249   context("file",
00250           po::value<string>(&sysvar_transaction_log_file)->default_value(DEFAULT_LOG_FILE_PATH),
00251           _("Path to the file to use for transaction log"));
00252   context("use-replicator",
00253           po::value<string>(&sysvar_transaction_log_use_replicator)->default_value(DEFAULT_USE_REPLICATOR),
00254           _("Name of the replicator plugin to use (default='default_replicator')")); 
00255   context("flush-frequency",
00256           po::value<flush_constraint>(&sysvar_transaction_log_flush_frequency)->default_value(0),
00257           _("0 == rely on operating system to sync log file (default), 1 == sync file at each transaction write, 2 == sync log file once per second"));
00258   context("num-write-buffers",
00259           po::value<write_buffers_constraint>(&sysvar_transaction_log_num_write_buffers)->default_value(8),
00260           _("Number of slots for in-memory write buffers (default=8)."));
00261 }
00262 
00263 DRIZZLE_PLUGIN(init, NULL, init_options);