1
/* Copyright (C) 2005 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#ifndef DRIZZLE_SERVER_LOG_H
17
#define DRIZZLE_SERVER_LOG_H
21
class Format_description_log_event;
24
Transaction Coordinator log - a base abstract class
25
for two different implementations
30
int using_heuristic_recover();
34
virtual int open(const char *opt_name)=0;
35
virtual void close()=0;
36
virtual int log_xid(THD *thd, my_xid xid)=0;
37
virtual void unlog(ulong cookie, my_xid xid)=0;
40
class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
44
int open(const char *opt_name __attribute__((unused)))
47
int log_xid(THD *thd __attribute__((unused)),
48
my_xid xid __attribute__((unused))) { return 1; }
49
void unlog(ulong cookie __attribute__((unused)),
50
my_xid xid __attribute__((unused))) { }
54
class TC_LOG_MMAP: public TC_LOG
56
public: // only to keep Sun Forte on sol9x86 happy
58
POOL, // page is in pool
59
ERROR, // last sync failed
60
DIRTY // new xids added since last sync
64
typedef struct st_page {
65
struct st_page *next; // page a linked in a fifo queue
66
my_xid *start, *end; // usable area of a page
67
my_xid *ptr; // next xid will be written here
68
int size, free; // max and current number of free xid slots on the page
69
int waiters; // number of waiters on condition
70
PAGE_STATE state; // see above
71
pthread_mutex_t lock; // to access page data or control structure
72
pthread_cond_t cond; // to wait for a sync
75
char logname[FN_REFLEN];
80
struct st_page *pages, *syncing, *active, *pool, *pool_last;
82
note that, e.g. LOCK_active is only used to protect
83
'active' pointer, to protect the content of the active page
84
one has to use active->lock.
85
Same for LOCK_pool and LOCK_sync
87
pthread_mutex_t LOCK_active, LOCK_pool, LOCK_sync;
88
pthread_cond_t COND_pool, COND_active;
91
TC_LOG_MMAP(): inited(0) {}
92
int open(const char *opt_name);
94
int log_xid(THD *thd, my_xid xid);
95
void unlog(ulong cookie, my_xid xid);
99
void get_active_from_pool();
104
#define TC_LOG_MMAP TC_LOG_DUMMY
107
extern TC_LOG *tc_log;
108
extern TC_LOG_MMAP tc_log_mmap;
109
extern TC_LOG_DUMMY tc_log_dummy;
111
/* log info errors */
112
#define LOG_INFO_EOF -1
113
#define LOG_INFO_IO -2
114
#define LOG_INFO_INVALID -3
115
#define LOG_INFO_SEEK -4
116
#define LOG_INFO_MEM -6
117
#define LOG_INFO_FATAL -7
118
#define LOG_INFO_IN_USE -8
119
#define LOG_INFO_EMFILE -9
122
/* bitmap to SQL_LOG::close() */
123
#define LOG_CLOSE_INDEX 1
124
#define LOG_CLOSE_TO_BE_OPENED 2
125
#define LOG_CLOSE_STOP_EVENT 4
127
class Relay_log_info;
129
typedef struct st_log_info
131
char log_file_name[FN_REFLEN];
132
my_off_t index_file_offset, index_file_start_offset;
134
bool fatal; // if the purge happens to give us a negative offset
135
pthread_mutex_t lock;
137
: index_file_offset(0), index_file_start_offset(0),
140
log_file_name[0] = '\0';
141
pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);
143
~st_log_info() { pthread_mutex_destroy(&lock);}
147
Currently we have only 3 kinds of logging functions: old-fashioned
148
logs, stdout and csv logging routines.
150
#define MAX_LOG_HANDLERS_NUM 3
152
/* log event handler flags */
157
class Rows_log_event;
159
enum enum_log_type { LOG_UNKNOWN, LOG_NORMAL, LOG_BIN };
160
enum enum_log_state { LOG_OPENED, LOG_CLOSED, LOG_TO_BE_OPENED };
163
TODO use mmap instead of IO_CACHE for binlog
164
(mmap+fsync is two times faster than write+fsync)
171
void init_pthread_objects();
173
bool open(const char *log_name,
174
enum_log_type log_type,
175
const char *new_name,
176
enum cache_type io_cache_type_arg);
177
void init(enum_log_type log_type_arg,
178
enum cache_type io_cache_type_arg);
179
void close(uint exiting);
180
inline bool is_open() { return log_state != LOG_CLOSED; }
181
const char *generate_name(const char *log_name, const char *suffix,
182
bool strip_ext, char *buff);
183
int generate_new_name(char *new_name, const char *log_name);
185
/* LOCK_log is inited by init_pthread_objects() */
186
pthread_mutex_t LOCK_log;
188
char log_file_name[FN_REFLEN];
189
char time_buff[20], db[NAME_LEN + 1];
190
bool write_error, inited;
192
enum_log_type log_type;
193
volatile enum_log_state log_state;
194
enum cache_type io_cache_type;
195
friend class Log_event;
198
class DRIZZLE_QUERY_LOG: public DRIZZLE_LOG
201
DRIZZLE_QUERY_LOG() : last_time(0) {}
203
bool write(time_t event_time, const char *user_host,
204
uint user_host_len, int thread_id,
205
const char *command_type, uint command_type_len,
206
const char *sql_text, uint sql_text_len);
207
bool write(THD *thd, time_t current_time, time_t query_start_arg,
208
const char *user_host, uint user_host_len,
209
uint64_t query_utime, uint64_t lock_utime, bool is_command,
210
const char *sql_text, uint sql_text_len);
211
bool open_slow_log(const char *log_name)
214
return open(generate_name(log_name, "-slow.log", 0, buf), LOG_NORMAL, 0,
217
bool open_query_log(const char *log_name)
220
return open(generate_name(log_name, ".log", 0, buf), LOG_NORMAL, 0,
228
class DRIZZLE_BIN_LOG: public TC_LOG, private DRIZZLE_LOG
231
/* LOCK_log and LOCK_index are inited by init_pthread_objects() */
232
pthread_mutex_t LOCK_index;
233
pthread_mutex_t LOCK_prep_xids;
234
pthread_cond_t COND_prep_xids;
235
pthread_cond_t update_cond;
236
uint64_t bytes_written;
238
char index_file_name[FN_REFLEN];
240
The max size before rotation (usable only if log_type == LOG_BIN: binary
241
logs and relay logs).
242
For a binlog, max_size should be max_binlog_size.
243
For a relay log, it should be max_relay_log_size if this is non-zero,
244
max_binlog_size otherwise.
245
max_size is set in init(), and dynamically changed (when one does SET
246
GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) by fix_max_binlog_size and
247
fix_max_relay_log_size).
250
long prepared_xids; /* for tc log - number of xids to remember */
251
// current file sequence number for load data infile binary logging
253
uint open_count; // For replication
255
bool need_start_event;
257
no_auto_events means we don't want any of these automatic events :
258
Start/Rotate/Stop. That is, in 4.x when we rotate a relay log, we don't
259
want a Rotate_log event to be written to the relay log. When we start a
260
relay log etc. So in 4.x this is 1 for relay logs, 0 for binlogs.
261
In 5.0 it's 0 for relay logs too!
265
uint64_t m_table_map_version;
267
int write_to_file(IO_CACHE *cache);
269
This is used to start writing to a new log file. The difference from
270
new_file() is locking. new_file_without_locking() does not acquire
273
void new_file_without_locking();
274
void new_file_impl(bool need_lock);
277
DRIZZLE_LOG::generate_name;
278
DRIZZLE_LOG::is_open;
280
These describe the log's format. This is used only for relay logs.
281
_for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
282
necessary to have 2 distinct objects, because the I/O thread may be reading
283
events in a different format from what the SQL thread is reading (consider
284
the case of a master which has been upgraded from 5.0 to 5.1 without doing
285
RESET MASTER, or from 4.x to 5.0).
287
Format_description_log_event *description_event_for_exec,
288
*description_event_for_queue;
292
note that there's no destructor ~DRIZZLE_BIN_LOG() !
293
The reason is that we don't want it to be automatically called
294
on exit() - but only during the correct shutdown process
297
int open(const char *opt_name);
299
int log_xid(THD *thd, my_xid xid);
300
void unlog(ulong cookie, my_xid xid);
301
int recover(IO_CACHE *log, Format_description_log_event *fdle);
302
#if !defined(DRIZZLE_CLIENT)
303
bool is_table_mapped(TABLE *table) const
305
return table->s->table_map_version == table_map_version();
308
uint64_t table_map_version() const { return m_table_map_version; }
309
void update_table_map_version() { ++m_table_map_version; }
311
int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event);
313
#endif /* !defined(DRIZZLE_CLIENT) */
314
void reset_bytes_written()
318
void harvest_bytes_written(uint64_t* counter)
320
(*counter)+=bytes_written;
324
void set_max_size(ulong max_size_arg);
325
void signal_update();
326
void wait_for_update_relay_log(THD* thd);
327
int wait_for_update_bin_log(THD* thd, const struct timespec * timeout);
328
void set_need_start_event() { need_start_event = 1; }
329
void init(bool no_auto_events_arg, ulong max_size);
330
void init_pthread_objects();
332
bool open(const char *log_name,
333
enum_log_type log_type,
334
const char *new_name,
335
enum cache_type io_cache_type_arg,
336
bool no_auto_events_arg, ulong max_size,
338
bool open_index_file(const char *index_file_name_arg,
339
const char *log_name);
340
/* Use this to start writing a new log file */
343
bool write(Log_event* event_info); // binary log write
344
bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event);
346
int write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync);
348
void start_union_events(THD *thd, query_id_t query_id_param);
349
void stop_union_events(THD *thd);
350
bool is_query_in_union(THD *thd, query_id_t query_id_param);
354
invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
356
bool appendv(const char* buf,uint len,...);
357
bool append(Log_event* ev);
359
void make_log_name(char* buf, const char* log_ident);
360
bool is_active(const char* log_file_name);
361
int update_log_index(LOG_INFO* linfo, bool need_update_threads);
362
void rotate_and_purge(uint flags);
363
bool flush_and_sync();
364
int purge_logs(const char *to_log, bool included,
365
bool need_mutex, bool need_update_threads,
366
uint64_t *decrease_log_space);
367
int purge_logs_before_date(time_t purge_time);
368
int purge_first_log(Relay_log_info* rli, bool included);
369
bool reset_logs(THD* thd);
370
void close(uint exiting);
372
// iterating through the log index file
373
int find_log_pos(LOG_INFO* linfo, const char* log_name,
375
int find_next_log(LOG_INFO* linfo, bool need_mutex);
376
int get_current_log(LOG_INFO* linfo);
377
int raw_get_current_log(LOG_INFO* linfo);
379
inline char* get_index_fname() { return index_file_name;}
380
inline char* get_log_fname() { return log_file_name; }
381
inline char* get_name() { return name; }
382
inline pthread_mutex_t* get_log_lock() { return &LOCK_log; }
383
inline IO_CACHE* get_log_file() { return &log_file; }
385
inline void lock_index() { pthread_mutex_lock(&LOCK_index);}
386
inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
387
inline IO_CACHE *get_index_file() { return &index_file;}
388
inline uint32_t get_open_count() { return open_count; }
391
class Log_event_handler
394
Log_event_handler() {}
395
virtual bool init()= 0;
396
virtual void cleanup()= 0;
398
virtual bool log_slow(THD *thd, time_t current_time,
399
time_t query_start_arg, const char *user_host,
400
uint user_host_len, uint64_t query_utime,
401
uint64_t lock_utime, bool is_command,
402
const char *sql_text, uint sql_text_len)= 0;
403
virtual bool log_error(enum loglevel level, const char *format,
405
virtual bool log_general(THD *thd, time_t event_time, const char *user_host,
406
uint user_host_len, int thread_id,
407
const char *command_type, uint command_type_len,
408
const char *sql_text, uint sql_text_len,
409
const CHARSET_INFO * const client_cs)= 0;
410
virtual ~Log_event_handler() {}
414
/* type of the log table */
415
#define QUERY_LOG_SLOW 1
416
#define QUERY_LOG_GENERAL 2
418
class Log_to_file_event_handler: public Log_event_handler
420
DRIZZLE_QUERY_LOG mysql_log;
421
DRIZZLE_QUERY_LOG mysql_slow_log;
424
Log_to_file_event_handler(): is_initialized(false)
427
virtual void cleanup();
429
virtual bool log_slow(THD *thd, time_t current_time,
430
time_t query_start_arg, const char *user_host,
431
uint user_host_len, uint64_t query_utime,
432
uint64_t lock_utime, bool is_command,
433
const char *sql_text, uint sql_text_len);
434
virtual bool log_error(enum loglevel level, const char *format,
436
virtual bool log_general(THD *thd, time_t event_time, const char *user_host,
437
uint user_host_len, int thread_id,
438
const char *command_type, uint command_type_len,
439
const char *sql_text, uint sql_text_len,
440
const CHARSET_INFO * const client_cs);
442
void init_pthread_objects();
443
DRIZZLE_QUERY_LOG *get_mysql_slow_log() { return &mysql_slow_log; }
444
DRIZZLE_QUERY_LOG *get_mysql_log() { return &mysql_log; }
448
/* Class which manages slow, general and error log event handlers */
451
rw_lock_t LOCK_logger;
452
/* flag to check whether logger mutex is initialized */
455
/* available log handlers */
456
Log_to_file_event_handler *file_log_handler;
458
/* NULL-terminated arrays of log handlers */
459
Log_event_handler *error_log_handler_list[MAX_LOG_HANDLERS_NUM + 1];
460
Log_event_handler *slow_log_handler_list[MAX_LOG_HANDLERS_NUM + 1];
461
Log_event_handler *general_log_handler_list[MAX_LOG_HANDLERS_NUM + 1];
465
LOGGER() : inited(0), file_log_handler(NULL)
467
void lock_shared() { rw_rdlock(&LOCK_logger); }
468
void lock_exclusive() { rw_wrlock(&LOCK_logger); }
469
void unlock() { rw_unlock(&LOCK_logger); }
470
bool log_command(THD *thd, enum enum_server_command command);
473
We want to initialize all log mutexes as soon as possible,
474
but we cannot do it in constructor, as safe_mutex relies on
475
initialization, performed by MY_INIT(). This why this is done in
479
bool flush_logs(THD *thd);
480
/* Perform basic logger cleanup. this will leave e.g. error log open. */
482
/* Free memory. Nothing could be logged after this function is called */
484
bool error_log_print(enum loglevel level, const char *format,
486
bool slow_log_print(THD *thd, const char *query, uint query_length,
487
uint64_t current_utime);
488
bool general_log_print(THD *thd,enum enum_server_command command,
489
const char *format, va_list args);
490
bool general_log_write(THD *thd, enum enum_server_command command,
491
const char *query, uint query_length);
493
/* we use this function to setup all enabled log event handlers */
494
int set_handlers(uint error_log_printer,
495
uint slow_log_printer,
496
uint general_log_printer);
497
void init_error_log(uint error_log_printer);
498
void init_slow_log(uint slow_log_printer);
499
void init_general_log(uint general_log_printer);
500
void deactivate_log_handler(THD* thd, uint log_type);
501
bool activate_log_handler(THD* thd, uint log_type);
502
DRIZZLE_QUERY_LOG *get_slow_log_file_handler()
504
if (file_log_handler)
505
return file_log_handler->get_mysql_slow_log();
508
DRIZZLE_QUERY_LOG *get_log_file_handler()
510
if (file_log_handler)
511
return file_log_handler->get_mysql_log();
516
enum enum_binlog_format {
518
statement-based except for cases where only row-based can work (UUID()
521
BINLOG_FORMAT_MIXED= 0,
522
BINLOG_FORMAT_STMT= 1, // statement-based
523
BINLOG_FORMAT_ROW= 2, // row_based
525
This value is last, after the end of binlog_format_typelib: it has no
526
corresponding cell in this typelib. We use this value to be able to know if
527
the user has explicitely specified a binlog format at startup or not.
529
BINLOG_FORMAT_UNSPEC= 3
531
extern TYPELIB binlog_format_typelib;
533
int vprint_msg_to_log(enum loglevel level, const char *format, va_list args);
534
void sql_print_error(const char *format, ...) __attribute__((format(printf, 1, 2)));
535
void sql_print_warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
536
void sql_print_information(const char *format, ...)
537
__attribute__((format(printf, 1, 2)));
538
typedef void (*sql_print_message_func)(const char *format, ...)
539
__attribute__((format(printf, 1, 2)));
540
extern sql_print_message_func sql_print_message_handlers[];
542
int error_log_print(enum loglevel level, const char *format,
545
bool slow_log_print(THD *thd, const char *query, uint query_length,
546
uint64_t current_utime);
548
bool general_log_print(THD *thd, enum enum_server_command command,
549
const char *format,...);
551
bool general_log_write(THD *thd, enum enum_server_command command,
552
const char *query, uint query_length);
554
#endif /* DRIZZLE_SERVER_LOG_H */