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
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
* Defines the implementation of the default serial event log.
26
* @see drizzled/plugin/replicator.h
27
* @see drizzled/plugin/applier.h
31
* Currently, this is a very simple implementation. We have a global
32
* lock on the file writer and write the events as the are received,
33
* first writing a 64-bit length and then the serialized transaction/command.
37
* Possibly look at a scoreboard approach with multiple file segments. For
38
* right now, though, this is just a quick simple implementation to serve
39
* as a skeleton and a springboard.
42
#include "serial_event_log.h"
44
#include <drizzled/gettext.h>
45
#include <drizzled/message/transaction.pb.h>
52
/** Serial Event Log plugin system variable - The path to the log file used */
53
static char* sysvar_serial_event_log_file= NULL;
54
static const char DEFAULT_LOG_FILE_PATH[16]= "event.log"; /* In datadir... */
56
SerialEventLog::SerialEventLog(const char *in_log_file_path)
58
drizzled::plugin::Applier(),
59
state(SerialEventLog::OFFLINE),
61
log_file_path(in_log_file_path)
63
/* Setup our lock protection and our log file... */
64
if (pthread_mutex_init(&lock, NULL) != 0)
66
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize lock on serial event log. Got error: %s"), strerror(errno));
71
log_file= open(log_file_path, O_APPEND|O_CREAT|O_SYNC|O_WRONLY, S_IRWXU);
74
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to open serial event log file. Got error: %s"), strerror(errno));
79
state= SerialEventLog::ONLINE;
83
SerialEventLog::~SerialEventLog()
85
/* Clear up any resources we've consumed */
86
if (is_active && state != SerialEventLog::CRASHED && log_file != -1)
88
(void) close(log_file);
90
if (pthread_mutex_destroy(&lock) != 0)
92
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to destroy lock on serial event log. Got error: %s"), strerror(errno));
96
bool SerialEventLog::isActive()
101
void SerialEventLog::apply(drizzled::message::Command *to_apply)
103
std::string buffer; /* Buffer we will write serialized command to */
107
to_apply->SerializeToString(&buffer);
108
length= buffer.length();
110
pthread_mutex_lock(&lock);
113
* Quick safety...if an error occurs below, the log file will
114
* not be active, therefore a caller could have been waiting
117
if (unlikely(state == SerialEventLog::CRASHED))
119
pthread_mutex_unlock(&lock);
123
written= write(log_file, &length, sizeof(uint64_t));
124
if (unlikely(written != sizeof(uint64_t)))
126
errmsg_printf(ERRMSG_LVL_ERROR,
127
_("Failed to write full size of command. Tried to write %" PRId64 ", but only wrote %" PRId64 ". Error: %s"),
133
pthread_mutex_unlock(&lock);
137
written= write(log_file, buffer.c_str(), length);
138
if (unlikely(written != length))
140
errmsg_printf(ERRMSG_LVL_ERROR,
141
_("Failed to write full serialized command. Tried to write %" PRId64 ", but only wrote %" PRId64 ". Error: %s"),
147
pthread_mutex_unlock(&lock);
150
pthread_mutex_unlock(&lock);
153
static SerialEventLog *serial_event_log= NULL; /* The singleton serial log */
155
static int init(PluginRegistry ®istry)
157
serial_event_log= new SerialEventLog(sysvar_serial_event_log_file);
158
registry.add(serial_event_log);
162
static int deinit(PluginRegistry ®istry)
164
if (serial_event_log)
166
registry.remove(serial_event_log);
167
delete serial_event_log;
172
static DRIZZLE_SYSVAR_STR(log_file,
173
sysvar_serial_event_log_file,
175
N_("Path to the file to use for serial event log."),
176
NULL, /* check func */
177
NULL, /* update func*/
178
DEFAULT_LOG_FILE_PATH /* default */);
180
static struct st_mysql_sys_var* system_variables[]= {
181
DRIZZLE_SYSVAR(log_file),
185
drizzle_declare_plugin(serial_event_log)
190
N_("Default Serial Event Log"),
192
init, /* Plugin Init */
193
deinit, /* Plugin Deinit */
194
NULL, /* status variables */
195
system_variables, /* system variables */
196
NULL /* config options */
198
drizzle_declare_plugin_end;