~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/replication/binlog.cc

  • Committer: Brian Aker
  • Date: 2008-12-05 07:20:46 UTC
  • Revision ID: brian@tangent.org-20081205072046-kg4gs7zudeukbzlx
Remove unused (yet more)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2005-2006 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
15
 
 
16
#include <drizzled/server_includes.h>
 
17
#include <drizzled/replication/rli.h>
 
18
#include <drizzled/replication/binlog.h>
 
19
#include <mysys/base64.h>
 
20
#include <drizzled/error.h>
 
21
#include <drizzled/slave.h>
 
22
#include <drizzled/session.h>
 
23
 
 
24
/**
 
25
  Execute a BINLOG statement
 
26
 
 
27
  To execute the BINLOG command properly the server needs to know
 
28
  which format the BINLOG command's event is in.  Therefore, the first
 
29
  BINLOG statement seen must be a base64 encoding of the
 
30
  Format_description_log_event, as outputted by mysqlbinlog.  This
 
31
  Format_description_log_event is cached in
 
32
  rli->description_event_for_exec.
 
33
*/
 
34
 
 
35
void mysql_client_binlog_statement(Session* session)
 
36
{
 
37
  size_t coded_len= session->lex->comment.length + 1;
 
38
  size_t decoded_len= base64_needed_decoded_length(coded_len);
 
39
  assert(coded_len > 0);
 
40
 
 
41
  /*
 
42
    Allocation
 
43
  */
 
44
 
 
45
  /*
 
46
    If we do not have a Format_description_event, we create a dummy
 
47
    one here.  In this case, the first event we read must be a
 
48
    Format_description_event.
 
49
  */
 
50
  bool have_fd_event= true;
 
51
  if (!session->rli_fake)
 
52
  {
 
53
    session->rli_fake= new Relay_log_info;
 
54
#ifdef HAVE_purify
 
55
    session->rli_fake->is_fake= true;
 
56
#endif
 
57
    have_fd_event= false;
 
58
  }
 
59
  if (session->rli_fake && !session->rli_fake->relay_log.description_event_for_exec)
 
60
  {
 
61
    session->rli_fake->relay_log.description_event_for_exec=
 
62
      new Format_description_log_event(4);
 
63
    have_fd_event= false;
 
64
  }
 
65
 
 
66
  const char *error= 0;
 
67
  char *buf= (char *) malloc(decoded_len);
 
68
  Log_event *ev = 0;
 
69
 
 
70
  /*
 
71
    Out of memory check
 
72
  */
 
73
  if (!(session->rli_fake &&
 
74
        session->rli_fake->relay_log.description_event_for_exec &&
 
75
        buf))
 
76
  {
 
77
    my_error(ER_OUTOFMEMORY, MYF(0), 1);  /* needed 1 bytes */
 
78
    goto end;
 
79
  }
 
80
 
 
81
  session->rli_fake->sql_session= session;
 
82
  session->rli_fake->no_storage= true;
 
83
 
 
84
  for (char const *strptr= session->lex->comment.str ;
 
85
       strptr < session->lex->comment.str + session->lex->comment.length ; )
 
86
  {
 
87
    char const *endptr= 0;
 
88
    int bytes_decoded= base64_decode(strptr, coded_len, buf, &endptr);
 
89
 
 
90
    if (bytes_decoded < 0)
 
91
    {
 
92
      my_error(ER_BASE64_DECODE_ERROR, MYF(0));
 
93
      goto end;
 
94
    }
 
95
    else if (bytes_decoded == 0)
 
96
      break; // If no bytes where read, the string contained only whitespace
 
97
 
 
98
    assert(bytes_decoded > 0);
 
99
    assert(endptr > strptr);
 
100
    coded_len-= endptr - strptr;
 
101
    strptr= endptr;
 
102
 
 
103
    /*
 
104
      Now we have one or more events stored in the buffer. The size of
 
105
      the buffer is computed based on how much base64-encoded data
 
106
      there were, so there should be ample space for the data (maybe
 
107
      even too much, since a statement can consist of a considerable
 
108
      number of events).
 
109
 
 
110
      TODO: Switch to use a stream-based base64 encoder/decoder in
 
111
      order to be able to read exactly what is necessary.
 
112
    */
 
113
 
 
114
    /*
 
115
      Now we start to read events of the buffer, until there are no
 
116
      more.
 
117
    */
 
118
    for (char *bufptr= buf ; bytes_decoded > 0 ; )
 
119
    {
 
120
      /*
 
121
        Checking that the first event in the buffer is not truncated.
 
122
      */
 
123
      uint32_t event_len= uint4korr(bufptr + EVENT_LEN_OFFSET);
 
124
      if (bytes_decoded < EVENT_LEN_OFFSET || (uint) bytes_decoded < event_len)
 
125
      {
 
126
        my_error(ER_SYNTAX_ERROR, MYF(0));
 
127
        goto end;
 
128
      }
 
129
 
 
130
      /*
 
131
        If we have not seen any Format_description_event, then we must
 
132
        see one; it is the only statement that can be read in base64
 
133
        without a prior Format_description_event.
 
134
      */
 
135
      if (!have_fd_event)
 
136
      {
 
137
        int type = bufptr[EVENT_TYPE_OFFSET];
 
138
        if (type == FORMAT_DESCRIPTION_EVENT || type == START_EVENT_V3)
 
139
          have_fd_event= true;
 
140
        else
 
141
        {
 
142
          my_error(ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT,
 
143
                   MYF(0), Log_event::get_type_str((Log_event_type)type));
 
144
          goto end;
 
145
        }
 
146
      }
 
147
 
 
148
      ev= Log_event::read_log_event(bufptr, event_len, &error,
 
149
                                    session->rli_fake->relay_log.
 
150
                                      description_event_for_exec);
 
151
 
 
152
      if (!ev)
 
153
      {
 
154
        /*
 
155
          This could actually be an out-of-memory, but it is more likely
 
156
          causes by a bad statement
 
157
        */
 
158
        my_error(ER_SYNTAX_ERROR, MYF(0));
 
159
        goto end;
 
160
      }
 
161
 
 
162
      bytes_decoded -= event_len;
 
163
      bufptr += event_len;
 
164
 
 
165
      ev->session= session;
 
166
      /*
 
167
        We go directly to the application phase, since we don't need
 
168
        to check if the event shall be skipped or not.
 
169
 
 
170
        Neither do we have to update the log positions, since that is
 
171
        not used at all: the rli_fake instance is used only for error
 
172
        reporting.
 
173
      */
 
174
      if (apply_event_and_update_pos(ev, session, session->rli_fake, false))
 
175
      {
 
176
        /*
 
177
          TODO: Maybe a better error message since the BINLOG statement
 
178
          now contains several events.
 
179
        */
 
180
        my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
 
181
        goto end;
 
182
      }
 
183
 
 
184
      /*
 
185
        Format_description_log_event should not be deleted because it
 
186
        will be used to read info about the relay log's format; it
 
187
        will be deleted when the SQL thread does not need it,
 
188
        i.e. when this thread terminates.
 
189
      */
 
190
      if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
 
191
        delete ev;
 
192
      ev= 0;
 
193
    }
 
194
  }
 
195
 
 
196
  my_ok(session);
 
197
 
 
198
end:
 
199
  session->rli_fake->clear_tables_to_lock();
 
200
  free(buf);
 
201
  return;
 
202
}