~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/log.h

  • Committer: Monty Taylor
  • Date: 2008-08-01 22:33:44 UTC
  • mto: (236.1.42 codestyle)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: monty@inaugust.com-20080801223344-vzhlflfmtijp1imv
First pass at gettexizing the error messages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2005 MySQL AB
 
2
 
 
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.
 
6
 
 
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.
 
11
 
 
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 */
 
15
 
 
16
#ifndef LOG_H
 
17
#define LOG_H
 
18
 
 
19
class Relay_log_info;
 
20
 
 
21
class Format_description_log_event;
 
22
 
 
23
/*
 
24
  Transaction Coordinator log - a base abstract class
 
25
  for two different implementations
 
26
*/
 
27
class TC_LOG
 
28
{
 
29
  public:
 
30
  int using_heuristic_recover();
 
31
  TC_LOG() {}
 
32
  virtual ~TC_LOG() {}
 
33
 
 
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;
 
38
};
 
39
 
 
40
class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
 
41
{
 
42
public:
 
43
  TC_LOG_DUMMY() {}
 
44
  int open(const char *opt_name __attribute__((unused)))
 
45
  { return 0; }
 
46
  void close(void)                          { }
 
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)))  { }
 
51
};
 
52
 
 
53
#ifdef HAVE_MMAP
 
54
class TC_LOG_MMAP: public TC_LOG
 
55
{
 
56
  public:                // only to keep Sun Forte on sol9x86 happy
 
57
  typedef enum {
 
58
    POOL,                 // page is in pool
 
59
    ERROR,                // last sync failed
 
60
    DIRTY                 // new xids added since last sync
 
61
  } PAGE_STATE;
 
62
 
 
63
  private:
 
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
 
73
  } PAGE;
 
74
 
 
75
  char logname[FN_REFLEN];
 
76
  File fd;
 
77
  my_off_t file_length;
 
78
  uint npages, inited;
 
79
  uchar *data;
 
80
  struct st_page *pages, *syncing, *active, *pool, *pool_last;
 
81
  /*
 
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
 
86
  */
 
87
  pthread_mutex_t LOCK_active, LOCK_pool, LOCK_sync;
 
88
  pthread_cond_t COND_pool, COND_active;
 
89
 
 
90
  public:
 
91
  TC_LOG_MMAP(): inited(0) {}
 
92
  int open(const char *opt_name);
 
93
  void close();
 
94
  int log_xid(THD *thd, my_xid xid);
 
95
  void unlog(ulong cookie, my_xid xid);
 
96
  int recover();
 
97
 
 
98
  private:
 
99
  void get_active_from_pool();
 
100
  int sync();
 
101
  int overflow();
 
102
};
 
103
#else
 
104
#define TC_LOG_MMAP TC_LOG_DUMMY
 
105
#endif
 
106
 
 
107
extern TC_LOG *tc_log;
 
108
extern TC_LOG_MMAP tc_log_mmap;
 
109
extern TC_LOG_DUMMY tc_log_dummy;
 
110
 
 
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
 
120
 
 
121
 
 
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
 
126
 
 
127
class Relay_log_info;
 
128
 
 
129
typedef struct st_log_info
 
130
{
 
131
  char log_file_name[FN_REFLEN];
 
132
  my_off_t index_file_offset, index_file_start_offset;
 
133
  my_off_t pos;
 
134
  bool fatal; // if the purge happens to give us a negative offset
 
135
  pthread_mutex_t lock;
 
136
  st_log_info()
 
137
    : index_file_offset(0), index_file_start_offset(0),
 
138
      pos(0), fatal(0)
 
139
    {
 
140
      log_file_name[0] = '\0';
 
141
      pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);
 
142
    }
 
143
  ~st_log_info() { pthread_mutex_destroy(&lock);}
 
144
} LOG_INFO;
 
145
 
 
146
/*
 
147
  Currently we have only 3 kinds of logging functions: old-fashioned
 
148
  logs, stdout and csv logging routines.
 
149
*/
 
150
#define MAX_LOG_HANDLERS_NUM 3
 
151
 
 
152
/* log event handler flags */
 
153
#define LOG_NONE       1
 
154
#define LOG_FILE       2
 
155
 
 
156
class Log_event;
 
157
class Rows_log_event;
 
158
 
 
159
enum enum_log_type { LOG_UNKNOWN, LOG_NORMAL, LOG_BIN };
 
160
enum enum_log_state { LOG_OPENED, LOG_CLOSED, LOG_TO_BE_OPENED };
 
161
 
 
162
/*
 
163
  TODO use mmap instead of IO_CACHE for binlog
 
164
  (mmap+fsync is two times faster than write+fsync)
 
165
*/
 
166
 
 
167
class MYSQL_LOG
 
168
{
 
169
public:
 
170
  MYSQL_LOG();
 
171
  void init_pthread_objects();
 
172
  void cleanup();
 
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);
 
184
 protected:
 
185
  /* LOCK_log is inited by init_pthread_objects() */
 
186
  pthread_mutex_t LOCK_log;
 
187
  char *name;
 
188
  char log_file_name[FN_REFLEN];
 
189
  char time_buff[20], db[NAME_LEN + 1];
 
190
  bool write_error, inited;
 
191
  IO_CACHE log_file;
 
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;
 
196
};
 
197
 
 
198
class MYSQL_QUERY_LOG: public MYSQL_LOG
 
199
{
 
200
public:
 
201
  MYSQL_QUERY_LOG() : last_time(0) {}
 
202
  void reopen_file();
 
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)
 
212
  {
 
213
    char buf[FN_REFLEN];
 
214
    return open(generate_name(log_name, "-slow.log", 0, buf), LOG_NORMAL, 0,
 
215
                WRITE_CACHE);
 
216
  }
 
217
  bool open_query_log(const char *log_name)
 
218
  {
 
219
    char buf[FN_REFLEN];
 
220
    return open(generate_name(log_name, ".log", 0, buf), LOG_NORMAL, 0,
 
221
                WRITE_CACHE);
 
222
  }
 
223
 
 
224
private:
 
225
  time_t last_time;
 
226
};
 
227
 
 
228
class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
 
229
{
 
230
 private:
 
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;
 
237
  IO_CACHE index_file;
 
238
  char index_file_name[FN_REFLEN];
 
239
  /*
 
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).
 
248
  */
 
249
  ulong max_size;
 
250
  long prepared_xids; /* for tc log - number of xids to remember */
 
251
  // current file sequence number for load data infile binary logging
 
252
  uint file_id;
 
253
  uint open_count;                              // For replication
 
254
  int readers_count;
 
255
  bool need_start_event;
 
256
  /*
 
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!
 
262
  */
 
263
  bool no_auto_events;
 
264
 
 
265
  uint64_t m_table_map_version;
 
266
 
 
267
  int write_to_file(IO_CACHE *cache);
 
268
  /*
 
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
 
271
    LOCK_log.
 
272
  */
 
273
  void new_file_without_locking();
 
274
  void new_file_impl(bool need_lock);
 
275
 
 
276
public:
 
277
  MYSQL_LOG::generate_name;
 
278
  MYSQL_LOG::is_open;
 
279
  /*
 
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).
 
286
  */
 
287
  Format_description_log_event *description_event_for_exec,
 
288
    *description_event_for_queue;
 
289
 
 
290
  MYSQL_BIN_LOG();
 
291
  /*
 
292
    note that there's no destructor ~MYSQL_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
 
295
  */
 
296
 
 
297
  int open(const char *opt_name);
 
298
  void close();
 
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(MYSQL_CLIENT)
 
303
  bool is_table_mapped(TABLE *table) const
 
304
  {
 
305
    return table->s->table_map_version == table_map_version();
 
306
  }
 
307
 
 
308
  uint64_t table_map_version() const { return m_table_map_version; }
 
309
  void update_table_map_version() { ++m_table_map_version; }
 
310
 
 
311
  int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event);
 
312
 
 
313
#endif /* !defined(MYSQL_CLIENT) */
 
314
  void reset_bytes_written()
 
315
  {
 
316
    bytes_written = 0;
 
317
  }
 
318
  void harvest_bytes_written(uint64_t* counter)
 
319
  {
 
320
    (*counter)+=bytes_written;
 
321
    bytes_written=0;
 
322
    return;
 
323
  }
 
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();
 
331
  void cleanup();
 
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,
 
337
            bool null_created);
 
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 */
 
341
  void new_file();
 
342
 
 
343
  bool write(Log_event* event_info); // binary log write
 
344
  bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event);
 
345
 
 
346
  int  write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync);
 
347
 
 
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);
 
351
 
 
352
  /*
 
353
    v stands for vector
 
354
    invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
 
355
  */
 
356
  bool appendv(const char* buf,uint len,...);
 
357
  bool append(Log_event* ev);
 
358
 
 
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);
 
371
 
 
372
  // iterating through the log index file
 
373
  int find_log_pos(LOG_INFO* linfo, const char* log_name,
 
374
                   bool need_mutex);
 
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);
 
378
  uint next_file_id();
 
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; }
 
384
 
 
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; }
 
389
};
 
390
 
 
391
class Log_event_handler
 
392
{
 
393
public:
 
394
  Log_event_handler() {}
 
395
  virtual bool init()= 0;
 
396
  virtual void cleanup()= 0;
 
397
 
 
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,
 
404
                         va_list args)= 0;
 
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
                           CHARSET_INFO *client_cs)= 0;
 
410
  virtual ~Log_event_handler() {}
 
411
};
 
412
 
 
413
 
 
414
/* type of the log table */
 
415
#define QUERY_LOG_SLOW 1
 
416
#define QUERY_LOG_GENERAL 2
 
417
 
 
418
class Log_to_file_event_handler: public Log_event_handler
 
419
{
 
420
  MYSQL_QUERY_LOG mysql_log;
 
421
  MYSQL_QUERY_LOG mysql_slow_log;
 
422
  bool is_initialized;
 
423
public:
 
424
  Log_to_file_event_handler(): is_initialized(false)
 
425
  {}
 
426
  virtual bool init();
 
427
  virtual void cleanup();
 
428
 
 
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,
 
435
                         va_list args);
 
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
                           CHARSET_INFO *client_cs);
 
441
  void flush();
 
442
  void init_pthread_objects();
 
443
  MYSQL_QUERY_LOG *get_mysql_slow_log() { return &mysql_slow_log; }
 
444
  MYSQL_QUERY_LOG *get_mysql_log() { return &mysql_log; }
 
445
};
 
446
 
 
447
 
 
448
/* Class which manages slow, general and error log event handlers */
 
449
class LOGGER
 
450
{
 
451
  rw_lock_t LOCK_logger;
 
452
  /* flag to check whether logger mutex is initialized */
 
453
  uint inited;
 
454
 
 
455
  /* available log handlers */
 
456
  Log_to_file_event_handler *file_log_handler;
 
457
 
 
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];
 
462
 
 
463
public:
 
464
 
 
465
  LOGGER() : inited(0), file_log_handler(NULL)
 
466
  {}
 
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);
 
471
 
 
472
  /*
 
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
 
476
    this function.
 
477
  */
 
478
  void init_base();
 
479
  bool flush_logs(THD *thd);
 
480
  /* Perform basic logger cleanup. this will leave e.g. error log open. */
 
481
  void cleanup_base();
 
482
  /* Free memory. Nothing could be logged after this function is called */
 
483
  void cleanup_end();
 
484
  bool error_log_print(enum loglevel level, const char *format,
 
485
                      va_list args);
 
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);
 
492
 
 
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
  MYSQL_QUERY_LOG *get_slow_log_file_handler()
 
503
  { 
 
504
    if (file_log_handler)
 
505
      return file_log_handler->get_mysql_slow_log();
 
506
    return NULL;
 
507
  }
 
508
  MYSQL_QUERY_LOG *get_log_file_handler()
 
509
  { 
 
510
    if (file_log_handler)
 
511
      return file_log_handler->get_mysql_log();
 
512
    return NULL;
 
513
  }
 
514
};
 
515
 
 
516
enum enum_binlog_format {
 
517
  /*
 
518
    statement-based except for cases where only row-based can work (UUID()
 
519
    etc):
 
520
  */
 
521
  BINLOG_FORMAT_MIXED= 0,
 
522
  BINLOG_FORMAT_STMT= 1, // statement-based
 
523
  BINLOG_FORMAT_ROW= 2, // row_based
 
524
/*
 
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.
 
528
*/
 
529
  BINLOG_FORMAT_UNSPEC= 3
 
530
};
 
531
extern TYPELIB binlog_format_typelib;
 
532
 
 
533
#endif /* LOG_H */