1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 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; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#ifndef DRIZZLE_SERVER_LOG_H
21
#define DRIZZLE_SERVER_LOG_H
23
#include <mysys/iocache.h>
24
#include <drizzled/xid.h>
28
class Format_description_log_event;
31
Transaction Coordinator log - a base abstract class
32
for two different implementations
37
int using_heuristic_recover();
41
virtual int open(const char *opt_name)=0;
42
virtual void close()=0;
43
virtual int log_xid(Session *session, my_xid xid)=0;
44
virtual void unlog(ulong cookie, my_xid xid)=0;
47
class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
51
int open(const char *opt_name __attribute__((unused)))
54
int log_xid(Session *session __attribute__((unused)),
55
my_xid xid __attribute__((unused))) { return 1; }
56
void unlog(ulong cookie __attribute__((unused)),
57
my_xid xid __attribute__((unused))) { }
61
class TC_LOG_MMAP: public TC_LOG
63
public: // only to keep Sun Forte on sol9x86 happy
65
POOL, // page is in pool
66
ERROR, // last sync failed
67
DIRTY // new xids added since last sync
71
typedef struct st_page {
72
struct st_page *next; // page a linked in a fifo queue
73
my_xid *start, *end; // usable area of a page
74
my_xid *ptr; // next xid will be written here
75
int size, free; // max and current number of free xid slots on the page
76
int waiters; // number of waiters on condition
77
PAGE_STATE state; // see above
78
pthread_mutex_t lock; // to access page data or control structure
79
pthread_cond_t cond; // to wait for a sync
82
char logname[FN_REFLEN];
85
uint32_t npages, inited;
87
struct st_page *pages, *syncing, *active, *pool, *pool_last;
89
note that, e.g. LOCK_active is only used to protect
90
'active' pointer, to protect the content of the active page
91
one has to use active->lock.
92
Same for LOCK_pool and LOCK_sync
94
pthread_mutex_t LOCK_active, LOCK_pool, LOCK_sync;
95
pthread_cond_t COND_pool, COND_active;
98
TC_LOG_MMAP(): inited(0) {}
99
int open(const char *opt_name);
101
int log_xid(Session *session, my_xid xid);
102
void unlog(ulong cookie, my_xid xid);
106
void get_active_from_pool();
111
#define TC_LOG_MMAP TC_LOG_DUMMY
114
extern TC_LOG *tc_log;
115
extern TC_LOG_MMAP tc_log_mmap;
116
extern TC_LOG_DUMMY tc_log_dummy;
118
/* log info errors */
119
#define LOG_INFO_EOF -1
120
#define LOG_INFO_IO -2
121
#define LOG_INFO_INVALID -3
122
#define LOG_INFO_SEEK -4
123
#define LOG_INFO_MEM -6
124
#define LOG_INFO_FATAL -7
125
#define LOG_INFO_IN_USE -8
126
#define LOG_INFO_EMFILE -9
129
/* bitmap to SQL_LOG::close() */
130
#define LOG_CLOSE_INDEX 1
131
#define LOG_CLOSE_TO_BE_OPENED 2
132
#define LOG_CLOSE_STOP_EVENT 4
134
class Relay_log_info;
136
typedef struct st_log_info
138
char log_file_name[FN_REFLEN];
139
my_off_t index_file_offset, index_file_start_offset;
141
bool fatal; // if the purge happens to give us a negative offset
142
pthread_mutex_t lock;
144
: index_file_offset(0), index_file_start_offset(0),
147
log_file_name[0] = '\0';
148
pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);
150
~st_log_info() { pthread_mutex_destroy(&lock);}
154
Currently we have only 3 kinds of logging functions: old-fashioned
155
logs, stdout and csv logging routines.
157
#define MAX_LOG_HANDLERS_NUM 3
159
/* log event handler flags */
164
class Rows_log_event;
166
enum enum_log_type { LOG_UNKNOWN, LOG_NORMAL, LOG_BIN };
167
enum enum_log_state { LOG_OPENED, LOG_CLOSED, LOG_TO_BE_OPENED };
170
TODO use mmap instead of IO_CACHE for binlog
171
(mmap+fsync is two times faster than write+fsync)
178
void init_pthread_objects();
180
bool open(const char *log_name,
181
enum_log_type log_type,
182
const char *new_name,
183
enum cache_type io_cache_type_arg);
184
void init(enum_log_type log_type_arg,
185
enum cache_type io_cache_type_arg);
186
void close(uint32_t exiting);
187
inline bool is_open() { return log_state != LOG_CLOSED; }
188
const char *generate_name(const char *log_name, const char *suffix,
189
bool strip_ext, char *buff);
190
int generate_new_name(char *new_name, const char *log_name);
192
/* LOCK_log is inited by init_pthread_objects() */
193
pthread_mutex_t LOCK_log;
195
char log_file_name[FN_REFLEN];
196
char time_buff[20], db[NAME_LEN + 1];
197
bool write_error, inited;
199
enum_log_type log_type;
200
volatile enum_log_state log_state;
201
enum cache_type io_cache_type;
202
friend class Log_event;
205
class DRIZZLE_BIN_LOG: public TC_LOG, private DRIZZLE_LOG
208
/* LOCK_log and LOCK_index are inited by init_pthread_objects() */
209
pthread_mutex_t LOCK_index;
210
pthread_mutex_t LOCK_prep_xids;
211
pthread_cond_t COND_prep_xids;
212
pthread_cond_t update_cond;
213
uint64_t bytes_written;
215
char index_file_name[FN_REFLEN];
217
The max size before rotation (usable only if log_type == LOG_BIN: binary
218
logs and relay logs).
219
For a binlog, max_size should be max_binlog_size.
220
For a relay log, it should be max_relay_log_size if this is non-zero,
221
max_binlog_size otherwise.
222
max_size is set in init(), and dynamically changed (when one does SET
223
GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) by fix_max_binlog_size and
224
fix_max_relay_log_size).
227
long prepared_xids; /* for tc log - number of xids to remember */
228
// current file sequence number for load data infile binary logging
230
uint32_t open_count; // For replication
232
bool need_start_event;
234
no_auto_events means we don't want any of these automatic events :
235
Start/Rotate/Stop. That is, in 4.x when we rotate a relay log, we don't
236
want a Rotate_log event to be written to the relay log. When we start a
237
relay log etc. So in 4.x this is 1 for relay logs, 0 for binlogs.
238
In 5.0 it's 0 for relay logs too!
242
uint64_t m_table_map_version;
244
int write_to_file(IO_CACHE *cache);
246
This is used to start writing to a new log file. The difference from
247
new_file() is locking. new_file_without_locking() does not acquire
250
void new_file_without_locking();
251
void new_file_impl(bool need_lock);
254
DRIZZLE_LOG::generate_name;
255
DRIZZLE_LOG::is_open;
257
These describe the log's format. This is used only for relay logs.
258
_for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
259
necessary to have 2 distinct objects, because the I/O thread may be reading
260
events in a different format from what the SQL thread is reading (consider
261
the case of a master which has been upgraded from 5.0 to 5.1 without doing
262
RESET MASTER, or from 4.x to 5.0).
264
Format_description_log_event *description_event_for_exec,
265
*description_event_for_queue;
269
note that there's no destructor ~DRIZZLE_BIN_LOG() !
270
The reason is that we don't want it to be automatically called
271
on exit() - but only during the correct shutdown process
274
int open(const char *opt_name);
276
int log_xid(Session *session, my_xid xid);
277
void unlog(ulong cookie, my_xid xid);
278
int recover(IO_CACHE *log, Format_description_log_event *fdle);
279
bool is_table_mapped(Table *table) const
281
return table->s->table_map_version == table_map_version();
284
uint64_t table_map_version() const { return m_table_map_version; }
285
void update_table_map_version() { ++m_table_map_version; }
287
int flush_and_set_pending_rows_event(Session *session, Rows_log_event* event);
289
void reset_bytes_written()
293
void harvest_bytes_written(uint64_t* counter)
295
(*counter)+=bytes_written;
299
void set_max_size(ulong max_size_arg);
300
void signal_update();
301
void wait_for_update_relay_log(Session* session);
302
int wait_for_update_bin_log(Session* session, const struct timespec * timeout);
303
void set_need_start_event() { need_start_event = 1; }
304
void init(bool no_auto_events_arg, ulong max_size);
305
void init_pthread_objects();
307
bool open(const char *log_name,
308
enum_log_type log_type,
309
const char *new_name,
310
enum cache_type io_cache_type_arg,
311
bool no_auto_events_arg, ulong max_size,
313
bool open_index_file(const char *index_file_name_arg,
314
const char *log_name);
315
/* Use this to start writing a new log file */
318
bool write(Log_event* event_info); // binary log write
319
bool write(Session *session, IO_CACHE *cache, Log_event *commit_event);
321
int write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync);
323
void start_union_events(Session *session, query_id_t query_id_param);
324
void stop_union_events(Session *session);
325
bool is_query_in_union(Session *session, query_id_t query_id_param);
329
invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
331
bool appendv(const char* buf,uint32_t len,...);
332
bool append(Log_event* ev);
334
void make_log_name(char* buf, const char* log_ident);
335
bool is_active(const char* log_file_name);
336
int update_log_index(LOG_INFO* linfo, bool need_update_threads);
337
void rotate_and_purge(uint32_t flags);
338
bool flush_and_sync();
339
int purge_logs(const char *to_log, bool included,
340
bool need_mutex, bool need_update_threads,
341
uint64_t *decrease_log_space);
342
int purge_logs_before_date(time_t purge_time);
343
int purge_first_log(Relay_log_info* rli, bool included);
344
bool reset_logs(Session* session);
345
void close(uint32_t exiting);
347
// iterating through the log index file
348
int find_log_pos(LOG_INFO* linfo, const char* log_name,
350
int find_next_log(LOG_INFO* linfo, bool need_mutex);
351
int get_current_log(LOG_INFO* linfo);
352
int raw_get_current_log(LOG_INFO* linfo);
353
uint32_t next_file_id();
354
inline char* get_index_fname() { return index_file_name;}
355
inline char* get_log_fname() { return log_file_name; }
356
inline char* get_name() { return name; }
357
inline pthread_mutex_t* get_log_lock() { return &LOCK_log; }
358
inline IO_CACHE* get_log_file() { return &log_file; }
360
inline void lock_index() { pthread_mutex_lock(&LOCK_index);}
361
inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
362
inline IO_CACHE *get_index_file() { return &index_file;}
363
inline uint32_t get_open_count() { return open_count; }
366
class Log_event_handler
369
Log_event_handler() {}
370
virtual bool init()= 0;
371
virtual void cleanup()= 0;
373
virtual bool log_error(enum loglevel level, const char *format,
375
virtual ~Log_event_handler() {}
379
/* Class which manages slow, general and error log event handlers */
382
rw_lock_t LOCK_logger;
383
/* flag to check whether logger mutex is initialized */
386
/* NULL-terminated arrays of log handlers */
387
Log_event_handler *error_log_handler_list[MAX_LOG_HANDLERS_NUM + 1];
393
void lock_shared() { rw_rdlock(&LOCK_logger); }
394
void lock_exclusive() { rw_wrlock(&LOCK_logger); }
395
void unlock() { rw_unlock(&LOCK_logger); }
396
bool log_command(Session *session, enum enum_server_command command);
399
We want to initialize all log mutexes as soon as possible,
400
but we cannot do it in constructor, as safe_mutex relies on
401
initialization, performed by MY_INIT(). This why this is done in
405
bool flush_logs(Session *session);
406
/* Perform basic logger cleanup. this will leave e.g. error log open. */
408
/* Free memory. Nothing could be logged after this function is called */
410
bool error_log_print(enum loglevel level, const char *format,
412
/* we use this function to setup all enabled log event handlers */
413
int set_handlers(uint32_t error_log_printer);
414
void init_error_log(uint32_t error_log_printer);
417
enum enum_binlog_format {
419
statement-based except for cases where only row-based can work (UUID()
422
BINLOG_FORMAT_MIXED= 0,
423
BINLOG_FORMAT_STMT= 1, // statement-based
424
BINLOG_FORMAT_ROW= 2, // row_based
426
This value is last, after the end of binlog_format_typelib: it has no
427
corresponding cell in this typelib. We use this value to be able to know if
428
the user has explicitely specified a binlog format at startup or not.
430
BINLOG_FORMAT_UNSPEC= 3
432
extern TYPELIB binlog_format_typelib;
434
int vprint_msg_to_log(enum loglevel level, const char *format, va_list args);
435
void sql_print_error(const char *format, ...) __attribute__((format(printf, 1, 2)));
436
void sql_print_warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
437
void sql_print_information(const char *format, ...)
438
__attribute__((format(printf, 1, 2)));
439
typedef void (*sql_print_message_func)(const char *format, ...)
440
__attribute__((format(printf, 1, 2)));
441
extern sql_print_message_func sql_print_message_handlers[];
443
int error_log_print(enum loglevel level, const char *format,
446
void sql_perror(const char *message);
449
#endif /* DRIZZLE_SERVER_LOG_H */