~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/log.h

Moved the last of the libdrizzleclient calls into Protocol.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
5
 
 *
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.
9
 
 *
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.
14
 
 *
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
18
 
 */
19
 
 
20
 
#ifndef DRIZZLE_SERVER_LOG_H
21
 
#define DRIZZLE_SERVER_LOG_H
22
 
 
23
 
class Relay_log_info;
24
 
 
25
 
class Format_description_log_event;
26
 
 
27
 
/*
28
 
  Transaction Coordinator log - a base abstract class
29
 
  for two different implementations
30
 
*/
31
 
class TC_LOG
32
 
{
33
 
  public:
34
 
  int using_heuristic_recover();
35
 
  TC_LOG() {}
36
 
  virtual ~TC_LOG() {}
37
 
 
38
 
  virtual int open(const char *opt_name)=0;
39
 
  virtual void close()=0;
40
 
  virtual int log_xid(THD *thd, my_xid xid)=0;
41
 
  virtual void unlog(ulong cookie, my_xid xid)=0;
42
 
};
43
 
 
44
 
class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
45
 
{
46
 
public:
47
 
  TC_LOG_DUMMY() {}
48
 
  int open(const char *opt_name __attribute__((unused)))
49
 
  { return 0; }
50
 
  void close(void)                          { }
51
 
  int log_xid(THD *thd __attribute__((unused)),
52
 
              my_xid xid __attribute__((unused)))         { return 1; }
53
 
  void unlog(ulong cookie __attribute__((unused)),
54
 
             my_xid xid __attribute__((unused)))  { }
55
 
};
56
 
 
57
 
#ifdef HAVE_MMAP
58
 
class TC_LOG_MMAP: public TC_LOG
59
 
{
60
 
  public:                // only to keep Sun Forte on sol9x86 happy
61
 
  typedef enum {
62
 
    POOL,                 // page is in pool
63
 
    ERROR,                // last sync failed
64
 
    DIRTY                 // new xids added since last sync
65
 
  } PAGE_STATE;
66
 
 
67
 
  private:
68
 
  typedef struct st_page {
69
 
    struct st_page *next; // page a linked in a fifo queue
70
 
    my_xid *start, *end;  // usable area of a page
71
 
    my_xid *ptr;          // next xid will be written here
72
 
    int size, free;       // max and current number of free xid slots on the page
73
 
    int waiters;          // number of waiters on condition
74
 
    PAGE_STATE state;     // see above
75
 
    pthread_mutex_t lock; // to access page data or control structure
76
 
    pthread_cond_t  cond; // to wait for a sync
77
 
  } PAGE;
78
 
 
79
 
  char logname[FN_REFLEN];
80
 
  File fd;
81
 
  my_off_t file_length;
82
 
  uint32_t npages, inited;
83
 
  unsigned char *data;
84
 
  struct st_page *pages, *syncing, *active, *pool, *pool_last;
85
 
  /*
86
 
    note that, e.g. LOCK_active is only used to protect
87
 
    'active' pointer, to protect the content of the active page
88
 
    one has to use active->lock.
89
 
    Same for LOCK_pool and LOCK_sync
90
 
  */
91
 
  pthread_mutex_t LOCK_active, LOCK_pool, LOCK_sync;
92
 
  pthread_cond_t COND_pool, COND_active;
93
 
 
94
 
  public:
95
 
  TC_LOG_MMAP(): inited(0) {}
96
 
  int open(const char *opt_name);
97
 
  void close();
98
 
  int log_xid(THD *thd, my_xid xid);
99
 
  void unlog(ulong cookie, my_xid xid);
100
 
  int recover();
101
 
 
102
 
  private:
103
 
  void get_active_from_pool();
104
 
  int sync();
105
 
  int overflow();
106
 
};
107
 
#else
108
 
#define TC_LOG_MMAP TC_LOG_DUMMY
109
 
#endif
110
 
 
111
 
extern TC_LOG *tc_log;
112
 
extern TC_LOG_MMAP tc_log_mmap;
113
 
extern TC_LOG_DUMMY tc_log_dummy;
114
 
 
115
 
/* log info errors */
116
 
#define LOG_INFO_EOF -1
117
 
#define LOG_INFO_IO  -2
118
 
#define LOG_INFO_INVALID -3
119
 
#define LOG_INFO_SEEK -4
120
 
#define LOG_INFO_MEM -6
121
 
#define LOG_INFO_FATAL -7
122
 
#define LOG_INFO_IN_USE -8
123
 
#define LOG_INFO_EMFILE -9
124
 
 
125
 
 
126
 
/* bitmap to SQL_LOG::close() */
127
 
#define LOG_CLOSE_INDEX         1
128
 
#define LOG_CLOSE_TO_BE_OPENED  2
129
 
#define LOG_CLOSE_STOP_EVENT    4
130
 
 
131
 
class Relay_log_info;
132
 
 
133
 
typedef struct st_log_info
134
 
{
135
 
  char log_file_name[FN_REFLEN];
136
 
  my_off_t index_file_offset, index_file_start_offset;
137
 
  my_off_t pos;
138
 
  bool fatal; // if the purge happens to give us a negative offset
139
 
  pthread_mutex_t lock;
140
 
  st_log_info()
141
 
    : index_file_offset(0), index_file_start_offset(0),
142
 
      pos(0), fatal(0)
143
 
    {
144
 
      log_file_name[0] = '\0';
145
 
      pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);
146
 
    }
147
 
  ~st_log_info() { pthread_mutex_destroy(&lock);}
148
 
} LOG_INFO;
149
 
 
150
 
/*
151
 
  Currently we have only 3 kinds of logging functions: old-fashioned
152
 
  logs, stdout and csv logging routines.
153
 
*/
154
 
#define MAX_LOG_HANDLERS_NUM 3
155
 
 
156
 
/* log event handler flags */
157
 
#define LOG_NONE       1
158
 
#define LOG_FILE       2
159
 
 
160
 
class Log_event;
161
 
class Rows_log_event;
162
 
 
163
 
enum enum_log_type { LOG_UNKNOWN, LOG_NORMAL, LOG_BIN };
164
 
enum enum_log_state { LOG_OPENED, LOG_CLOSED, LOG_TO_BE_OPENED };
165
 
 
166
 
/*
167
 
  TODO use mmap instead of IO_CACHE for binlog
168
 
  (mmap+fsync is two times faster than write+fsync)
169
 
*/
170
 
 
171
 
class DRIZZLE_LOG
172
 
{
173
 
public:
174
 
  DRIZZLE_LOG();
175
 
  void init_pthread_objects();
176
 
  void cleanup();
177
 
  bool open(const char *log_name,
178
 
            enum_log_type log_type,
179
 
            const char *new_name,
180
 
            enum cache_type io_cache_type_arg);
181
 
  void init(enum_log_type log_type_arg,
182
 
            enum cache_type io_cache_type_arg);
183
 
  void close(uint32_t exiting);
184
 
  inline bool is_open() { return log_state != LOG_CLOSED; }
185
 
  const char *generate_name(const char *log_name, const char *suffix,
186
 
                            bool strip_ext, char *buff);
187
 
  int generate_new_name(char *new_name, const char *log_name);
188
 
 protected:
189
 
  /* LOCK_log is inited by init_pthread_objects() */
190
 
  pthread_mutex_t LOCK_log;
191
 
  char *name;
192
 
  char log_file_name[FN_REFLEN];
193
 
  char time_buff[20], db[NAME_LEN + 1];
194
 
  bool write_error, inited;
195
 
  IO_CACHE log_file;
196
 
  enum_log_type log_type;
197
 
  volatile enum_log_state log_state;
198
 
  enum cache_type io_cache_type;
199
 
  friend class Log_event;
200
 
};
201
 
 
202
 
class DRIZZLE_BIN_LOG: public TC_LOG, private DRIZZLE_LOG
203
 
{
204
 
 private:
205
 
  /* LOCK_log and LOCK_index are inited by init_pthread_objects() */
206
 
  pthread_mutex_t LOCK_index;
207
 
  pthread_mutex_t LOCK_prep_xids;
208
 
  pthread_cond_t  COND_prep_xids;
209
 
  pthread_cond_t update_cond;
210
 
  uint64_t bytes_written;
211
 
  IO_CACHE index_file;
212
 
  char index_file_name[FN_REFLEN];
213
 
  /*
214
 
     The max size before rotation (usable only if log_type == LOG_BIN: binary
215
 
     logs and relay logs).
216
 
     For a binlog, max_size should be max_binlog_size.
217
 
     For a relay log, it should be max_relay_log_size if this is non-zero,
218
 
     max_binlog_size otherwise.
219
 
     max_size is set in init(), and dynamically changed (when one does SET
220
 
     GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) by fix_max_binlog_size and
221
 
     fix_max_relay_log_size).
222
 
  */
223
 
  ulong max_size;
224
 
  long prepared_xids; /* for tc log - number of xids to remember */
225
 
  // current file sequence number for load data infile binary logging
226
 
  uint32_t file_id;
227
 
  uint32_t open_count;                          // For replication
228
 
  int readers_count;
229
 
  bool need_start_event;
230
 
  /*
231
 
    no_auto_events means we don't want any of these automatic events :
232
 
    Start/Rotate/Stop. That is, in 4.x when we rotate a relay log, we don't
233
 
    want a Rotate_log event to be written to the relay log. When we start a
234
 
    relay log etc. So in 4.x this is 1 for relay logs, 0 for binlogs.
235
 
    In 5.0 it's 0 for relay logs too!
236
 
  */
237
 
  bool no_auto_events;
238
 
 
239
 
  uint64_t m_table_map_version;
240
 
 
241
 
  int write_to_file(IO_CACHE *cache);
242
 
  /*
243
 
    This is used to start writing to a new log file. The difference from
244
 
    new_file() is locking. new_file_without_locking() does not acquire
245
 
    LOCK_log.
246
 
  */
247
 
  void new_file_without_locking();
248
 
  void new_file_impl(bool need_lock);
249
 
 
250
 
public:
251
 
  DRIZZLE_LOG::generate_name;
252
 
  DRIZZLE_LOG::is_open;
253
 
  /*
254
 
    These describe the log's format. This is used only for relay logs.
255
 
    _for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
256
 
    necessary to have 2 distinct objects, because the I/O thread may be reading
257
 
    events in a different format from what the SQL thread is reading (consider
258
 
    the case of a master which has been upgraded from 5.0 to 5.1 without doing
259
 
    RESET MASTER, or from 4.x to 5.0).
260
 
  */
261
 
  Format_description_log_event *description_event_for_exec,
262
 
    *description_event_for_queue;
263
 
 
264
 
  DRIZZLE_BIN_LOG();
265
 
  /*
266
 
    note that there's no destructor ~DRIZZLE_BIN_LOG() !
267
 
    The reason is that we don't want it to be automatically called
268
 
    on exit() - but only during the correct shutdown process
269
 
  */
270
 
 
271
 
  int open(const char *opt_name);
272
 
  void close();
273
 
  int log_xid(THD *thd, my_xid xid);
274
 
  void unlog(ulong cookie, my_xid xid);
275
 
  int recover(IO_CACHE *log, Format_description_log_event *fdle);
276
 
  bool is_table_mapped(Table *table) const
277
 
  {
278
 
    return table->s->table_map_version == table_map_version();
279
 
  }
280
 
 
281
 
  uint64_t table_map_version() const { return m_table_map_version; }
282
 
  void update_table_map_version() { ++m_table_map_version; }
283
 
 
284
 
  int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event);
285
 
 
286
 
  void reset_bytes_written()
287
 
  {
288
 
    bytes_written = 0;
289
 
  }
290
 
  void harvest_bytes_written(uint64_t* counter)
291
 
  {
292
 
    (*counter)+=bytes_written;
293
 
    bytes_written=0;
294
 
    return;
295
 
  }
296
 
  void set_max_size(ulong max_size_arg);
297
 
  void signal_update();
298
 
  void wait_for_update_relay_log(THD* thd);
299
 
  int  wait_for_update_bin_log(THD* thd, const struct timespec * timeout);
300
 
  void set_need_start_event() { need_start_event = 1; }
301
 
  void init(bool no_auto_events_arg, ulong max_size);
302
 
  void init_pthread_objects();
303
 
  void cleanup();
304
 
  bool open(const char *log_name,
305
 
            enum_log_type log_type,
306
 
            const char *new_name,
307
 
            enum cache_type io_cache_type_arg,
308
 
            bool no_auto_events_arg, ulong max_size,
309
 
            bool null_created);
310
 
  bool open_index_file(const char *index_file_name_arg,
311
 
                       const char *log_name);
312
 
  /* Use this to start writing a new log file */
313
 
  void new_file();
314
 
 
315
 
  bool write(Log_event* event_info); // binary log write
316
 
  bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event);
317
 
 
318
 
  int  write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync);
319
 
 
320
 
  void start_union_events(THD *thd, query_id_t query_id_param);
321
 
  void stop_union_events(THD *thd);
322
 
  bool is_query_in_union(THD *thd, query_id_t query_id_param);
323
 
 
324
 
  /*
325
 
    v stands for vector
326
 
    invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
327
 
  */
328
 
  bool appendv(const char* buf,uint32_t len,...);
329
 
  bool append(Log_event* ev);
330
 
 
331
 
  void make_log_name(char* buf, const char* log_ident);
332
 
  bool is_active(const char* log_file_name);
333
 
  int update_log_index(LOG_INFO* linfo, bool need_update_threads);
334
 
  void rotate_and_purge(uint32_t flags);
335
 
  bool flush_and_sync();
336
 
  int purge_logs(const char *to_log, bool included,
337
 
                 bool need_mutex, bool need_update_threads,
338
 
                 uint64_t *decrease_log_space);
339
 
  int purge_logs_before_date(time_t purge_time);
340
 
  int purge_first_log(Relay_log_info* rli, bool included);
341
 
  bool reset_logs(THD* thd);
342
 
  void close(uint32_t exiting);
343
 
 
344
 
  // iterating through the log index file
345
 
  int find_log_pos(LOG_INFO* linfo, const char* log_name,
346
 
                   bool need_mutex);
347
 
  int find_next_log(LOG_INFO* linfo, bool need_mutex);
348
 
  int get_current_log(LOG_INFO* linfo);
349
 
  int raw_get_current_log(LOG_INFO* linfo);
350
 
  uint32_t next_file_id();
351
 
  inline char* get_index_fname() { return index_file_name;}
352
 
  inline char* get_log_fname() { return log_file_name; }
353
 
  inline char* get_name() { return name; }
354
 
  inline pthread_mutex_t* get_log_lock() { return &LOCK_log; }
355
 
  inline IO_CACHE* get_log_file() { return &log_file; }
356
 
 
357
 
  inline void lock_index() { pthread_mutex_lock(&LOCK_index);}
358
 
  inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
359
 
  inline IO_CACHE *get_index_file() { return &index_file;}
360
 
  inline uint32_t get_open_count() { return open_count; }
361
 
};
362
 
 
363
 
class Log_event_handler
364
 
{
365
 
public:
366
 
  Log_event_handler() {}
367
 
  virtual bool init()= 0;
368
 
  virtual void cleanup()= 0;
369
 
 
370
 
  virtual bool log_error(enum loglevel level, const char *format,
371
 
                         va_list args)= 0;
372
 
  virtual ~Log_event_handler() {}
373
 
};
374
 
 
375
 
 
376
 
/* Class which manages slow, general and error log event handlers */
377
 
class LOGGER
378
 
{
379
 
  rw_lock_t LOCK_logger;
380
 
  /* flag to check whether logger mutex is initialized */
381
 
  uint32_t inited;
382
 
 
383
 
  /* NULL-terminated arrays of log handlers */
384
 
  Log_event_handler *error_log_handler_list[MAX_LOG_HANDLERS_NUM + 1];
385
 
 
386
 
public:
387
 
 
388
 
  LOGGER() : inited(0)
389
 
  {}
390
 
  void lock_shared() { rw_rdlock(&LOCK_logger); }
391
 
  void lock_exclusive() { rw_wrlock(&LOCK_logger); }
392
 
  void unlock() { rw_unlock(&LOCK_logger); }
393
 
  bool log_command(THD *thd, enum enum_server_command command);
394
 
 
395
 
  /*
396
 
    We want to initialize all log mutexes as soon as possible,
397
 
    but we cannot do it in constructor, as safe_mutex relies on
398
 
    initialization, performed by MY_INIT(). This why this is done in
399
 
    this function.
400
 
  */
401
 
  void init_base();
402
 
  bool flush_logs(THD *thd);
403
 
  /* Perform basic logger cleanup. this will leave e.g. error log open. */
404
 
  void cleanup_base();
405
 
  /* Free memory. Nothing could be logged after this function is called */
406
 
  void cleanup_end();
407
 
  bool error_log_print(enum loglevel level, const char *format,
408
 
                      va_list args);
409
 
  /* we use this function to setup all enabled log event handlers */
410
 
  int set_handlers(uint32_t error_log_printer);
411
 
  void init_error_log(uint32_t error_log_printer);
412
 
};
413
 
 
414
 
enum enum_binlog_format {
415
 
  /*
416
 
    statement-based except for cases where only row-based can work (UUID()
417
 
    etc):
418
 
  */
419
 
  BINLOG_FORMAT_MIXED= 0,
420
 
  BINLOG_FORMAT_STMT= 1, // statement-based
421
 
  BINLOG_FORMAT_ROW= 2, // row_based
422
 
/*
423
 
  This value is last, after the end of binlog_format_typelib: it has no
424
 
  corresponding cell in this typelib. We use this value to be able to know if
425
 
  the user has explicitely specified a binlog format at startup or not.
426
 
*/
427
 
  BINLOG_FORMAT_UNSPEC= 3
428
 
};
429
 
extern TYPELIB binlog_format_typelib;
430
 
 
431
 
int vprint_msg_to_log(enum loglevel level, const char *format, va_list args);
432
 
void sql_print_error(const char *format, ...) __attribute__((format(printf, 1, 2)));
433
 
void sql_print_warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
434
 
void sql_print_information(const char *format, ...)
435
 
  __attribute__((format(printf, 1, 2)));
436
 
typedef void (*sql_print_message_func)(const char *format, ...)
437
 
  __attribute__((format(printf, 1, 2)));
438
 
extern sql_print_message_func sql_print_message_handlers[];
439
 
 
440
 
int error_log_print(enum loglevel level, const char *format,
441
 
                    va_list args);
442
 
 
443
 
#endif /* DRIZZLE_SERVER_LOG_H */