log_event.h
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:12k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16. #ifndef _LOG_EVENT_H
  17. #define _LOG_EVENT_H
  18. #ifdef __EMX__
  19. #undef write  // remove pthread.h macro definition, conflict with write() class member
  20. #endif
  21. #if defined(__GNUC__) && !defined(MYSQL_CLIENT)
  22. #pragma interface /* gcc class implementation */
  23. #endif
  24. #define LOG_READ_EOF    -1
  25. #define LOG_READ_BOGUS  -2
  26. #define LOG_READ_IO     -3
  27. #define LOG_READ_MEM    -5
  28. #define LOG_READ_TRUNC  -6
  29. #define LOG_READ_TOO_LARGE -7
  30. #define LOG_EVENT_OFFSET 4
  31. #define BINLOG_VERSION    1
  32. #define LOG_EVENT_HEADER_LEN 13
  33. #define QUERY_HEADER_LEN     (sizeof(uint32) + sizeof(uint32) + 
  34.  sizeof(uchar) + sizeof(uint16))
  35. #define LOAD_HEADER_LEN      (sizeof(uint32) + sizeof(uint32) + 
  36.   + sizeof(uint32) + 2 + sizeof(uint32))
  37. #define EVENT_LEN_OFFSET     9
  38. #define EVENT_TYPE_OFFSET    4
  39. #define QUERY_EVENT_OVERHEAD  (LOG_EVENT_HEADER_LEN+QUERY_HEADER_LEN)
  40. #define ROTATE_EVENT_OVERHEAD LOG_EVENT_HEADER_LEN
  41. #define LOAD_EVENT_OVERHEAD   (LOG_EVENT_HEADER_LEN+LOAD_HEADER_LEN+sizeof(sql_ex_info))
  42. #define BINLOG_MAGIC        "xfex62x69x6e"
  43. enum Log_event_type { START_EVENT = 1, QUERY_EVENT =2,
  44.       STOP_EVENT=3, ROTATE_EVENT = 4, INTVAR_EVENT=5,
  45.                       LOAD_EVENT=6};
  46. enum Int_event_type { INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
  47.  };
  48. #ifndef MYSQL_CLIENT
  49. class String;
  50. #endif
  51. extern uint32 server_id;
  52. class Log_event
  53. {
  54. public:
  55.   time_t when;
  56.   ulong exec_time;
  57.   int valid_exec_time; // if false, the exec time setting is bogus 
  58.   uint32 server_id;
  59.   static void *operator new(size_t size)
  60.   {
  61.     return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE));
  62.   }
  63.   static void operator delete(void *ptr, size_t size)
  64.   {
  65.     my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
  66.   }
  67.   
  68.   int write(IO_CACHE* file);
  69.   int write_header(IO_CACHE* file);
  70.   virtual int write_data(IO_CACHE* file __attribute__((unused))) { return 0; }
  71.   virtual Log_event_type get_type_code() = 0;
  72.   Log_event(time_t when_arg, ulong exec_time_arg = 0,
  73.     int valid_exec_time_arg = 0, uint32 server_id_arg = 0):
  74.     when(when_arg), exec_time(exec_time_arg),
  75.     valid_exec_time(valid_exec_time_arg)
  76.   {
  77.     server_id = server_id_arg ? server_id_arg : (::server_id);
  78.   }
  79.   Log_event(const char* buf): valid_exec_time(0)
  80.   {
  81.    when = uint4korr(buf);
  82.    server_id = uint4korr(buf + 5);
  83.   }
  84.   virtual ~Log_event() {}
  85.   virtual int get_data_size() { return 0;}
  86.   virtual void print(FILE* file, bool short_form = 0) = 0;
  87.   void print_timestamp(FILE* file, time_t *ts = 0);
  88.   void print_header(FILE* file);
  89.   // if mutex is 0, the read will proceed without mutex
  90.   static Log_event* read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock);
  91.   static Log_event* read_log_event(const char* buf, int event_len);
  92. #ifndef MYSQL_CLIENT
  93.   static int read_log_event(IO_CACHE* file, String* packet,
  94.     pthread_mutex_t* log_lock);
  95. #endif
  96.   
  97. };
  98. class Query_log_event: public Log_event
  99. {
  100. protected:
  101.   char* data_buf;
  102. public:
  103.   const char* query;
  104.   const char* db;
  105.   uint32 q_len; // if we already know the length of the query string
  106.   // we pass it here, so we would not have to call strlen()
  107.   // otherwise, set it to 0, in which case, we compute it with strlen()
  108.   uint32 db_len;
  109.   uint16 error_code;
  110.   ulong thread_id;
  111. #if !defined(MYSQL_CLIENT)
  112.   THD* thd;
  113.   bool cache_stmt;
  114.   Query_log_event(THD* thd_arg, const char* query_arg, bool using_trans=0):
  115.     Log_event(thd_arg->start_time,0,1,thd_arg->server_id), data_buf(0),
  116.     query(query_arg),  db(thd_arg->db), q_len(thd_arg->query_length),
  117.     error_code(thd_arg->net.last_errno),
  118.     thread_id(thd_arg->thread_id), thd(thd_arg),
  119.     cache_stmt(using_trans &&
  120.        (thd_arg->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)))
  121.   {
  122.     time_t end_time;
  123.     time(&end_time);
  124.     exec_time = (ulong) (end_time  - thd->start_time);
  125.     db_len = (db) ? (uint32) strlen(db) : 0;
  126.   }
  127. #endif
  128.   Query_log_event(IO_CACHE* file, time_t when, uint32 server_id_arg);
  129.   Query_log_event(const char* buf, int event_len);
  130.   ~Query_log_event()
  131.   {
  132.     if (data_buf)
  133.     {
  134.       my_free((gptr) data_buf, MYF(0));
  135.     }
  136.   }
  137.   Log_event_type get_type_code() { return QUERY_EVENT; }
  138.   int write(IO_CACHE* file);
  139.   int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
  140.   int get_data_size()
  141.   {
  142.     return q_len + db_len + 2 +
  143.       sizeof(uint32) // thread_id
  144.       + sizeof(uint32) // exec_time
  145.       + sizeof(uint16) // error_code
  146.       ;
  147.   }
  148.   void print(FILE* file, bool short_form = 0);
  149. };
  150. #define DUMPFILE_FLAG 0x1
  151. #define OPT_ENCLOSED_FLAG 0x2
  152. #define REPLACE_FLAG  0x4
  153. #define IGNORE_FLAG   0x8
  154. #define FIELD_TERM_EMPTY 0x1
  155. #define ENCLOSED_EMPTY   0x2
  156. #define LINE_TERM_EMPTY  0x4
  157. #define LINE_START_EMPTY 0x8
  158. #define ESCAPED_EMPTY    0x10
  159. struct sql_ex_info
  160.   {
  161.     char field_term;
  162.     char enclosed;
  163.     char line_term;
  164.     char line_start;
  165.     char escaped;
  166.     char opt_flags; // flags for the options
  167.     char empty_flags; // flags to indicate which of the terminating charact
  168.   } ;
  169. class Load_log_event: public Log_event
  170. {
  171. protected:
  172.   char* data_buf;
  173.   void copy_log_event(const char *buf, ulong data_len);
  174. public:
  175.   ulong thread_id;
  176.   uint32 table_name_len;
  177.   uint32 db_len;
  178.   uint32 fname_len;
  179.   uint32 num_fields;
  180.   const char* fields;
  181.   const uchar* field_lens;
  182.   uint32 field_block_len;
  183.   
  184.   const char* table_name;
  185.   const char* db;
  186.   const char* fname;
  187.   uint32 skip_lines;
  188.   sql_ex_info sql_ex;
  189.   
  190. #if !defined(MYSQL_CLIENT)
  191.   THD* thd;
  192.   String field_lens_buf;
  193.   String fields_buf;
  194.   Load_log_event(THD* thd, sql_exchange* ex, const char* table_name_arg,
  195.  List<Item>& fields_arg, enum enum_duplicates handle_dup ):
  196.     Log_event(thd->start_time),data_buf(0),thread_id(thd->thread_id),
  197.     num_fields(0),fields(0),field_lens(0),field_block_len(0),
  198.     table_name(table_name_arg),
  199.     db(thd->db),
  200.     fname(ex->file_name),
  201.     thd(thd)
  202.   {
  203.     time_t end_time;
  204.     time(&end_time);
  205.     exec_time = (ulong) (end_time  - thd->start_time);
  206.     valid_exec_time = 1;
  207.     db_len = (db) ? (uint32) strlen(db) : 0;
  208.     table_name_len = (table_name) ? (uint32) strlen(table_name) : 0;
  209.     fname_len = (fname) ? (uint) strlen(fname) : 0;
  210.     sql_ex.field_term = (*ex->field_term)[0];
  211.     sql_ex.enclosed = (*ex->enclosed)[0];
  212.     sql_ex.line_term = (*ex->line_term)[0];
  213.     sql_ex.line_start = (*ex->line_start)[0];
  214.     sql_ex.escaped = (*ex->escaped)[0];
  215.     sql_ex.opt_flags = 0;
  216.     if(ex->dumpfile)
  217.       sql_ex.opt_flags |= DUMPFILE_FLAG;
  218.     if(ex->opt_enclosed)
  219.       sql_ex.opt_flags |= OPT_ENCLOSED_FLAG;
  220.     sql_ex.empty_flags = 0;
  221.     switch(handle_dup)
  222.       {
  223.       case DUP_IGNORE: sql_ex.opt_flags |= IGNORE_FLAG; break;
  224.       case DUP_REPLACE: sql_ex.opt_flags |= REPLACE_FLAG; break;
  225.       case DUP_ERROR: break;
  226.       }
  227.     if(!ex->field_term->length())
  228.       sql_ex.empty_flags |= FIELD_TERM_EMPTY;
  229.     if(!ex->enclosed->length())
  230.       sql_ex.empty_flags |= ENCLOSED_EMPTY;
  231.     if(!ex->line_term->length())
  232.       sql_ex.empty_flags |= LINE_TERM_EMPTY;
  233.     if(!ex->line_start->length())
  234.       sql_ex.empty_flags |= LINE_START_EMPTY;
  235.     if(!ex->escaped->length())
  236.       sql_ex.empty_flags |= ESCAPED_EMPTY;
  237.     
  238.     skip_lines = ex->skip_lines;
  239.     List_iterator<Item> li(fields_arg);
  240.     field_lens_buf.length(0);
  241.     fields_buf.length(0);
  242.     Item* item;
  243.     while((item = li++))
  244.       {
  245. num_fields++;
  246. uchar len = (uchar) strlen(item->name);
  247. field_block_len += len + 1;
  248. fields_buf.append(item->name, len + 1);
  249. field_lens_buf.append((char*)&len, 1);
  250.       }
  251.     field_lens = (const uchar*)field_lens_buf.ptr();
  252.     fields = fields_buf.ptr();
  253.   }
  254.   void set_fields(List<Item> &fields_arg);
  255. #endif
  256.   Load_log_event(IO_CACHE * file, time_t when, uint32 server_id_arg);
  257.   Load_log_event(const char* buf, int event_len);
  258.   ~Load_log_event()
  259.   {
  260.     if (data_buf)
  261.     {
  262.       my_free((gptr) data_buf, MYF(0));
  263.     }
  264.   }
  265.   Log_event_type get_type_code() { return LOAD_EVENT; }
  266.   int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
  267.   int get_data_size()
  268.   {
  269.     return table_name_len + 2 + db_len + 2 + fname_len
  270.       + 4 // thread_id
  271.       + 4 // exec_time
  272.       + 4 // skip_lines
  273.       + 4 // field block len
  274.       + sizeof(sql_ex) + field_block_len + num_fields*sizeof(uchar) ;
  275.       ;
  276.   }
  277.   void print(FILE* file, bool short_form = 0);
  278. };
  279. extern char server_version[SERVER_VERSION_LENGTH];
  280. class Start_log_event: public Log_event
  281. {
  282. public:
  283.   uint32 created;
  284.   uint16 binlog_version;
  285.   char server_version[50];
  286.   
  287.   Start_log_event() :Log_event(time(NULL)),binlog_version(BINLOG_VERSION)
  288.   {
  289.     created = (uint32) when;
  290.     memcpy(server_version, ::server_version, sizeof(server_version));
  291.   }
  292.   Start_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id_arg) :
  293.     Log_event(when_arg, 0, 0, server_id_arg)
  294.   {
  295.     char buf[sizeof(server_version) + 2 + 4 + 4];
  296.     if (my_b_read(file, (byte*) buf, sizeof(buf)))
  297.       return;
  298.     binlog_version = uint2korr(buf+4);
  299.     memcpy(server_version, buf + 6, sizeof(server_version));
  300.     server_version[sizeof(server_version)-1]=0;
  301.     created = uint4korr(buf + 6 + sizeof(server_version));
  302.   }
  303.   Start_log_event(const char* buf);
  304.   
  305.   ~Start_log_event() {}
  306.   Log_event_type get_type_code() { return START_EVENT;}
  307.   int write_data(IO_CACHE* file);
  308.   int get_data_size()
  309.   {
  310.     // sizeof(binlog_version) + sizeof(server_version) sizeof(created)
  311.     return 2 + sizeof(server_version) + 4;
  312.   }
  313.   void print(FILE* file, bool short_form = 0);
  314. };
  315. class Intvar_log_event: public Log_event
  316. {
  317. public:
  318.   ulonglong val;
  319.   uchar type;
  320.   Intvar_log_event(uchar type_arg, ulonglong val_arg)
  321.     :Log_event(time(NULL)),val(val_arg),type(type_arg)
  322.   {}
  323.   Intvar_log_event(IO_CACHE* file, time_t when, uint32 server_id_arg);
  324.   Intvar_log_event(const char* buf);
  325.   ~Intvar_log_event() {}
  326.   Log_event_type get_type_code() { return INTVAR_EVENT;}
  327.   int get_data_size() { return  sizeof(type) + sizeof(val);}
  328.   int write_data(IO_CACHE* file);
  329.   
  330.   
  331.   void print(FILE* file, bool short_form = 0);
  332. };
  333. class Stop_log_event: public Log_event
  334. {
  335. public:
  336.   Stop_log_event() :Log_event(time(NULL))
  337.   {}
  338.   Stop_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id_arg):
  339.     Log_event(when_arg,0,0,server_id_arg)
  340.   {
  341.     byte skip[4];
  342.     my_b_read(file, skip, sizeof(skip)); // skip the event length
  343.   }
  344.   Stop_log_event(const char* buf):Log_event(buf)
  345.   {
  346.   }
  347.   ~Stop_log_event() {}
  348.   Log_event_type get_type_code() { return STOP_EVENT;}
  349.   void print(FILE* file, bool short_form = 0);
  350. };
  351. class Rotate_log_event: public Log_event
  352. {
  353. public:
  354.   const char* new_log_ident;
  355.   uchar ident_len;
  356.   bool alloced;
  357.   
  358.   Rotate_log_event(const char* new_log_ident_arg, uint ident_len_arg = 0) :
  359.     Log_event(time(NULL)),
  360.     new_log_ident(new_log_ident_arg),
  361.     ident_len(ident_len_arg ? ident_len_arg : (uint) strlen(new_log_ident_arg)),
  362.     alloced(0)
  363.   {}
  364.   
  365.   Rotate_log_event(IO_CACHE* file, time_t when, uint32 server_id_arg) ;
  366.   Rotate_log_event(const char* buf, int event_len);
  367.   ~Rotate_log_event()
  368.   {
  369.     if (alloced)
  370.       my_free((gptr) new_log_ident, MYF(0));
  371.   }
  372.   Log_event_type get_type_code() { return ROTATE_EVENT;}
  373.   int get_data_size() { return  ident_len;}
  374.   int write_data(IO_CACHE* file);
  375.   
  376.   void print(FILE* file, bool short_form = 0);
  377. };
  378. #endif