~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/log.h

  • Committer: Brian Aker
  • Date: 2009-01-23 02:15:04 UTC
  • mfrom: (798.2.32 drizzle)
  • Revision ID: brian@tangent.org-20090123021504-2j99e6hxab1ew601
Merge for replication removal.

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
 
#include <drizzled/common.h>
24
 
#include <mysys/iocache.h>
25
 
#include <drizzled/xid.h>
26
 
 
27
 
class Table;
28
 
class Relay_log_info;
29
 
class Session;
30
 
class Format_description_log_event;
31
 
 
32
 
/*
33
 
  Transaction Coordinator log - a base abstract class
34
 
  for two different implementations
35
 
*/
36
 
class TC_LOG
37
 
{
38
 
  public:
39
 
  int using_heuristic_recover();
40
 
  TC_LOG() {}
41
 
  virtual ~TC_LOG() {}
42
 
 
43
 
  virtual int open(const char *opt_name)=0;
44
 
  virtual void close()=0;
45
 
  virtual int log_xid(Session *session, my_xid xid)=0;
46
 
  virtual void unlog(ulong cookie, my_xid xid)=0;
47
 
};
48
 
 
49
 
class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
50
 
{
51
 
public:
52
 
  TC_LOG_DUMMY() {}
53
 
  int open(const char *)
54
 
  { return 0; }
55
 
  void close(void)                          { }
56
 
  int log_xid(Session *, my_xid)         { return 1; }
57
 
  void unlog(ulong, my_xid)  { }
58
 
};
59
 
 
60
 
#ifdef HAVE_MMAP
61
 
class TC_LOG_MMAP: public TC_LOG
62
 
{
63
 
  public:                // only to keep Sun Forte on sol9x86 happy
64
 
  typedef enum {
65
 
    POOL,                 // page is in pool
66
 
    ERROR,                // last sync failed
67
 
    DIRTY                 // new xids added since last sync
68
 
  } PAGE_STATE;
69
 
 
70
 
  private:
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
80
 
  } PAGE;
81
 
 
82
 
  char logname[FN_REFLEN];
83
 
  File fd;
84
 
  my_off_t file_length;
85
 
  uint32_t npages, inited;
86
 
  unsigned char *data;
87
 
  struct st_page *pages, *syncing, *active, *pool, *pool_last;
88
 
  /*
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
93
 
  */
94
 
  pthread_mutex_t LOCK_active, LOCK_pool, LOCK_sync;
95
 
  pthread_cond_t COND_pool, COND_active;
96
 
 
97
 
  public:
98
 
  TC_LOG_MMAP(): inited(0) {}
99
 
  int open(const char *opt_name);
100
 
  void close();
101
 
  int log_xid(Session *session, my_xid xid);
102
 
  void unlog(ulong cookie, my_xid xid);
103
 
  int recover();
104
 
 
105
 
  private:
106
 
  void get_active_from_pool();
107
 
  int sync();
108
 
  int overflow();
109
 
};
110
 
#else
111
 
#define TC_LOG_MMAP TC_LOG_DUMMY
112
 
#endif
113
 
 
114
 
extern TC_LOG *tc_log;
115
 
extern TC_LOG_MMAP tc_log_mmap;
116
 
extern TC_LOG_DUMMY tc_log_dummy;
117
 
 
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
127
 
 
128
 
 
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
133
 
 
134
 
class Relay_log_info;
135
 
 
136
 
typedef struct st_log_info
137
 
{
138
 
  char log_file_name[FN_REFLEN];
139
 
  my_off_t index_file_offset, index_file_start_offset;
140
 
  my_off_t pos;
141
 
  bool fatal; // if the purge happens to give us a negative offset
142
 
  pthread_mutex_t lock;
143
 
  st_log_info()
144
 
    : index_file_offset(0), index_file_start_offset(0),
145
 
      pos(0), fatal(0)
146
 
    {
147
 
      log_file_name[0] = '\0';
148
 
      pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);
149
 
    }
150
 
  ~st_log_info() { pthread_mutex_destroy(&lock);}
151
 
} LOG_INFO;
152
 
 
153
 
/*
154
 
  Currently we have only 3 kinds of logging functions: old-fashioned
155
 
  logs, stdout and csv logging routines.
156
 
*/
157
 
#define MAX_LOG_HANDLERS_NUM 3
158
 
 
159
 
/* log event handler flags */
160
 
#define LOG_NONE       1
161
 
#define LOG_FILE       2
162
 
 
163
 
class Log_event;
164
 
class Rows_log_event;
165
 
 
166
 
enum enum_log_type { LOG_UNKNOWN, LOG_NORMAL, LOG_BIN };
167
 
enum enum_log_state { LOG_OPENED, LOG_CLOSED, LOG_TO_BE_OPENED };
168
 
 
169
 
/*
170
 
  TODO use mmap instead of IO_CACHE for binlog
171
 
  (mmap+fsync is two times faster than write+fsync)
172
 
*/
173
 
 
174
 
class DRIZZLE_LOG
175
 
{
176
 
public:
177
 
  DRIZZLE_LOG();
178
 
  void init_pthread_objects();
179
 
  void cleanup();
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);
191
 
 protected:
192
 
  /* LOCK_log is inited by init_pthread_objects() */
193
 
  pthread_mutex_t LOCK_log;
194
 
  char *name;
195
 
  char log_file_name[FN_REFLEN];
196
 
  char time_buff[20], db[NAME_LEN + 1];
197
 
  bool write_error, inited;
198
 
  IO_CACHE log_file;
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;
203
 
};
204
 
 
205
 
class DRIZZLE_BIN_LOG: public TC_LOG, private DRIZZLE_LOG
206
 
{
207
 
 private:
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;
214
 
  IO_CACHE index_file;
215
 
  char index_file_name[FN_REFLEN];
216
 
  /*
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).
225
 
  */
226
 
  ulong max_size;
227
 
  long prepared_xids; /* for tc log - number of xids to remember */
228
 
  // current file sequence number for load data infile binary logging
229
 
  uint32_t file_id;
230
 
  uint32_t open_count;                          // For replication
231
 
  int readers_count;
232
 
  bool need_start_event;
233
 
  /*
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!
239
 
  */
240
 
  bool no_auto_events;
241
 
 
242
 
  uint64_t m_table_map_version;
243
 
 
244
 
  int write_to_file(IO_CACHE *cache);
245
 
  /*
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
248
 
    LOCK_log.
249
 
  */
250
 
  void new_file_without_locking();
251
 
  void new_file_impl(bool need_lock);
252
 
 
253
 
public:
254
 
  DRIZZLE_LOG::generate_name;
255
 
  DRIZZLE_LOG::is_open;
256
 
  /*
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).
263
 
  */
264
 
  Format_description_log_event *description_event_for_exec,
265
 
    *description_event_for_queue;
266
 
 
267
 
  DRIZZLE_BIN_LOG();
268
 
  /*
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
272
 
  */
273
 
 
274
 
  int open(const char *opt_name);
275
 
  void close();
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;
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(Session *session, 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(Session* session);
299
 
  int  wait_for_update_bin_log(Session* session, 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(Session *session, 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(Session *session, query_id_t query_id_param);
321
 
  void stop_union_events(Session *session);
322
 
  bool is_query_in_union(Session *session, 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(Session* session);
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
 
 
364
 
File open_binlog(IO_CACHE *log, const char *log_file_name,
365
 
                 const char **errmsg);
366
 
 
367
 
class Log_event_handler
368
 
{
369
 
public:
370
 
  Log_event_handler() {}
371
 
  virtual bool init()= 0;
372
 
  virtual void cleanup()= 0;
373
 
 
374
 
  virtual bool log_error(enum loglevel level, const char *format,
375
 
                         va_list args)= 0;
376
 
  virtual ~Log_event_handler() {}
377
 
};
378
 
 
379
 
extern TYPELIB binlog_format_typelib;
380
 
 
381
 
#endif /* DRIZZLE_SERVER_LOG_H */