1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
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.
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.
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
20
#include <drizzled/server_includes.h>
21
#include <drizzled/log_event.h>
22
#include <drizzled/replication/rli.h>
23
#include <drizzled/replication/mi.h>
24
#include <drizzled/replication/filter.h>
25
#include <drizzled/replication/utility.h>
26
#include <drizzled/replication/record.h>
1
/* Copyright (C) 2000-2004 MySQL AB
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.
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.
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 */
19
#include "mysql_priv.h"
23
#ifdef USE_PRAGMA_IMPLEMENTATION
24
#pragma implementation // gcc: Class implementation
27
#include "mysql_priv.h"
31
#include "rpl_filter.h"
32
#include "rpl_utility.h"
33
#include "rpl_record.h"
27
34
#include <mysys/my_dir.h>
28
#include <drizzled/error.h>
29
#include <libdrizzle/pack.h>
30
#include <drizzled/sql_parse.h>
31
#include <drizzled/sql_base.h>
32
#include <drizzled/sql_load.h>
35
#include <drizzled/drizzled_error_messages.h>
37
#endif /* MYSQL_CLIENT */
36
39
#include <mysys/base64.h>
37
40
#include <mysys/my_bitmap.h>
39
#include <drizzled/gettext.h>
40
#include <libdrizzle/libdrizzle.h>
41
#include <drizzled/error.h>
42
#include <drizzled/query_id.h>
43
#include <drizzled/tztime.h>
44
#include <drizzled/slave.h>
42
#define log_cs &my_charset_latin1
44
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
48
Size of buffer for printing a double in format %.<PREC>g
50
optional '-' + optional zero + '.' + PREC digits + 'e' + sign +
51
exponent digits + '\0'
53
#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
56
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
47
57
static const char *HA_ERR(int i)
117
127
static void inline slave_rows_error_report(enum loglevel level, int ha_error,
118
Relay_log_info const *rli, Session *session,
119
Table *table, const char * type,
128
Relay_log_info const *rli, THD *thd,
129
TABLE *table, const char * type,
120
130
const char *log_name, ulong pos)
122
132
const char *handler_error= HA_ERR(ha_error);
123
133
char buff[MAX_SLAVE_ERRMSG], *slider;
124
134
const char *buff_end= buff + sizeof(buff);
126
List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
136
List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
130
140
for (err= it++, slider= buff; err && slider < buff_end - 1;
131
141
slider += len, err= it++)
133
143
len= snprintf(slider, buff_end - slider,
134
_(" %s, Error_code: %d;"), err->msg, err->code);
144
" %s, Error_code: %d;", err->msg, err->code);
137
rli->report(level, session->is_error()? session->main_da.sql_errno() : 0,
138
_("Could not execute %s event on table %s.%s;"
139
"%s handler error %s; "
140
"the event's master log %s, end_log_pos %lu"),
147
rli->report(level, thd->is_error()? thd->main_da.sql_errno() : 0,
148
"Could not execute %s event on table %s.%s;"
149
"%s handler error %s; "
150
"the event's master log %s, end_log_pos %lu",
141
151
type, table->s->db.str,
142
152
table->s->table_name.str,
144
handler_error == NULL? _("<unknown>") : handler_error,
154
handler_error == NULL? "<unknown>" : handler_error,
150
160
Cache that will automatically be written to a dedicated file on
224
234
flag_set m_flags;
227
uint32_t debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
237
uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
230
240
pretty_print_str()
233
static void clear_all_errors(Session *session, Relay_log_info *rli)
235
session->is_slave_error = 0;
236
session->clear_error();
244
static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
246
const char* end = str + len;
247
my_b_printf(cache, "\'");
251
switch ((c=*str++)) {
252
case '\n': my_b_printf(cache, "\\n"); break;
253
case '\r': my_b_printf(cache, "\\r"); break;
254
case '\\': my_b_printf(cache, "\\\\"); break;
255
case '\b': my_b_printf(cache, "\\b"); break;
256
case '\t': my_b_printf(cache, "\\t"); break;
257
case '\'': my_b_printf(cache, "\\'"); break;
258
case 0 : my_b_printf(cache, "\\0"); break;
260
my_b_printf(cache, "%c", c);
264
my_b_printf(cache, "\'");
266
#endif /* MYSQL_CLIENT */
268
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
270
static void clear_all_errors(THD *thd, Relay_log_info *rli)
272
thd->is_slave_error = 0;
237
274
rli->clear_error();
1051
1148
if (!ev || !ev->is_valid())
1152
if (!force_opt) /* then mysqlbinlog dies */
1154
*error= "Found invalid event in binary log";
1157
ev= new Unknown_log_event(buf, description_event);
1054
1159
*error= "Found invalid event in binary log";
1169
Log_event::print_header()
1172
void Log_event::print_header(IO_CACHE* file,
1173
PRINT_EVENT_INFO* print_event_info,
1174
bool is_more __attribute__((unused)))
1177
my_off_t hexdump_from= print_event_info->hexdump_from;
1179
my_b_printf(file, "#");
1180
print_timestamp(file);
1181
my_b_printf(file, " server id %d end_log_pos %s ", server_id,
1182
llstr(log_pos,llbuff));
1184
/* mysqlbinlog --hexdump */
1185
if (print_event_info->hexdump_from)
1187
my_b_printf(file, "\n");
1188
uchar *ptr= (uchar*)temp_buf;
1190
uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
1193
/* Header len * 4 >= header len * (2 chars + space + extra space) */
1194
char *h, hex_string[LOG_EVENT_MINIMAL_HEADER_LEN*4]= {0};
1195
char *c, char_string[16+1]= {0};
1197
/* Pretty-print event common header if header is exactly 19 bytes */
1198
if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
1200
char emit_buf[256]; // Enough for storing one line
1201
my_b_printf(file, "# Position Timestamp Type Master ID "
1202
"Size Master Pos Flags \n");
1203
int const bytes_written=
1204
snprintf(emit_buf, sizeof(emit_buf),
1205
"# %8.8lx %02x %02x %02x %02x %02x "
1206
"%02x %02x %02x %02x %02x %02x %02x %02x "
1207
"%02x %02x %02x %02x %02x %02x\n",
1208
(unsigned long) hexdump_from,
1209
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
1210
ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1211
ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
1212
assert(bytes_written >= 0);
1213
assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1214
my_b_write(file, (uchar*) emit_buf, bytes_written);
1215
ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
1216
hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
1219
/* Rest of event (without common header) */
1220
for (i= 0, c= char_string, h=hex_string;
1224
snprintf(h, 4, "%02x ", *ptr);
1227
*c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
1232
my_b_printf() does not support full printf() formats, so we
1233
have to do it this way.
1235
TODO: Rewrite my_b_printf() to support full printf() syntax.
1238
int const bytes_written=
1239
snprintf(emit_buf, sizeof(emit_buf),
1240
"# %8.8lx %-48.48s |%16s|\n",
1241
(unsigned long) (hexdump_from + (i & 0xfffffff0)),
1242
hex_string, char_string);
1243
assert(bytes_written >= 0);
1244
assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1245
my_b_write(file, (uchar*) emit_buf, bytes_written);
1251
else if (i % 8 == 7) *h++ = ' ';
1258
int const bytes_written=
1259
snprintf(emit_buf, sizeof(emit_buf),
1260
"# %8.8lx %-48.48s |%s|\n",
1261
(unsigned long) (hexdump_from + (i & 0xfffffff0)),
1262
hex_string, char_string);
1263
assert(bytes_written >= 0);
1264
assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1265
my_b_write(file, (uchar*) emit_buf, bytes_written);
1268
need a # to prefix the rest of printouts for example those of
1269
Rows_log_event::print_helper().
1271
my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
1277
void Log_event::print_base64(IO_CACHE* file,
1278
PRINT_EVENT_INFO* print_event_info,
1281
const uchar *ptr= (const uchar *)temp_buf;
1282
uint32_t size= uint4korr(ptr + EVENT_LEN_OFFSET);
1284
size_t const tmp_str_sz= base64_needed_encoded_length((int) size);
1285
char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
1287
fprintf(stderr, "\nError: Out of memory. "
1288
"Could not print correct binlog event.\n");
1292
if (base64_encode(ptr, (size_t) size, tmp_str))
1297
if (my_b_tell(file) == 0)
1298
my_b_printf(file, "\nBINLOG '\n");
1300
my_b_printf(file, "%s\n", tmp_str);
1303
my_b_printf(file, "'%s\n", print_event_info->delimiter);
1305
my_free(tmp_str, MYF(0));
1311
Log_event::print_timestamp()
1314
void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
1319
#ifdef MYSQL_SERVER // This is always false
1321
localtime_r(ts,(res= &tm_tmp));
1326
my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
1336
#endif /* MYSQL_CLIENT */
1339
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
1060
1340
inline Log_event::enum_skip_reason
1061
1341
Log_event::continue_group(Relay_log_info *rli)
1187
1486
int4store(start, flags2);
1489
if (sql_mode_inited)
1491
*start++= Q_SQL_MODE_CODE;
1492
int8store(start, (uint64_t)sql_mode);
1495
if (catalog_len) // i.e. this var is inited (false for 4.0 events)
1497
write_str_with_code_and_len((char **)(&start),
1498
catalog, catalog_len, Q_CATALOG_NZ_CODE);
1500
In 5.0.x where x<4 masters we used to store the end zero here. This was
1501
a waste of one byte so we don't do it in x>=4 masters. We change code to
1502
Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
1503
of this x>=4 master segfault (expecting a zero when there is
1504
none). Remaining compatibility problems are: the older slave will not
1505
find the catalog; but it is will not crash, and it's not an issue
1506
that it does not find the catalog as catalogs were not used in these
1507
older MySQL versions (we store it in binlog and read it from relay log
1508
but do nothing useful with it). What is an issue is that the older slave
1509
will stop processing the Q_* blocks (and jumps to the db/query) as soon
1510
as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
1511
Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
1512
various ways. Documented that you should not mix alpha/beta versions if
1513
they are not exactly the same version, with example of 5.0.3->5.0.2 and
1514
5.0.4->5.0.3. If replication is from older to new, the new will
1515
recognize Q_CATALOG_CODE and have no problem.
1518
if (auto_increment_increment != 1 || auto_increment_offset != 1)
1520
*start++= Q_AUTO_INCREMENT;
1521
int2store(start, auto_increment_increment);
1522
int2store(start+2, auto_increment_offset);
1527
*start++= Q_CHARSET_CODE;
1528
memcpy(start, charset, 6);
1533
/* In the TZ sys table, column Name is of length 64 so this should be ok */
1534
assert(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
1535
*start++= Q_TIME_ZONE_CODE;
1536
*start++= time_zone_len;
1537
memcpy(start, time_zone_str, time_zone_len);
1538
start+= time_zone_len;
1190
1540
if (lc_time_names_number)
1192
1542
assert(lc_time_names_number <= 0xFFFF);
1247
1597
Query_log_event::Query_log_event()
1248
session_arg - thread handle
1598
thd_arg - thread handle
1249
1599
query_arg - array of char representing the query
1250
1600
query_length - size of the `query_arg' array
1251
1601
using_trans - there is a modified transactional table
1252
1602
suppress_use - suppress the generation of 'USE' statements
1253
killed_status_arg - an optional with default to Session::KILLED_NO_VALUE
1603
killed_status_arg - an optional with default to THD::KILLED_NO_VALUE
1254
1604
if the value is different from the default, the arg
1255
is set to the current session->killed value.
1256
A caller might need to masquerade session->killed with
1257
Session::NOT_KILLED.
1605
is set to the current thd->killed value.
1606
A caller might need to masquerade thd->killed with
1259
1609
Creates an event for binlogging
1260
1610
The value for local `killed_status' can be supplied by caller.
1262
Query_log_event::Query_log_event(Session* session_arg, const char* query_arg,
1263
ulong query_length, bool using_trans,
1265
Session::killed_state killed_status_arg)
1266
:Log_event(session_arg,
1267
(session_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0) |
1268
(suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
1270
data_buf(0), query(query_arg), catalog(session_arg->catalog),
1271
db(session_arg->db), q_len((uint32_t) query_length),
1272
thread_id(session_arg->thread_id),
1273
/* save the original thread id; we already know the server id */
1274
slave_proxy_id(session_arg->variables.pseudo_thread_id),
1275
flags2_inited(1), sql_mode_inited(1), charset_inited(1),
1277
auto_increment_increment(session_arg->variables.auto_increment_increment),
1278
auto_increment_offset(session_arg->variables.auto_increment_offset),
1279
lc_time_names_number(session_arg->variables.lc_time_names->number),
1612
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
1613
ulong query_length, bool using_trans,
1615
THD::killed_state killed_status_arg)
1617
(thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
1619
(suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
1621
data_buf(0), query(query_arg), catalog(thd_arg->catalog),
1622
db(thd_arg->db), q_len((uint32_t) query_length),
1623
thread_id(thd_arg->thread_id),
1624
/* save the original thread id; we already know the server id */
1625
slave_proxy_id(thd_arg->variables.pseudo_thread_id),
1626
flags2_inited(1), sql_mode_inited(1), charset_inited(1),
1628
auto_increment_increment(thd_arg->variables.auto_increment_increment),
1629
auto_increment_offset(thd_arg->variables.auto_increment_offset),
1630
lc_time_names_number(thd_arg->variables.lc_time_names->number),
1280
1631
charset_database_number(0)
1282
1633
time_t end_time;
1284
if (killed_status_arg == Session::KILLED_NO_VALUE)
1285
killed_status_arg= session_arg->killed;
1635
if (killed_status_arg == THD::KILLED_NO_VALUE)
1636
killed_status_arg= thd_arg->killed;
1288
(killed_status_arg == Session::NOT_KILLED) ?
1289
(session_arg->is_error() ? session_arg->main_da.sql_errno() : 0) :
1290
(session_arg->killed_errno());
1639
(killed_status_arg == THD::NOT_KILLED) ?
1640
(thd_arg->is_error() ? thd_arg->main_da.sql_errno() : 0) :
1641
(thd_arg->killed_errno());
1292
1643
time(&end_time);
1293
exec_time = (ulong) (end_time - session_arg->start_time);
1644
exec_time = (ulong) (end_time - thd_arg->start_time);
1295
1646
@todo this means that if we have no catalog, then it is replicated
1296
1647
as an existing catalog of length zero. is that safe? /sven
1298
1649
catalog_len = (catalog) ? (uint32_t) strlen(catalog) : 0;
1299
1650
/* status_vars_len is set just before writing the event */
1300
1651
db_len = (db) ? (uint32_t) strlen(db) : 0;
1301
if (session_arg->variables.collation_database != session_arg->db_charset)
1302
charset_database_number= session_arg->variables.collation_database->number;
1652
if (thd_arg->variables.collation_database != thd_arg->db_charset)
1653
charset_database_number= thd_arg->variables.collation_database->number;
1305
1656
If we don't use flags2 for anything else than options contained in
1306
session_arg->options, it would be more efficient to flags2=session_arg->options
1657
thd_arg->options, it would be more efficient to flags2=thd_arg->options
1307
1658
(OPTIONS_WRITTEN_TO_BIN_LOG would be used only at reading time).
1308
1659
But it's likely that we don't want to use 32 bits for 3 bits; in the future
1309
1660
we will probably want to reclaim the 29 bits. So we need the &.
1311
flags2= (uint32_t) (session_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
1312
assert(session_arg->variables.character_set_client->number < 256*256);
1313
assert(session_arg->variables.collation_connection->number < 256*256);
1314
assert(session_arg->variables.collation_server->number < 256*256);
1315
assert(session_arg->variables.character_set_client->mbminlen == 1);
1316
int2store(charset, session_arg->variables.character_set_client->number);
1317
int2store(charset+2, session_arg->variables.collation_connection->number);
1318
int2store(charset+4, session_arg->variables.collation_server->number);
1662
flags2= (uint32_t) (thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
1663
assert(thd_arg->variables.character_set_client->number < 256*256);
1664
assert(thd_arg->variables.collation_connection->number < 256*256);
1665
assert(thd_arg->variables.collation_server->number < 256*256);
1666
assert(thd_arg->variables.character_set_client->mbminlen == 1);
1667
int2store(charset, thd_arg->variables.character_set_client->number);
1668
int2store(charset+2, thd_arg->variables.collation_connection->number);
1669
int2store(charset+4, thd_arg->variables.collation_server->number);
1670
if (thd_arg->time_zone_used)
1673
Note that our event becomes dependent on the Time_zone object
1674
representing the time zone. Fortunately such objects are never deleted
1675
or changed during mysqld's lifetime.
1677
time_zone_len= thd_arg->variables.time_zone->get_name()->length();
1678
time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
1683
#endif /* MYSQL_CLIENT */
1686
/* 2 utility functions for the next method */
1689
Read a string with length from memory.
1691
This function reads the string-with-length stored at
1692
<code>src</code> and extract the length into <code>*len</code> and
1693
a pointer to the start of the string into <code>*dst</code>. The
1694
string can then be copied using <code>memcpy()</code> with the
1695
number of bytes given in <code>*len</code>.
1697
@param src Pointer to variable holding a pointer to the memory to
1698
read the string from.
1699
@param dst Pointer to variable holding a pointer where the actual
1700
string starts. Starting from this position, the string
1701
can be copied using @c memcpy().
1702
@param len Pointer to variable where the length will be stored.
1703
@param end One-past-the-end of the memory where the string is
1706
@return Zero if the entire string can be copied successfully,
1707
@c UINT_MAX if the length could not be read from memory
1708
(that is, if <code>*src >= end</code>), otherwise the
1709
number of bytes that are missing to read the full
1710
string, which happends <code>*dst + *len >= end</code>.
1713
get_str_len_and_pointer(const Log_event::Byte **src,
1716
const Log_event::Byte *end)
1719
return -1; // Will be UINT_MAX in two-complement arithmetics
1723
if (*src + length >= end)
1724
return *src + length - end + 1; // Number of bytes missing
1725
*dst= (char *)*src + 1; // Will be copied later
1322
1732
static void copy_str_and_move(const char **src,
1323
1733
Log_event::Byte **dst,
1326
1736
memcpy(*dst, *src, len);
1327
1737
*src= (const char *)*dst;
1945
Query_log_event::print().
1948
print the catalog ??
1950
void Query_log_event::print_query_header(IO_CACHE* file,
1951
PRINT_EVENT_INFO* print_event_info)
1953
// TODO: print the catalog ??
1954
char buff[40],*end; // Enough for SET TIMESTAMP
1955
bool different_db= 1;
1958
if (!print_event_info->short_form)
1960
print_header(file, print_event_info, false);
1961
my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
1962
get_type_str(), (ulong) thread_id, (ulong) exec_time,
1966
if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db)
1968
if ((different_db= memcmp(print_event_info->db, db, db_len + 1)))
1969
memcpy(print_event_info->db, db, db_len + 1);
1970
if (db[0] && different_db)
1971
my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
1974
end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
1975
end= strmov(end, print_event_info->delimiter);
1977
my_b_write(file, (uchar*) buff, (uint) (end-buff));
1978
if ((!print_event_info->thread_id_printed ||
1979
((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
1980
thread_id != print_event_info->thread_id)))
1982
// If --short-form, print deterministic value instead of pseudo_thread_id.
1983
my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
1984
short_form ? 999999999 : (ulong)thread_id,
1985
print_event_info->delimiter);
1986
print_event_info->thread_id= thread_id;
1987
print_event_info->thread_id_printed= 1;
1991
If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
1992
print (remember we don't produce mixed relay logs so there cannot be
1993
5.0 events before that one so there is nothing to reset).
1995
if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
1997
/* tmp is a bitmask of bits which have changed. */
1998
if (likely(print_event_info->flags2_inited))
1999
/* All bits which have changed */
2000
tmp= (print_event_info->flags2) ^ flags2;
2001
else /* that's the first Query event we read */
2003
print_event_info->flags2_inited= 1;
2004
tmp= ~((uint32_t)0); /* all bits have changed */
2007
if (unlikely(tmp)) /* some bits have changed */
2010
my_b_printf(file, "SET ");
2011
print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
2012
"@@session.foreign_key_checks", &need_comma);
2013
print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
2014
"@@session.sql_auto_is_null", &need_comma);
2015
print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
2016
"@@session.unique_checks", &need_comma);
2017
my_b_printf(file,"%s\n", print_event_info->delimiter);
2018
print_event_info->flags2= flags2;
2023
Now the session variables;
2024
it's more efficient to pass SQL_MODE as a number instead of a
2025
comma-separated list.
2026
FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
2027
variables (they have no global version; they're not listed in
2028
sql_class.h), The tests below work for pure binlogs or pure relay
2029
logs. Won't work for mixed relay logs but we don't create mixed
2030
relay logs (that is, there is no relay log with a format change
2031
except within the 3 first events, which mysqlbinlog handles
2032
gracefully). So this code should always be good.
2035
if (print_event_info->auto_increment_increment != auto_increment_increment ||
2036
print_event_info->auto_increment_offset != auto_increment_offset)
2038
my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
2039
auto_increment_increment,auto_increment_offset,
2040
print_event_info->delimiter);
2041
print_event_info->auto_increment_increment= auto_increment_increment;
2042
print_event_info->auto_increment_offset= auto_increment_offset;
2045
/* TODO: print the catalog when we feature SET CATALOG */
2047
if (likely(charset_inited) &&
2048
(unlikely(!print_event_info->charset_inited ||
2049
memcmp((uchar*) print_event_info->charset, (uchar*) charset, 6))))
2051
CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
2054
/* for mysql client */
2055
my_b_printf(file, "/*!\\C %s */%s\n",
2056
cs_info->csname, print_event_info->delimiter);
2058
my_b_printf(file,"SET "
2059
"@@session.character_set_client=%d,"
2060
"@@session.collation_connection=%d,"
2061
"@@session.collation_server=%d"
2064
uint2korr(charset+2),
2065
uint2korr(charset+4),
2066
print_event_info->delimiter);
2067
memcpy(print_event_info->charset, charset, 6);
2068
print_event_info->charset_inited= 1;
2072
if (memcmp((uchar*) print_event_info->time_zone_str,
2073
(uchar*) time_zone_str, time_zone_len+1))
2075
my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
2076
time_zone_str, print_event_info->delimiter);
2077
memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
2080
if (lc_time_names_number != print_event_info->lc_time_names_number)
2082
my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
2083
lc_time_names_number, print_event_info->delimiter);
2084
print_event_info->lc_time_names_number= lc_time_names_number;
2086
if (charset_database_number != print_event_info->charset_database_number)
2088
if (charset_database_number)
2089
my_b_printf(file, "SET @@session.collation_database=%d%s\n",
2090
charset_database_number, print_event_info->delimiter);
2092
my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
2093
print_event_info->delimiter);
2094
print_event_info->charset_database_number= charset_database_number;
2099
void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
2101
Write_on_release_cache cache(&print_event_info->head_cache, file);
2103
print_query_header(&cache, print_event_info);
2104
my_b_write(&cache, (uchar*) query, q_len);
2105
my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
2107
#endif /* MYSQL_CLIENT */
1488
2111
Query_log_event::do_apply_event()
2114
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
1490
2116
int Query_log_event::do_apply_event(Relay_log_info const *rli)
1492
2118
return do_apply_event(rli, query, q_len);
1555
2180
::do_apply_event(), then the companion SET also have so
1556
2181
we don't need to reset_one_shot_variables().
1558
if (rpl_filter->db_ok(session->db))
2183
if (rpl_filter->db_ok(thd->db))
1560
session->set_time((time_t)when);
1561
session->query_length= q_len_arg;
1562
session->query= (char*)query_arg;
1563
session->query_id= query_id.next();
1564
session->variables.pseudo_thread_id= thread_id; // for temp tables
2185
thd->set_time((time_t)when);
2186
thd->query_length= q_len_arg;
2187
thd->query= (char*)query_arg;
2188
VOID(pthread_mutex_lock(&LOCK_thread_count));
2189
thd->query_id = next_query_id();
2190
VOID(pthread_mutex_unlock(&LOCK_thread_count));
2191
thd->variables.pseudo_thread_id= thread_id; // for temp tables
1566
2193
if (ignored_error_code((expected_error= error_code)) ||
1567
!check_expected_error(session,rli,expected_error))
2194
!check_expected_error(thd,rli,expected_error))
1569
2196
if (flags2_inited)
1571
all bits of session->options which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
2198
all bits of thd->options which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
1572
2199
must take their value from flags2.
1574
session->options= flags2|(session->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
2201
thd->options= flags2|(thd->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
2203
else, we are in a 3.23/4.0 binlog; we previously received a
2204
Rotate_log_event which reset thd->options and sql_mode etc, so
2209
if (rli->cached_charset_compare(charset))
2211
/* Verify that we support the charsets found in the event. */
2212
if (!(thd->variables.character_set_client=
2213
get_charset(uint2korr(charset), MYF(MY_WME))) ||
2214
!(thd->variables.collation_connection=
2215
get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
2216
!(thd->variables.collation_server=
2217
get_charset(uint2korr(charset+4), MYF(MY_WME))))
2220
We updated the thd->variables with nonsensical values (0). Let's
2221
set them to something safe (i.e. which avoids crash), and we'll
2222
stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
2225
set_slave_thread_default_charset(thd, rli);
2226
goto compare_errors;
2228
thd->update_charset(); // for the charset change to take effect
1575
2231
if (time_zone_len)
1577
2233
String tmp(time_zone_str, time_zone_len, &my_charset_bin);
1578
if (!(session->variables.time_zone= my_tz_find(session, &tmp)))
2234
if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
1580
2236
my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
1581
session->variables.time_zone= global_system_variables.time_zone;
2237
thd->variables.time_zone= global_system_variables.time_zone;
1582
2238
goto compare_errors;
1585
2241
if (lc_time_names_number)
1587
if (!(session->variables.lc_time_names=
2243
if (!(thd->variables.lc_time_names=
1588
2244
my_locale_by_number(lc_time_names_number)))
1590
2246
my_printf_error(ER_UNKNOWN_ERROR,
1591
2247
"Unknown locale: '%d'", MYF(0), lc_time_names_number);
1592
session->variables.lc_time_names= &my_locale_en_US;
2248
thd->variables.lc_time_names= &my_locale_en_US;
1593
2249
goto compare_errors;
1597
session->variables.lc_time_names= &my_locale_en_US;
2253
thd->variables.lc_time_names= &my_locale_en_US;
1598
2254
if (charset_database_number)
1600
const CHARSET_INFO *cs;
1601
2257
if (!(cs= get_charset(charset_database_number, MYF(0))))
1624
2280
we exit gracefully; otherwise we warn about the bad error and tell DBA
1625
2281
to check/fix it.
1627
if (mysql_test_parse_for_slave(session, session->query, session->query_length))
1628
clear_all_errors(session, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
2283
if (mysql_test_parse_for_slave(thd, thd->query, thd->query_length))
2284
clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
1631
rli->report(ERROR_LEVEL, expected_error,
1632
_("Query partially completed on the master "
1633
"(error on master: %d) and was aborted. There is a "
1634
"chance that your master is inconsistent at this "
1635
"point. If you are sure that your master is ok, run "
1636
"this query manually on the slave and then restart the "
1637
"slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; "
1638
"START SLAVE; . Query: '%s'"),
1639
expected_error, session->query);
1640
session->is_slave_error= 1;
2287
rli->report(ERROR_LEVEL, expected_error,
2289
Query partially completed on the master (error on master: %d) \
2290
and was aborted. There is a chance that your master is inconsistent at this \
2291
point. If you are sure that your master is ok, run this query manually on the \
2292
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
2293
START SLAVE; . Query: '%s'", expected_error, thd->query);
2294
thd->is_slave_error= 1;
2299
/* If the query was not ignored, it is printed to the general log */
2300
if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
2301
general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
1645
2303
compare_errors:
1648
2306
If we expected a non-zero error code, and we don't get the same error
1649
2307
code, and none of them should be ignored.
1651
actual_error= session->is_error() ? session->main_da.sql_errno() : 0;
2309
actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0;
1652
2310
if ((expected_error != actual_error) &&
1654
!ignored_error_code(actual_error) &&
1655
!ignored_error_code(expected_error))
2312
!ignored_error_code(actual_error) &&
2313
!ignored_error_code(expected_error))
1657
2315
rli->report(ERROR_LEVEL, 0,
1658
_("Query caused differenxt errors on master and slave.\n"
1659
"Error on master: '%s' (%d), Error on slave: '%s' (%d).\n"
1660
"Default database: '%s'. Query: '%s'"),
1663
actual_error ? session->main_da.message() : _("no error"),
1665
print_slave_db_safe(db), query_arg);
1666
session->is_slave_error= 1;
2317
Query caused different errors on master and slave. \
2318
Error on master: '%s' (%d), Error on slave: '%s' (%d). \
2319
Default database: '%s'. Query: '%s'",
2320
ER_SAFE(expected_error),
2322
actual_error ? thd->main_da.message() : "no error",
2324
print_slave_db_safe(db), query_arg);
2325
thd->is_slave_error= 1;
1669
2328
If we get the same error code as expected, or they should be ignored.
1711
2370
} /* End of if (db_ok(... */
1714
pthread_mutex_lock(&LOCK_thread_count);
2373
VOID(pthread_mutex_lock(&LOCK_thread_count));
1716
Probably we have set session->query, session->db, session->catalog to point to places
2375
Probably we have set thd->query, thd->db, thd->catalog to point to places
1717
2376
in the data_buf of this event. Now the event is going to be deleted
1718
probably, so data_buf will be freed, so the session->... listed above will be
2377
probably, so data_buf will be freed, so the thd->... listed above will be
1719
2378
pointers to freed memory.
1720
2379
So we must set them to 0, so that those bad pointers values are not later
1721
used. Note that "cleanup" queries like automatic DROP TEMPORARY Table
2380
used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
1722
2381
don't suffer from these assignments to 0 as DROP TEMPORARY
1723
Table uses the db.table syntax.
1725
session->catalog= 0;
1726
session->set_db(NULL, 0); /* will free the current database */
1727
session->query= 0; // just to be sure
1728
session->query_length= 0;
1729
pthread_mutex_unlock(&LOCK_thread_count);
1730
close_thread_tables(session);
1731
session->first_successful_insert_id_in_prev_stmt= 0;
1732
session->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
1733
free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
1734
return session->is_slave_error;
2382
TABLE uses the db.table syntax.
2385
thd->set_db(NULL, 0); /* will free the current database */
2386
thd->query= 0; // just to be sure
2387
thd->query_length= 0;
2388
VOID(pthread_mutex_unlock(&LOCK_thread_count));
2389
close_thread_tables(thd);
2391
As a disk space optimization, future masters will not log an event for
2392
LAST_INSERT_ID() if that function returned 0 (and thus they will be able
2393
to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
2394
variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
2395
resetting below we are ready to support that.
2397
thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
2398
thd->first_successful_insert_id_in_prev_stmt= 0;
2399
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
2400
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
2401
return thd->is_slave_error;
1737
2404
int Query_log_event::do_update_pos(Relay_log_info *rli)
1739
return Log_event::do_update_pos(rli);
2407
Note that we will not increment group* positions if we are just
2408
after a SET ONE_SHOT, because SET ONE_SHOT should not be separated
2409
from its following updating query.
2411
if (thd->one_shot_set)
2413
rli->inc_event_relay_log_pos();
2417
return Log_event::do_update_pos(rli);
1750
2428
if (strcmp("BEGIN", query) == 0)
1752
session->options|= OPTION_BEGIN;
2430
thd->options|= OPTION_BEGIN;
1753
2431
return(Log_event::continue_group(rli));
1756
2434
if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
1758
session->options&= ~OPTION_BEGIN;
2436
thd->options&= ~OPTION_BEGIN;
1759
2437
return(Log_event::EVENT_SKIP_COUNT);
1762
2440
return(Log_event::do_shall_skip(rli));
1766
2446
/**************************************************************************
1767
2447
Start_log_event_v3 methods
1768
2448
**************************************************************************/
2450
#ifndef MYSQL_CLIENT
1770
2451
Start_log_event_v3::Start_log_event_v3()
1771
2452
:Log_event(), created(0), binlog_version(BINLOG_VERSION),
1772
2453
artificial_event(0), dont_set_created(0)
1774
2455
memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
1778
2460
Start_log_event_v3::pack_info()
2463
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
1781
2464
void Start_log_event_v3::pack_info(Protocol *protocol)
1783
2466
char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
1784
pos= my_stpcpy(buf, "Server ver: ");
1785
pos= my_stpcpy(pos, server_version);
1786
pos= my_stpcpy(pos, ", Binlog ver: ");
2467
pos= strmov(buf, "Server ver: ");
2468
pos= strmov(pos, server_version);
2469
pos= strmov(pos, ", Binlog ver: ");
1787
2470
pos= int10_to_str(binlog_version, pos, 10);
1788
2471
protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
2477
Start_log_event_v3::print()
2481
void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
2483
Write_on_release_cache cache(&print_event_info->head_cache, file,
2484
Write_on_release_cache::FLUSH_F);
2486
if (!print_event_info->short_form)
2488
print_header(&cache, print_event_info, false);
2489
my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
2490
binlog_version, server_version);
2491
print_timestamp(&cache);
2493
my_b_printf(&cache," at startup");
2494
my_b_printf(&cache, "\n");
2495
if (flags & LOG_EVENT_BINLOG_IN_USE_F)
2496
my_b_printf(&cache, "# Warning: this binlog was not closed properly. "
2497
"Most probably mysqld crashed writing it.\n");
2499
if (!artificial_event && created)
2501
#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
2503
This is for mysqlbinlog: like in replication, we want to delete the stale
2504
tmp files left by an unclean shutdown of mysqld (temporary tables)
2505
and rollback unfinished transaction.
2506
Probably this can be done with RESET CONNECTION (syntax to be defined).
2508
my_b_printf(&cache,"RESET CONNECTION%s\n", print_event_info->delimiter);
2510
my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter);
2514
print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
2515
!print_event_info->short_form)
2517
my_b_printf(&cache, "BINLOG '\n");
2518
print_base64(&cache, print_event_info, false);
2519
print_event_info->printed_fd_event= true;
2523
#endif /* MYSQL_CLIENT */
1793
2526
Start_log_event_v3::Start_log_event_v3()
2175
2915
original place when it comes to us; we'll know this by checking
2176
2916
log_pos ("artificial" events have log_pos == 0).
2178
if (!artificial_event && created && session->transaction.all.ha_list)
2918
if (!artificial_event && created && thd->transaction.all.ha_list)
2180
2920
/* This is not an error (XA is safe), just an information */
2181
2921
rli->report(INFORMATION_LEVEL, 0,
2182
_("Rolling back unfinished transaction (no COMMIT "
2183
"or ROLLBACK in relay log). A probable cause is that "
2184
"the master died while writing the transaction to "
2185
"its binary log, thus rolled back too."));
2186
const_cast<Relay_log_info*>(rli)->cleanup_context(session, 1);
2922
"Rolling back unfinished transaction (no COMMIT "
2923
"or ROLLBACK in relay log). A probable cause is that "
2924
"the master died while writing the transaction to "
2925
"its binary log, thus rolled back too.");
2926
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
2189
2929
If this event comes from ourselves, there is no cleaning task to
2190
2930
perform, we don't call Start_log_event_v3::do_apply_event()
2191
2931
(this was just to update the log's description event).
2193
if (server_id != ::server_id)
2933
if (server_id != (uint32_t) ::server_id)
2196
2936
If the event was not requested by the slave i.e. the master sent
2316
3059
if (need_db && db && db_len)
2318
pos= my_stpcpy(pos, "use `");
3061
pos= strmov(pos, "use `");
2319
3062
memcpy(pos, db, db_len);
2320
pos= my_stpcpy(pos+db_len, "`; ");
3063
pos= strmov(pos+db_len, "`; ");
2323
pos= my_stpcpy(pos, "LOAD DATA ");
3066
pos= strmov(pos, "LOAD DATA ");
2326
3069
*fn_start= pos;
2328
3071
if (check_fname_outside_temp_buf())
2329
pos= my_stpcpy(pos, "LOCAL ");
2330
pos= my_stpcpy(pos, "INFILE '");
3072
pos= strmov(pos, "LOCAL ");
3073
pos= strmov(pos, "INFILE '");
2331
3074
memcpy(pos, fname, fname_len);
2332
pos= my_stpcpy(pos+fname_len, "' ");
3075
pos= strmov(pos+fname_len, "' ");
2334
3077
if (sql_ex.opt_flags & REPLACE_FLAG)
2335
pos= my_stpcpy(pos, " REPLACE ");
3078
pos= strmov(pos, " REPLACE ");
2336
3079
else if (sql_ex.opt_flags & IGNORE_FLAG)
2337
pos= my_stpcpy(pos, " IGNORE ");
3080
pos= strmov(pos, " IGNORE ");
2339
pos= my_stpcpy(pos ,"INTO");
3082
pos= strmov(pos ,"INTO");
2344
pos= my_stpcpy(pos ," Table `");
3087
pos= strmov(pos ," TABLE `");
2345
3088
memcpy(pos, table_name, table_name_len);
2346
3089
pos+= table_name_len;
2348
3091
/* We have to create all optinal fields as the default is not empty */
2349
pos= my_stpcpy(pos, "` FIELDS TERMINATED BY ");
3092
pos= strmov(pos, "` FIELDS TERMINATED BY ");
2350
3093
pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
2351
3094
if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
2352
pos= my_stpcpy(pos, " OPTIONALLY ");
2353
pos= my_stpcpy(pos, " ENCLOSED BY ");
3095
pos= strmov(pos, " OPTIONALLY ");
3096
pos= strmov(pos, " ENCLOSED BY ");
2354
3097
pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
2356
pos= my_stpcpy(pos, " ESCAPED BY ");
3099
pos= strmov(pos, " ESCAPED BY ");
2357
3100
pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
2359
pos= my_stpcpy(pos, " LINES TERMINATED BY ");
3102
pos= strmov(pos, " LINES TERMINATED BY ");
2360
3103
pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
2361
3104
if (sql_ex.line_start_len)
2363
pos= my_stpcpy(pos, " STARTING BY ");
3106
pos= strmov(pos, " STARTING BY ");
2364
3107
pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
2367
3110
if ((long) skip_lines > 0)
2369
pos= my_stpcpy(pos, " IGNORE ");
3112
pos= strmov(pos, " IGNORE ");
2370
3113
pos= int64_t10_to_str((int64_t) skip_lines, pos, 10);
2371
pos= my_stpcpy(pos," LINES ");
3114
pos= strmov(pos," LINES ");
2374
3117
if (num_fields)
2377
3120
const char *field= fields;
2378
pos= my_stpcpy(pos, " (");
3121
pos= strmov(pos, " (");
2379
3122
for (i = 0; i < num_fields; i++)
3356
Load_log_event::print()
3360
void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
3362
print(file, print_event_info, 0);
3366
void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
3369
Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
3371
if (!print_event_info->short_form)
3373
print_header(&cache, print_event_info, false);
3374
my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
3375
thread_id, exec_time);
3378
bool different_db= 1;
3382
If the database is different from the one of the previous statement, we
3383
need to print the "use" command, and we update the last_db.
3384
But if commented, the "use" is going to be commented so we should not
3387
if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
3389
memcpy(print_event_info->db, db, db_len + 1);
3392
if (db && db[0] && different_db)
3393
my_b_printf(&cache, "%suse %s%s\n",
3394
commented ? "# " : "",
3395
db, print_event_info->delimiter);
3397
if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
3398
my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
3399
commented ? "# " : "", (ulong)thread_id,
3400
print_event_info->delimiter);
3401
my_b_printf(&cache, "%sLOAD DATA ",
3402
commented ? "# " : "");
3403
if (check_fname_outside_temp_buf())
3404
my_b_printf(&cache, "LOCAL ");
3405
my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
3407
if (sql_ex.opt_flags & REPLACE_FLAG)
3408
my_b_printf(&cache," REPLACE ");
3409
else if (sql_ex.opt_flags & IGNORE_FLAG)
3410
my_b_printf(&cache," IGNORE ");
3412
my_b_printf(&cache, "INTO TABLE `%s`", table_name);
3413
my_b_printf(&cache, " FIELDS TERMINATED BY ");
3414
pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
3416
if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
3417
my_b_printf(&cache," OPTIONALLY ");
3418
my_b_printf(&cache, " ENCLOSED BY ");
3419
pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len);
3421
my_b_printf(&cache, " ESCAPED BY ");
3422
pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len);
3424
my_b_printf(&cache," LINES TERMINATED BY ");
3425
pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len);
3428
if (sql_ex.line_start)
3430
my_b_printf(&cache," STARTING BY ");
3431
pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len);
3433
if ((long) skip_lines > 0)
3434
my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines);
3439
const char* field = fields;
3440
my_b_printf(&cache, " (");
3441
for (i = 0; i < num_fields; i++)
3444
my_b_printf(&cache, ",");
3445
my_b_printf(&cache, field);
3447
field += field_lens[i] + 1;
3449
my_b_printf(&cache, ")");
3452
my_b_printf(&cache, "%s\n", print_event_info->delimiter);
3455
#endif /* MYSQL_CLIENT */
3457
#ifndef MYSQL_CLIENT
2609
3460
Load_log_event::set_fields()
2713
3565
::do_apply_event(), then the companion SET also have so
2714
3566
we don't need to reset_one_shot_variables().
2716
if (rpl_filter->db_ok(session->db))
3568
if (rpl_filter->db_ok(thd->db))
2718
session->set_time((time_t)when);
2719
session->query_id = query_id.next();
3570
thd->set_time((time_t)when);
3571
VOID(pthread_mutex_lock(&LOCK_thread_count));
3572
thd->query_id = next_query_id();
3573
VOID(pthread_mutex_unlock(&LOCK_thread_count));
2721
Initing session->row_count is not necessary in theory as this variable has no
3575
Initing thd->row_count is not necessary in theory as this variable has no
2722
3576
influence in the case of the slave SQL thread (it is used to generate a
2723
3577
"data truncated" warning but which is absorbed and never gets to the
2724
3578
error log); still we init it to avoid a Valgrind message.
2726
drizzle_reset_errors(session, 0);
3580
mysql_reset_errors(thd, 0);
2729
memset(&tables, 0, sizeof(tables));
2730
tables.db= session->strmake(session->db, session->db_length);
3583
memset((char*) &tables, 0, sizeof(tables));
3584
tables.db= thd->strmake(thd->db, thd->db_length);
2731
3585
tables.alias = tables.table_name = (char*) table_name;
2732
3586
tables.lock_type = TL_WRITE;
2733
3587
tables.updating= 1;
2735
3589
// the table will be opened in mysql_load
2736
if (rpl_filter->is_on() && !rpl_filter->tables_ok(session->db, &tables))
3590
if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db, &tables))
2738
3592
// TODO: this is a bug - this needs to be moved to the I/O thread
2793
3647
handle_dup= DUP_ERROR;
2796
We need to set session->lex->sql_command and session->lex->duplicates
3650
We need to set thd->lex->sql_command and thd->lex->duplicates
2797
3651
since InnoDB tests these variables to decide if this is a LOAD
2798
3652
DATA ... REPLACE INTO ... statement even though mysql_parse()
2799
3653
is not called. This is not needed in 5.0 since there the LOAD
2800
3654
DATA ... statement is replicated using mysql_parse(), which
2801
sets the session->lex fields correctly.
3655
sets the thd->lex fields correctly.
2803
session->lex->sql_command= SQLCOM_LOAD;
2804
session->lex->duplicates= handle_dup;
3657
thd->lex->sql_command= SQLCOM_LOAD;
3658
thd->lex->duplicates= handle_dup;
2806
3660
sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
2807
String field_term(sql_ex.field_term,sql_ex.field_term_len,&my_charset_utf8_general_ci);
2808
String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,&my_charset_utf8_general_ci);
2809
String line_term(sql_ex.line_term,sql_ex.line_term_len,&my_charset_utf8_general_ci);
2810
String line_start(sql_ex.line_start,sql_ex.line_start_len,&my_charset_utf8_general_ci);
2811
String escaped(sql_ex.escaped,sql_ex.escaped_len, &my_charset_utf8_general_ci);
3661
String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
3662
String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,log_cs);
3663
String line_term(sql_ex.line_term,sql_ex.line_term_len,log_cs);
3664
String line_start(sql_ex.line_start,sql_ex.line_start_len,log_cs);
3665
String escaped(sql_ex.escaped,sql_ex.escaped_len, log_cs);
2812
3666
ex.field_term= &field_term;
2813
3667
ex.enclosed= &enclosed;
2814
3668
ex.line_term= &line_term;
2822
3676
ex.skip_lines = skip_lines;
2823
3677
List<Item> field_list;
2824
session->lex->select_lex.context.resolve_in_table_list_only(&tables);
2825
set_fields(tables.db, field_list, &session->lex->select_lex.context);
2826
session->variables.pseudo_thread_id= thread_id;
3678
thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
3679
set_fields(tables.db, field_list, &thd->lex->select_lex.context);
3680
thd->variables.pseudo_thread_id= thread_id;
2829
// mysql_load will use session->net to read the file
2830
session->net.vio = net->vio;
3683
// mysql_load will use thd->net to read the file
3684
thd->net.vio = net->vio;
2832
3686
Make sure the client does not get confused about the packet sequence
2834
session->net.pkt_nr = net->pkt_nr;
3688
thd->net.pkt_nr = net->pkt_nr;
2837
3691
It is safe to use tmp_list twice because we are not going to
2838
3692
update it inside mysql_load().
2840
3694
List<Item> tmp_list;
2841
if (mysql_load(session, &ex, &tables, field_list, tmp_list, tmp_list,
3695
if (mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
2842
3696
handle_dup, ignore, net != 0))
2843
session->is_slave_error= 1;
2844
if (session->cuted_fields)
3697
thd->is_slave_error= 1;
3698
if (thd->cuted_fields)
2846
3700
/* log_pos is the position of the LOAD event in the master log */
2847
sql_print_warning(_("Slave: load data infile on table '%s' at "
3701
sql_print_warning("Slave: load data infile on table '%s' at "
2848
3702
"log position %s in log '%s' produced %ld "
2849
"warning(s). Default database: '%s'"),
3703
"warning(s). Default database: '%s'",
2850
3704
(char*) table_name,
2851
3705
llstr(log_pos,llbuff), RPL_LOG_NAME,
2852
(ulong) session->cuted_fields,
2853
print_slave_db_safe(session->db));
3706
(ulong) thd->cuted_fields,
3707
print_slave_db_safe(thd->db));
2856
net->pkt_nr= session->net.pkt_nr;
3710
net->pkt_nr= thd->net.pkt_nr;
2871
session->net.vio = 0;
2872
const char *remember_db= session->db;
2873
pthread_mutex_lock(&LOCK_thread_count);
2874
session->catalog= 0;
2875
session->set_db(NULL, 0); /* will free the current database */
2877
session->query_length= 0;
2878
pthread_mutex_unlock(&LOCK_thread_count);
2879
close_thread_tables(session);
3726
const char *remember_db= thd->db;
3727
VOID(pthread_mutex_lock(&LOCK_thread_count));
3729
thd->set_db(NULL, 0); /* will free the current database */
3731
thd->query_length= 0;
3732
VOID(pthread_mutex_unlock(&LOCK_thread_count));
3733
close_thread_tables(thd);
2881
if (session->is_slave_error)
3735
if (thd->is_slave_error)
2883
3737
/* this err/sql_errno code is copy-paste from net_send_error() */
2884
3738
const char *err;
2886
if (session->is_error())
3740
if (thd->is_error())
2888
err= session->main_da.message();
2889
sql_errno= session->main_da.sql_errno();
3742
err= thd->main_da.message();
3743
sql_errno= thd->main_da.sql_errno();
2893
3747
sql_errno=ER_UNKNOWN_ERROR;
2896
rli->report(ERROR_LEVEL, sql_errno,
2897
_("Error '%s' running LOAD DATA INFILE on table '%s'. "
2898
"Default database: '%s'"),
2899
err, (char*)table_name, print_slave_db_safe(remember_db));
2900
free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
3750
rli->report(ERROR_LEVEL, sql_errno,"\
3751
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
3752
err, (char*)table_name, print_slave_db_safe(remember_db));
3753
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
2903
free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
3756
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
2905
if (session->is_fatal_error)
3758
if (thd->is_fatal_error)
2908
3761
snprintf(buf, sizeof(buf),
2909
_("Running LOAD DATA INFILE on table '%-.64s'."
2910
" Default database: '%-.64s'"),
3762
"Running LOAD DATA INFILE on table '%-.64s'."
3763
" Default database: '%-.64s'",
2911
3764
(char*)table_name,
2912
3765
print_slave_db_safe(remember_db));
2928
3782
Rotate_log_event::pack_info()
3785
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2931
3786
void Rotate_log_event::pack_info(Protocol *protocol)
2933
3788
char buf1[256], buf[22];
2934
String tmp(buf1, sizeof(buf1), &my_charset_utf8_general_ci);
3789
String tmp(buf1, sizeof(buf1), log_cs);
2936
3791
tmp.append(new_log_ident, ident_len);
2937
3792
tmp.append(STRING_WITH_LEN(";pos="));
2938
3793
tmp.append(llstr(pos,buf));
2939
3794
protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
3800
Rotate_log_event::print()
3804
void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
3807
Write_on_release_cache cache(&print_event_info->head_cache, file,
3808
Write_on_release_cache::FLUSH_F);
3810
if (print_event_info->short_form)
3812
print_header(&cache, print_event_info, false);
3813
my_b_printf(&cache, "\tRotate to ");
3815
my_b_write(&cache, (uchar*) new_log_ident, (uint)ident_len);
3816
my_b_printf(&cache, " pos: %s\n", llstr(pos, buf));
3818
#endif /* MYSQL_CLIENT */
3029
3914
if ((server_id != ::server_id || rli->replicate_same_server_id) &&
3030
3915
!rli->is_in_group())
3032
rli->group_master_log_name.assign(new_log_ident, ident_len+1);
3917
memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
3033
3918
rli->notify_group_master_log_name_update();
3034
3919
rli->group_master_log_pos= pos;
3035
rli->group_relay_log_name.assign(rli->event_relay_log_name);
3920
strmake(rli->group_relay_log_name, rli->event_relay_log_name,
3921
sizeof(rli->group_relay_log_name) - 1);
3036
3922
rli->notify_group_relay_log_name_update();
3037
3923
rli->group_relay_log_pos= rli->event_relay_log_pos;
3039
Reset session->options and sql_mode etc, because this could be the signal of
3925
Reset thd->options and sql_mode etc, because this could be the signal of
3040
3926
a master's downgrade from 5.0 to 4.0.
3041
3927
However, no need to reset description_event_for_exec: indeed, if the next
3042
3928
master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
3043
3929
master is 4.0 then the events are in the slave's format (conversion).
3045
set_slave_thread_options(session);
3046
session->variables.auto_increment_increment=
3047
session->variables.auto_increment_offset= 1;
3931
set_slave_thread_options(thd);
3932
set_slave_thread_default_charset(thd, rli);
3933
thd->variables.auto_increment_increment=
3934
thd->variables.auto_increment_offset= 1;
3049
3936
pthread_mutex_unlock(&rli->data_lock);
3050
3937
pthread_cond_broadcast(&rli->data_cond);
3122
4013
Intvar_log_event::write()
4016
#ifndef MYSQL_CLIENT
3125
4017
bool Intvar_log_event::write(IO_CACHE* file)
3127
unsigned char buf[9];
3128
buf[I_TYPE_OFFSET]= (unsigned char) type;
4020
buf[I_TYPE_OFFSET]= (uchar) type;
3129
4021
int8store(buf + I_VAL_OFFSET, val);
3130
4022
return (write_header(file, sizeof(buf)) ||
3131
4023
my_b_safe_write(file, buf, sizeof(buf)));
3136
4029
Intvar_log_event::print()
4033
void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4037
Write_on_release_cache cache(&print_event_info->head_cache, file,
4038
Write_on_release_cache::FLUSH_F);
4040
if (!print_event_info->short_form)
4042
print_header(&cache, print_event_info, false);
4043
my_b_printf(&cache, "\tIntvar\n");
4046
my_b_printf(&cache, "SET ");
4048
case LAST_INSERT_ID_EVENT:
4049
msg="LAST_INSERT_ID";
4051
case INSERT_ID_EVENT:
4054
case INVALID_INT_EVENT:
4055
default: // cannot happen
4059
my_b_printf(&cache, "%s=%s%s\n",
4060
msg, llstr(val,llbuff), print_event_info->delimiter);
3140
4066
Intvar_log_event::do_apply_event()
4069
#if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
3143
4070
int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
4141
#ifndef MYSQL_CLIENT
3210
4142
bool Rand_log_event::write(IO_CACHE* file)
3212
unsigned char buf[16];
3213
4145
int8store(buf + RAND_SEED1_OFFSET, seed1);
3214
4146
int8store(buf + RAND_SEED2_OFFSET, seed2);
3215
4147
return (write_header(file, sizeof(buf)) ||
3216
4148
my_b_safe_write(file, buf, sizeof(buf)));
4154
void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4156
Write_on_release_cache cache(&print_event_info->head_cache, file,
4157
Write_on_release_cache::FLUSH_F);
4159
char llbuff[22],llbuff2[22];
4160
if (!print_event_info->short_form)
4162
print_header(&cache, print_event_info, false);
4163
my_b_printf(&cache, "\tRand\n");
4165
my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
4166
llstr(seed1, llbuff),llstr(seed2, llbuff2),
4167
print_event_info->delimiter);
4169
#endif /* MYSQL_CLIENT */
4172
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3220
4173
int Rand_log_event::do_apply_event(Relay_log_info const *rli)
3280
4237
:Log_event(buf, description_event)
3282
4239
buf+= description_event->common_header_len;
3283
memcpy(&xid, buf, sizeof(xid));
4240
memcpy((char*) &xid, buf, sizeof(xid));
4244
#ifndef MYSQL_CLIENT
3287
4245
bool Xid_log_event::write(IO_CACHE* file)
3289
4247
return write_header(file, sizeof(xid)) ||
3290
my_b_safe_write(file, (unsigned char*) &xid, sizeof(xid));
3294
int Xid_log_event::do_apply_event(const Relay_log_info *)
3296
return end_trans(session, COMMIT);
4248
my_b_safe_write(file, (uchar*) &xid, sizeof(xid));
4254
void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4256
Write_on_release_cache cache(&print_event_info->head_cache, file,
4257
Write_on_release_cache::FLUSH_F);
4259
if (!print_event_info->short_form)
4262
int64_t10_to_str(xid, buf, 10);
4264
print_header(&cache, print_event_info, false);
4265
my_b_printf(&cache, "\tXid = %s\n", buf);
4267
my_b_printf(&cache, "COMMIT%s\n", print_event_info->delimiter);
4269
#endif /* MYSQL_CLIENT */
4272
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4273
int Xid_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
4275
/* For a slave Xid_log_event is COMMIT */
4276
general_log_print(thd, COM_QUERY,
4277
"COMMIT /* implicit, from Xid_log_event */");
4278
return end_trans(thd, COMMIT);
3299
4281
Log_event::enum_skip_reason
3300
4282
Xid_log_event::do_shall_skip(Relay_log_info *rli)
3302
4284
if (rli->slave_skip_counter > 0) {
3303
session->options&= ~OPTION_BEGIN;
4285
thd->options&= ~OPTION_BEGIN;
3304
4286
return(Log_event::EVENT_SKIP_COUNT);
3306
4288
return(Log_event::do_shall_skip(rli));
4290
#endif /* !MYSQL_CLIENT */
3310
4293
/**************************************************************************
3311
4294
User_var_log_event methods
3312
4295
**************************************************************************/
4297
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3314
4298
void User_var_log_event::pack_info(Protocol* protocol)
3317
uint32_t val_offset= 4 + name_len;
3318
uint32_t event_len= val_offset;
4301
uint val_offset= 4 + name_len;
4302
uint event_len= val_offset;
3322
4306
if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
3324
my_stpcpy(buf + val_offset, "NULL");
4308
strmov(buf + val_offset, "NULL");
3325
4309
event_len= val_offset + 4;
3473
4459
event_length= sizeof(buf)+ name_len + buf1_length + val_len;
3475
4461
return (write_header(file, event_length) ||
3476
my_b_safe_write(file, (unsigned char*) buf, sizeof(buf)) ||
3477
my_b_safe_write(file, (unsigned char*) name, name_len) ||
3478
my_b_safe_write(file, (unsigned char*) buf1, buf1_length) ||
4462
my_b_safe_write(file, (uchar*) buf, sizeof(buf)) ||
4463
my_b_safe_write(file, (uchar*) name, name_len) ||
4464
my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
3479
4465
my_b_safe_write(file, pos, val_len));
4471
User_var_log_event::print()
4475
void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4477
Write_on_release_cache cache(&print_event_info->head_cache, file,
4478
Write_on_release_cache::FLUSH_F);
4480
if (!print_event_info->short_form)
4482
print_header(&cache, print_event_info, false);
4483
my_b_printf(&cache, "\tUser_var\n");
4486
my_b_printf(&cache, "SET @`");
4487
my_b_write(&cache, (uchar*) name, (uint) (name_len));
4488
my_b_printf(&cache, "`");
4492
my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter);
4499
char real_buf[FMT_G_BUFSIZE(14)];
4500
float8get(real_val, val);
4501
sprintf(real_buf, "%.14g", real_val);
4502
my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter);
4506
int64_t10_to_str(uint8korr(val), int_buf, -10);
4507
my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
4509
case DECIMAL_RESULT:
4512
int str_len= sizeof(str_buf) - 1;
4513
int precision= (int)val[0];
4514
int scale= (int)val[1];
4515
decimal_digit_t dec_buf[10];
4520
bin2decimal((uchar*) val+2, &dec, precision, scale);
4521
decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
4522
str_buf[str_len]= 0;
4523
my_b_printf(&cache, ":=%s%s\n", str_buf, print_event_info->delimiter);
4529
Let's express the string in hex. That's the most robust way. If we
4530
print it in character form instead, we need to escape it with
4531
character_set_client which we don't know (we will know it in 5.0, but
4532
in 4.1 we don't know it easily when we are printing
4533
User_var_log_event). Explanation why we would need to bother with
4534
character_set_client (quoting Bar):
4535
> Note, the parser doesn't switch to another unescaping mode after
4536
> it has met a character set introducer.
4537
> For example, if an SJIS client says something like:
4538
> SET @a= _ucs2 \0a\0b'
4539
> the string constant is still unescaped according to SJIS, not
4540
> according to UCS2.
4545
if (!(hex_str= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits / byte
4546
break; // no error, as we are 'void'
4547
str_to_hex(hex_str, val, val_len);
4549
For proper behaviour when mysqlbinlog|mysql, we need to explicitely
4550
specify the variable's collation. It will however cause problems when
4551
people want to mysqlbinlog|mysql into another server not supporting the
4552
character set. But there's not much to do about this and it's unlikely.
4554
if (!(cs= get_charset(charset_number, MYF(0))))
4556
Generate an unusable command (=> syntax error) is probably the best
4557
thing we can do here.
4559
my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
4561
my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
4562
cs->csname, hex_str, cs->name,
4563
print_event_info->delimiter);
3485
4578
User_var_log_event::do_apply_event()
4581
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3488
4582
int User_var_log_event::do_apply_event(Relay_log_info const *rli)
3491
const CHARSET_INFO *charset;
4585
CHARSET_INFO *charset;
3492
4586
if (!(charset= get_charset(charset_number, MYF(MY_WME))))
3494
4588
LEX_STRING user_var_name;
3576
4670
return continue_group(rli);
4672
#endif /* !MYSQL_CLIENT */
3580
4675
/**************************************************************************
3581
4676
Slave_log_event methods
3582
4677
**************************************************************************/
4679
#ifdef HAVE_REPLICATION
4681
void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
4683
Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
4685
if (print_event_info->short_form)
4687
print_header(&cache, print_event_info, false);
4688
my_b_printf(&cache, "\n# %s", "Unknown event\n");
4692
#ifndef MYSQL_CLIENT
3584
4693
void Slave_log_event::pack_info(Protocol *protocol)
3586
4695
char buf[256+HOSTNAME_LENGTH], *pos;
3587
pos= my_stpcpy(buf, "host=");
3588
pos= my_stpncpy(pos, master_host.c_str(), HOSTNAME_LENGTH);
3589
pos= my_stpcpy(pos, ",port=");
4696
pos= strmov(buf, "host=");
4697
pos= strnmov(pos, master_host, HOSTNAME_LENGTH);
4698
pos= strmov(pos, ",port=");
3590
4699
pos= int10_to_str((long) master_port, pos, 10);
3591
pos= my_stpcpy(pos, ",log=");
3592
pos= my_stpcpy(pos, master_log.c_str());
3593
pos= my_stpcpy(pos, ",pos=");
4700
pos= strmov(pos, ",log=");
4701
pos= strmov(pos, master_log);
4702
pos= strmov(pos, ",pos=");
3594
4703
pos= int64_t10_to_str(master_pos, pos, 10);
3595
4704
protocol->store(buf, pos-buf, &my_charset_bin);
4706
#endif /* !MYSQL_CLIENT */
4709
#ifndef MYSQL_CLIENT
3601
4712
re-write this better without holding both locks at the same time
3603
Slave_log_event::Slave_log_event(Session* session_arg,
4714
Slave_log_event::Slave_log_event(THD* thd_arg,
3604
4715
Relay_log_info* rli)
3605
:Log_event(session_arg, 0, 0) , mem_pool(0), master_host(0)
4716
:Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
3607
4718
if (!rli->inited) // QQ When can this happen ?
3611
4722
// TODO: re-write this better without holding both locks at the same time
3612
4723
pthread_mutex_lock(&mi->data_lock);
3613
4724
pthread_mutex_lock(&rli->data_lock);
4725
master_host_len = strlen(mi->host);
4726
master_log_len = strlen(rli->group_master_log_name);
3614
4727
// on OOM, just do not initialize the structure and print the error
3615
4728
if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
3618
master_host.assign(mi->getHostname());
3619
master_log.assign(rli->group_master_log_name);
3620
master_port = mi->getPort();
4731
master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
4732
memcpy(master_host, mi->host, master_host_len + 1);
4733
master_log = master_host + master_host_len + 1;
4734
memcpy(master_log, rli->group_master_log_name, master_log_len + 1);
4735
master_port = mi->port;
3621
4736
master_pos = rli->group_master_log_pos;
3624
sql_print_error(_("Out of memory while recording slave event"));
4739
sql_print_error("Out of memory while recording slave event");
3625
4740
pthread_mutex_unlock(&rli->data_lock);
3626
4741
pthread_mutex_unlock(&mi->data_lock);
4744
#endif /* !MYSQL_CLIENT */
3631
4747
Slave_log_event::~Slave_log_event()
4749
my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
4754
void Slave_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4756
Write_on_release_cache cache(&print_event_info->head_cache, file);
4759
if (print_event_info->short_form)
4761
print_header(&cache, print_event_info, false);
4762
my_b_printf(&cache, "\n\
4763
Slave: master_host: '%s' master_port: %d master_log: '%s' master_pos: %s\n",
4764
master_host, master_port, master_log, llstr(master_pos, llbuff));
4766
#endif /* MYSQL_CLIENT */
3637
4769
int Slave_log_event::get_data_size()
3639
return master_host.length() + master_log.length() + 1 + SL_MASTER_HOST_OFFSET;
4771
return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
4775
#ifndef MYSQL_CLIENT
3643
4776
bool Slave_log_event::write(IO_CACHE* file)
3645
4778
ulong event_length= get_data_size();
3648
4781
// log and host are already there
3650
4783
return (write_header(file, event_length) ||
3651
my_b_safe_write(file, (unsigned char*) mem_pool, event_length));
4784
my_b_safe_write(file, (uchar*) mem_pool, event_length));
3655
void Slave_log_event::init_from_mem_pool()
4789
void Slave_log_event::init_from_mem_pool(int data_size)
3657
4791
master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
3658
4792
master_port = uint2korr(mem_pool + SL_MASTER_PORT_OFFSET);
3660
/* Assign these correctly */
3661
master_host.assign(mem_pool + SL_MASTER_HOST_OFFSET);
3662
master_log.assign();
3667
int Slave_log_event::do_apply_event(const Relay_log_info *)
3669
if (drizzle_bin_log.is_open())
3670
drizzle_bin_log.write(this);
4793
master_host = mem_pool + SL_MASTER_HOST_OFFSET;
4794
master_host_len = strlen(master_host);
4796
master_log = master_host + master_host_len + 1;
4797
if (master_log > mem_pool + data_size)
4802
master_log_len = strlen(master_log);
4806
/** This code is not used, so has not been updated to be format-tolerant. */
4807
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
4808
:Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
4810
if (event_len < LOG_EVENT_HEADER_LEN)
4812
event_len -= LOG_EVENT_HEADER_LEN;
4813
if (!(mem_pool = (char*) my_malloc(event_len + 1, MYF(MY_WME))))
4815
memcpy(mem_pool, buf + LOG_EVENT_HEADER_LEN, event_len);
4816
mem_pool[event_len] = 0;
4817
init_from_mem_pool(event_len);
4821
#ifndef MYSQL_CLIENT
4822
int Slave_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
4824
if (mysql_bin_log.is_open())
4825
mysql_bin_log.write(this);
4828
#endif /* !MYSQL_CLIENT */
3675
4831
/**************************************************************************
3715
4894
Create_file_log_event ctor
4897
#ifndef MYSQL_CLIENT
3718
4898
Create_file_log_event::
3719
Create_file_log_event(Session* session_arg, sql_exchange* ex,
4899
Create_file_log_event(THD* thd_arg, sql_exchange* ex,
3720
4900
const char* db_arg, const char* table_name_arg,
3721
4901
List<Item>& fields_arg, enum enum_duplicates handle_dup,
3723
unsigned char* block_arg, uint32_t block_len_arg, bool using_trans)
3724
:Load_log_event(session_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
4903
uchar* block_arg, uint block_len_arg, bool using_trans)
4904
:Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
3726
4906
fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
3727
file_id(session_arg->file_id = drizzle_bin_log.next_file_id())
4907
file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
3729
4909
sql_ex.force_new_format();
5013
Create_file_log_event::print()
5017
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
5020
Write_on_release_cache cache(&print_event_info->head_cache, file);
5022
if (print_event_info->short_form)
5024
if (enable_local && check_fname_outside_temp_buf())
5025
Load_log_event::print(file, print_event_info);
5031
Load_log_event::print(file, print_event_info,
5032
!check_fname_outside_temp_buf());
5034
That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
5035
SHOW BINLOG EVENTS we don't.
5037
my_b_printf(&cache, "#");
5040
my_b_printf(&cache, " file_id: %d block_len: %d\n", file_id, block_len);
5044
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5046
print(file, print_event_info, 0);
5048
#endif /* MYSQL_CLIENT */
3831
5052
Create_file_log_event::pack_info()
5055
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3834
5056
void Create_file_log_event::pack_info(Protocol *protocol)
3836
5058
char buf[NAME_LEN*2 + 30 + 21*2], *pos;
3837
pos= my_stpcpy(buf, "db=");
5059
pos= strmov(buf, "db=");
3838
5060
memcpy(pos, db, db_len);
3839
pos= my_stpcpy(pos + db_len, ";table=");
5061
pos= strmov(pos + db_len, ";table=");
3840
5062
memcpy(pos, table_name, table_name_len);
3841
pos= my_stpcpy(pos + table_name_len, ";file_id=");
5063
pos= strmov(pos + table_name_len, ";file_id=");
3842
5064
pos= int10_to_str((long) file_id, pos, 10);
3843
pos= my_stpcpy(pos, ";block_len=");
5065
pos= strmov(pos, ";block_len=");
3844
5066
pos= int10_to_str((long) block_len, pos, 10);
3845
5067
protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
5069
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
3850
5073
Create_file_log_event::do_apply_event()
5076
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3853
5077
int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
3855
5079
char proc_info[17+FN_REFLEN+10], *fname_buf;
3861
memset(&file, 0, sizeof(file));
3862
fname_buf= my_stpcpy(proc_info, "Making temp file ");
5085
memset((char*)&file, 0, sizeof(file));
5086
fname_buf= strmov(proc_info, "Making temp file ");
3863
5087
ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
3864
session->set_proc_info(proc_info);
5088
thd_proc_info(thd, proc_info);
3865
5089
my_delete(fname_buf, MYF(0)); // old copy may exist already
3866
5090
if ((fd= my_create(fname_buf, CREATE_MODE,
5091
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
3868
5092
MYF(MY_WME))) < 0 ||
3869
5093
init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
3870
5094
MYF(MY_WME|MY_NABP)))
3872
5096
rli->report(ERROR_LEVEL, my_errno,
3873
_("Error in Create_file event: could not open file '%s'"),
5097
"Error in Create_file event: could not open file '%s'",
3878
5102
// a trick to avoid allocating another buffer
3879
5103
fname= fname_buf;
3880
fname_len= (uint) (my_stpcpy(ext, ".data") - fname);
5104
fname_len= (uint) (strmov(ext, ".data") - fname);
3881
5105
if (write_base(&file))
3883
my_stpcpy(ext, ".info"); // to have it right in the error message
5107
strmov(ext, ".info"); // to have it right in the error message
3884
5108
rli->report(ERROR_LEVEL, my_errno,
3885
_("Error in Create_file event: could not write to file '%s'"),
5109
"Error in Create_file event: could not write to file '%s'",
3889
5113
end_io_cache(&file);
3890
5114
my_close(fd, MYF(0));
3892
5116
// fname_buf now already has .data, not .info, because we did our trick
3893
5117
my_delete(fname_buf, MYF(0)); // old copy may exist already
3894
5118
if ((fd= my_create(fname_buf, CREATE_MODE,
5119
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
3898
5122
rli->report(ERROR_LEVEL, my_errno,
3899
_("Error in Create_file event: could not open file '%s'"),
5123
"Error in Create_file event: could not open file '%s'",
3903
if (my_write(fd, (unsigned char*) block, block_len, MYF(MY_WME+MY_NABP)))
5127
if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
3905
5129
rli->report(ERROR_LEVEL, my_errno,
3906
_("Error in Create_file event: write to '%s' failed"),
5130
"Error in Create_file event: write to '%s' failed",
3927
5152
Append_block_log_event ctor
3930
Append_block_log_event::Append_block_log_event(Session *session_arg,
5155
#ifndef MYSQL_CLIENT
5156
Append_block_log_event::Append_block_log_event(THD *thd_arg,
3931
5157
const char *db_arg,
3932
unsigned char *block_arg,
3933
uint32_t block_len_arg,
3934
5160
bool using_trans)
3935
:Log_event(session_arg,0, using_trans), block(block_arg),
3936
block_len(block_len_arg), file_id(session_arg->file_id), db(db_arg)
5161
:Log_event(thd_arg,0, using_trans), block(block_arg),
5162
block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
3942
5169
Append_block_log_event ctor
3945
Append_block_log_event::Append_block_log_event(const char* buf, uint32_t len,
5172
Append_block_log_event::Append_block_log_event(const char* buf, uint len,
3946
5173
const Format_description_log_event* description_event)
3947
5174
:Log_event(buf, description_event),block(0)
3949
5176
uint8_t common_header_len= description_event->common_header_len;
3950
5177
uint8_t append_block_header_len=
3951
5178
description_event->post_header_len[APPEND_BLOCK_EVENT-1];
3952
uint32_t total_header_len= common_header_len+append_block_header_len;
5179
uint total_header_len= common_header_len+append_block_header_len;
3953
5180
if (len < total_header_len)
3955
5182
file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
3956
block= (unsigned char*)buf + total_header_len;
5183
block= (uchar*)buf + total_header_len;
3957
5184
block_len= len - total_header_len;
3963
5190
Append_block_log_event::write()
5193
#ifndef MYSQL_CLIENT
3966
5194
bool Append_block_log_event::write(IO_CACHE* file)
3968
unsigned char buf[APPEND_BLOCK_HEADER_LEN];
5196
uchar buf[APPEND_BLOCK_HEADER_LEN];
3969
5197
int4store(buf + AB_FILE_ID_OFFSET, file_id);
3970
5198
return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
3971
5199
my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
3972
my_b_safe_write(file, (unsigned char*) block, block_len));
5200
my_b_safe_write(file, (uchar*) block, block_len));
5206
Append_block_log_event::print()
5210
void Append_block_log_event::print(FILE* file,
5211
PRINT_EVENT_INFO* print_event_info)
5213
Write_on_release_cache cache(&print_event_info->head_cache, file);
5215
if (print_event_info->short_form)
5217
print_header(&cache, print_event_info, false);
5218
my_b_printf(&cache, "\n#%s: file_id: %d block_len: %d\n",
5219
get_type_str(), file_id, block_len);
5221
#endif /* MYSQL_CLIENT */
3977
5225
Append_block_log_event::pack_info()
5228
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3980
5229
void Append_block_log_event::pack_info(Protocol *protocol)
3984
5233
length= (uint) sprintf(buf, ";file_id=%u;block_len=%u", file_id,
3986
5235
protocol->store(buf, length, &my_charset_bin);
4009
fname= my_stpcpy(proc_info, "Making temp file ");
5258
fname= strmov(proc_info, "Making temp file ");
4010
5259
slave_load_file_stem(fname, file_id, server_id, ".data");
4011
session->set_proc_info(proc_info);
5260
thd_proc_info(thd, proc_info);
4012
5261
if (get_create_or_append())
4014
5263
my_delete(fname, MYF(0)); // old copy may exist already
4015
5264
if ((fd= my_create(fname, CREATE_MODE,
5265
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
4017
5266
MYF(MY_WME))) < 0)
4019
5268
rli->report(ERROR_LEVEL, my_errno,
4020
_("Error in %s event: could not create file '%s'"),
5269
"Error in %s event: could not create file '%s'",
4021
5270
get_type_str(), fname);
4025
else if ((fd = my_open(fname, O_WRONLY | O_APPEND,
5274
else if ((fd = my_open(fname, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
4026
5275
MYF(MY_WME))) < 0)
4028
5277
rli->report(ERROR_LEVEL, my_errno,
4029
_("Error in %s event: could not open file '%s'"),
5278
"Error in %s event: could not open file '%s'",
4030
5279
get_type_str(), fname);
4033
if (my_write(fd, (unsigned char*) block, block_len, MYF(MY_WME+MY_NABP)))
5282
if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
4035
5284
rli->report(ERROR_LEVEL, my_errno,
4036
_("Error in %s event: write to '%s' failed"),
5285
"Error in %s event: write to '%s' failed",
4037
5286
get_type_str(), fname);
4081
5333
Delete_file_log_event::write()
5336
#ifndef MYSQL_CLIENT
4084
5337
bool Delete_file_log_event::write(IO_CACHE* file)
4086
unsigned char buf[DELETE_FILE_HEADER_LEN];
5339
uchar buf[DELETE_FILE_HEADER_LEN];
4087
5340
int4store(buf + DF_FILE_ID_OFFSET, file_id);
4088
5341
return (write_header(file, sizeof(buf)) ||
4089
5342
my_b_safe_write(file, buf, sizeof(buf)));
5348
Delete_file_log_event::print()
5352
void Delete_file_log_event::print(FILE* file,
5353
PRINT_EVENT_INFO* print_event_info)
5355
Write_on_release_cache cache(&print_event_info->head_cache, file);
5357
if (print_event_info->short_form)
5359
print_header(&cache, print_event_info, false);
5360
my_b_printf(&cache, "\n#Delete_file: file_id=%u\n", file_id);
5362
#endif /* MYSQL_CLIENT */
4094
5365
Delete_file_log_event::pack_info()
5368
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4097
5369
void Delete_file_log_event::pack_info(Protocol *protocol)
4101
5373
length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
4102
5374
protocol->store(buf, (int32_t) length, &my_charset_bin);
4106
5379
Delete_file_log_event::do_apply_event()
4109
int Delete_file_log_event::do_apply_event(const Relay_log_info *)
5382
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5383
int Delete_file_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
4111
5385
char fname[FN_REFLEN+10];
4112
5386
char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
4113
5387
(void) my_delete(fname, MYF(MY_WME));
4114
my_stpcpy(ext, ".info");
5388
strmov(ext, ".info");
4115
5389
(void) my_delete(fname, MYF(MY_WME));
5392
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4120
5395
/**************************************************************************
5564
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4270
5567
/**************************************************************************
4271
5568
Begin_load_query_log_event methods
4272
5569
**************************************************************************/
5571
#ifndef MYSQL_CLIENT
4274
5572
Begin_load_query_log_event::
4275
Begin_load_query_log_event(Session* session_arg, const char* db_arg, unsigned char* block_arg,
4276
uint32_t block_len_arg, bool using_trans)
4277
:Append_block_log_event(session_arg, db_arg, block_arg, block_len_arg,
5573
Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
5574
uint block_len_arg, bool using_trans)
5575
:Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
4280
file_id= session_arg->file_id= drizzle_bin_log.next_file_id();
5578
file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
4284
5583
Begin_load_query_log_event::
4285
Begin_load_query_log_event(const char* buf, uint32_t len,
5584
Begin_load_query_log_event(const char* buf, uint len,
4286
5585
const Format_description_log_event* desc_event)
4287
5586
:Append_block_log_event(buf, len, desc_event)
5591
#if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4292
5592
int Begin_load_query_log_event::get_create_or_append() const
4294
5594
return 1; /* create the file */
5596
#endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
5599
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4298
5600
Log_event::enum_skip_reason
4299
5601
Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
4311
5614
**************************************************************************/
5617
#ifndef MYSQL_CLIENT
4314
5618
Execute_load_query_log_event::
4315
Execute_load_query_log_event(Session *session_arg, const char* query_arg,
4316
ulong query_length_arg, uint32_t fn_pos_start_arg,
4317
uint32_t fn_pos_end_arg,
5619
Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
5620
ulong query_length_arg, uint fn_pos_start_arg,
5621
uint fn_pos_end_arg,
4318
5622
enum_load_dup_handling dup_handling_arg,
4319
5623
bool using_trans, bool suppress_use,
4320
Session::killed_state killed_err_arg):
4321
Query_log_event(session_arg, query_arg, query_length_arg, using_trans,
5624
THD::killed_state killed_err_arg):
5625
Query_log_event(thd_arg, query_arg, query_length_arg, using_trans,
4322
5626
suppress_use, killed_err_arg),
4323
file_id(session_arg->file_id), fn_pos_start(fn_pos_start_arg),
5627
file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
4324
5628
fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
5631
#endif /* !MYSQL_CLIENT */
4329
5634
Execute_load_query_log_event::
4330
Execute_load_query_log_event(const char* buf, uint32_t event_len,
5635
Execute_load_query_log_event(const char* buf, uint event_len,
4331
5636
const Format_description_log_event* desc_event):
4332
5637
Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
4333
5638
file_id(0), fn_pos_start(0), fn_pos_end(0)
5663
#ifndef MYSQL_CLIENT
4359
5665
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
4361
unsigned char buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
5667
uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
4362
5668
int4store(buf, file_id);
4363
5669
int4store(buf + 4, fn_pos_start);
4364
5670
int4store(buf + 4 + 4, fn_pos_end);
4365
*(buf + 4 + 4 + 4)= (unsigned char) dup_handling;
5671
*(buf + 4 + 4 + 4)= (uchar) dup_handling;
4366
5672
return my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
5678
void Execute_load_query_log_event::print(FILE* file,
5679
PRINT_EVENT_INFO* print_event_info)
5681
print(file, print_event_info, 0);
5685
Prints the query as LOAD DATA LOCAL and with rewritten filename.
5687
void Execute_load_query_log_event::print(FILE* file,
5688
PRINT_EVENT_INFO* print_event_info,
5689
const char *local_fname)
5691
Write_on_release_cache cache(&print_event_info->head_cache, file);
5693
print_query_header(&cache, print_event_info);
5697
my_b_write(&cache, (uchar*) query, fn_pos_start);
5698
my_b_printf(&cache, " LOCAL INFILE \'");
5699
my_b_printf(&cache, local_fname);
5700
my_b_printf(&cache, "\'");
5701
if (dup_handling == LOAD_DUP_REPLACE)
5702
my_b_printf(&cache, " REPLACE");
5703
my_b_printf(&cache, " INTO");
5704
my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
5705
my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
5709
my_b_write(&cache, (uchar*) query, q_len);
5710
my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
5713
if (!print_event_info->short_form)
5714
my_b_printf(&cache, "# file_id: %d \n", file_id);
5719
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4370
5720
void Execute_load_query_log_event::pack_info(Protocol *protocol)
4372
5722
char *buf, *pos;
4543
5893
Rows_log_event member functions
4544
5894
**************************************************************************/
4546
Rows_log_event::Rows_log_event(Session *session_arg, Table *tbl_arg, ulong tid,
5896
#ifndef MYSQL_CLIENT
5897
Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
4547
5898
MY_BITMAP const *cols, bool is_transactional)
4548
: Log_event(session_arg, 0, is_transactional),
5899
: Log_event(thd_arg, 0, is_transactional),
4549
5900
m_row_count(0),
4550
5901
m_table(tbl_arg),
4551
5902
m_table_id(tid),
4552
5903
m_width(tbl_arg ? tbl_arg->s->fields : 1),
4553
5904
m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0)
5905
#ifdef HAVE_REPLICATION
4554
5906
, m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
4557
5910
We allow a special form of dummy event when the table, and cols
4558
are null and the table id is UINT32_MAX. This is a temporary
5911
are null and the table id is ~0UL. This is a temporary
4559
5912
solution, to be able to terminate a started statement in the
4560
5913
binary log: the extraneous events will be removed in the future.
4562
assert((tbl_arg && tbl_arg->s && tid != UINT32_MAX) || (!tbl_arg && !cols && tid == UINT32_MAX));
5915
assert((tbl_arg && tbl_arg->s && tid != ~0UL) || (!tbl_arg && !cols && tid == ~0UL));
4564
if (session_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
5917
if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
4565
5918
set_flags(NO_FOREIGN_KEY_CHECKS_F);
4566
if (session_arg->options & OPTION_RELAXED_UNIQUE_CHECKS)
5919
if (thd_arg->options & OPTION_RELAXED_UNIQUE_CHECKS)
4567
5920
set_flags(RELAXED_UNIQUE_CHECKS_F);
4568
5921
/* if bitmap_init fails, caught in is_valid() */
4569
5922
if (likely(!bitmap_init(&m_cols,
4817
6179
if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
4818
session->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
6180
thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
4820
session->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
6182
thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
4822
6184
if (get_flags(RELAXED_UNIQUE_CHECKS_F))
4823
session->options|= OPTION_RELAXED_UNIQUE_CHECKS;
6185
thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
4825
session->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
6187
thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
4826
6188
/* A small test to verify that objects have consistent types */
4827
assert(sizeof(session->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
4830
while ((error= lock_tables(session, rli->tables_to_lock,
6189
assert(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
6192
while ((error= lock_tables(thd, rli->tables_to_lock,
4831
6193
rli->tables_to_lock_count, &need_reopen)))
4833
6195
if (!need_reopen)
4835
if (session->is_slave_error || session->is_fatal_error)
6197
if (thd->is_slave_error || thd->is_fatal_error)
4838
6200
Error reporting borrowed from Query_log_event with many excessive
4839
6201
simplifications (we don't honour --slave-skip-errors)
4841
uint32_t actual_error= session->main_da.sql_errno();
6203
uint actual_error= thd->main_da.sql_errno();
4842
6204
rli->report(ERROR_LEVEL, actual_error,
4843
_("Error '%s' in %s event: when locking tables"),
4845
? session->main_da.message()
4846
: _("unexpected success or fatal error")),
6205
"Error '%s' in %s event: when locking tables",
6206
(actual_error ? thd->main_da.message():
6207
"unexpected success or fatal error"),
4847
6208
get_type_str());
4848
session->is_fatal_error= 1;
6209
thd->is_fatal_error= 1;
4852
6213
rli->report(ERROR_LEVEL, error,
4853
_("Error in %s event: when locking tables"),
6214
"Error in %s event: when locking tables",
4854
6215
get_type_str());
4856
6217
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
4870
6231
NOTE: For this new scheme there should be no pending event:
4871
6232
need to add code to assert that is the case.
4873
session->binlog_flush_pending_rows_event(false);
4874
TableList *tables= rli->tables_to_lock;
4875
close_tables_for_reopen(session, &tables);
6234
thd->binlog_flush_pending_rows_event(false);
6235
TABLE_LIST *tables= rli->tables_to_lock;
6236
close_tables_for_reopen(thd, &tables);
4877
uint32_t tables_count= rli->tables_to_lock_count;
4878
if ((error= open_tables(session, &tables, &tables_count, 0)))
6238
uint tables_count= rli->tables_to_lock_count;
6239
if ((error= open_tables(thd, &tables, &tables_count, 0)))
4880
if (session->is_slave_error || session->is_fatal_error)
6241
if (thd->is_slave_error || thd->is_fatal_error)
4883
6244
Error reporting borrowed from Query_log_event with many excessive
4884
6245
simplifications (we don't honour --slave-skip-errors)
4886
uint32_t actual_error= session->main_da.sql_errno();
6247
uint actual_error= thd->main_da.sql_errno();
4887
6248
rli->report(ERROR_LEVEL, actual_error,
4888
_("Error '%s' on reopening tables"),
4890
? session->main_da.message()
4891
: _("unexpected success or fatal error")));
4892
session->is_slave_error= 1;
6249
"Error '%s' on reopening tables",
6250
(actual_error ? thd->main_da.message() :
6251
"unexpected success or fatal error"));
6252
thd->is_slave_error= 1;
4894
6254
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
4959
6319
TIMESTAMP column to a table with one.
4960
6320
So we call set_time(), like in SBR. Presently it changes nothing.
4962
session->set_time((time_t)when);
6322
thd->set_time((time_t)when);
4964
6324
There are a few flags that are replicated with each row event.
4965
6325
Make sure to set/clear them before executing the main body of
4968
6328
if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
4969
session->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
6329
thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
4971
session->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
6331
thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
4973
6333
if (get_flags(RELAXED_UNIQUE_CHECKS_F))
4974
session->options|= OPTION_RELAXED_UNIQUE_CHECKS;
6334
thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
4976
session->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
6336
thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
4978
6338
if (slave_allow_batching)
4979
session->options|= OPTION_ALLOW_BATCH;
6339
thd->options|= OPTION_ALLOW_BATCH;
4981
session->options&= ~OPTION_ALLOW_BATCH;
6341
thd->options&= ~OPTION_ALLOW_BATCH;
4983
6343
/* A small test to verify that objects have consistent types */
4984
assert(sizeof(session->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
6344
assert(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
4987
6347
Now we are in a statement and will stay in a statement until we
5501
6900
const char *const vpart= buf + common_header_len + post_header_len;
5503
6902
/* Extract the length of the various parts from the buffer */
5504
unsigned char const *const ptr_dblen= (unsigned char const*)vpart + 0;
5505
m_dblen= *(unsigned char*) ptr_dblen;
6903
uchar const *const ptr_dblen= (uchar const*)vpart + 0;
6904
m_dblen= *(uchar*) ptr_dblen;
5507
6906
/* Length of database name + counter + terminating null */
5508
unsigned char const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
5509
m_tbllen= *(unsigned char*) ptr_tbllen;
6907
uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
6908
m_tbllen= *(uchar*) ptr_tbllen;
5511
6910
/* Length of table name + counter + terminating null */
5512
unsigned char const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
5513
unsigned char *ptr_after_colcnt= (unsigned char*) ptr_colcnt;
6911
uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
6912
uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
5514
6913
m_colcnt= net_field_length(&ptr_after_colcnt);
5516
6915
/* Allocate mem for all fields in one go. If fails, caught in is_valid() */
5517
m_memory= (unsigned char*) my_multi_malloc(MYF(MY_WME),
6916
m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
5518
6917
&m_dbnam, (uint) m_dblen + 1,
5519
6918
&m_tblnam, (uint) m_tbllen + 1,
5520
6919
&m_coltype, (uint) m_colcnt,
5528
6927
memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
5530
6929
ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
5531
bytes_read= ptr_after_colcnt - (unsigned char *)buf;
6930
bytes_read= ptr_after_colcnt - (uchar *)buf;
5532
6931
if (bytes_read < event_len)
5534
6933
m_field_metadata_size= net_field_length(&ptr_after_colcnt);
5535
6934
assert(m_field_metadata_size <= (m_colcnt * 2));
5536
uint32_t num_null_bytes= (m_colcnt + 7) / 8;
5537
m_meta_memory= (unsigned char *)my_multi_malloc(MYF(MY_WME),
6935
uint num_null_bytes= (m_colcnt + 7) / 8;
6936
m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
5538
6937
&m_null_bits, num_null_bytes,
5539
6938
&m_field_metadata, m_field_metadata_size,
5541
6940
memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
5542
ptr_after_colcnt= (unsigned char*)ptr_after_colcnt + m_field_metadata_size;
6941
ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
5543
6942
memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
5550
6950
Table_map_log_event::~Table_map_log_event()
5552
free(m_meta_memory);
6952
my_free(m_meta_memory, MYF(MY_ALLOW_ZERO_PTR));
6953
my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
5564
6964
4 Daisy-chaining RBR with SBR not possible
6967
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
5567
6968
int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
5569
RPL_TableList *table_list;
6970
RPL_TABLE_LIST *table_list;
5570
6971
char *db_mem, *tname_mem;
5571
Query_id &query_id= Query_id::get_query_id();
5572
6972
size_t dummy_len;
5574
assert(rli->sql_session == session);
6974
assert(rli->sql_thd == thd);
5576
6976
/* Step the query id to mark what columns that are actually used. */
5577
session->query_id= query_id.next();
6977
pthread_mutex_lock(&LOCK_thread_count);
6978
thd->query_id= next_query_id();
6979
pthread_mutex_unlock(&LOCK_thread_count);
5579
6981
if (!(memory= my_multi_malloc(MYF(MY_WME),
5580
&table_list, (uint) sizeof(RPL_TableList),
6982
&table_list, (uint) sizeof(RPL_TABLE_LIST),
5581
6983
&db_mem, (uint) NAME_LEN + 1,
5582
6984
&tname_mem, (uint) NAME_LEN + 1,
5584
6986
return(HA_ERR_OUT_OF_MEM);
5586
6988
memset(table_list, 0, sizeof(*table_list));
5590
6992
table_list->next_global= table_list->next_local= 0;
5591
6993
table_list->table_id= m_table_id;
5592
6994
table_list->updating= 1;
5593
my_stpcpy(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
5594
my_stpcpy(table_list->table_name, m_tblnam);
6995
strmov(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
6996
strmov(table_list->table_name, m_tblnam);
5598
7000
if (!rpl_filter->db_ok(table_list->db) ||
5599
7001
(rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list)))
7003
my_free(memory, MYF(MY_WME));
5606
open_tables() reads the contents of session->lex, so they must be
7008
open_tables() reads the contents of thd->lex, so they must be
5607
7009
initialized, so we should call lex_start(); to be even safer, we
5608
7010
call mysql_init_query() which does a more complete set of inits.
5611
mysql_reset_session_for_next_command(session);
7013
mysql_reset_thd_for_next_command(thd);
7015
Check if the slave is set to use SBR. If so, it should switch
7016
to using RBR until the end of the "statement", i.e., next
7017
STMT_END_F or next error.
7019
if (!thd->current_stmt_binlog_row_based &&
7020
mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
7022
thd->set_current_stmt_binlog_row_based();
5614
7026
Open the table if it is not already open and add the table to
5615
7027
table map. Note that for any table that should not be
5616
7028
replicated, a filter is needed.
5618
The creation of a new TableList is used to up-cast the
5619
table_list consisting of RPL_TableList items. This will work
7030
The creation of a new TABLE_LIST is used to up-cast the
7031
table_list consisting of RPL_TABLE_LIST items. This will work
5620
7032
since the only case where the argument to open_tables() is
5621
changed, is when session->lex->query_tables == table_list, i.e.,
7033
changed, is when thd->lex->query_tables == table_list, i.e.,
5622
7034
when the statement requires prelocking. Since this is not
5623
7035
executed when a statement is executed, this case will not occur.
5624
7036
As a precaution, an assertion is added to ensure that the bad
5628
7040
internally in the open_tables() function, hence we take a copy
5629
7041
of the pointer to make sure that it's not lost.
5632
assert(session->lex->query_tables != table_list);
5633
TableList *tmp_table_list= table_list;
5634
if ((error= open_tables(session, &tmp_table_list, &count, 0)))
7044
assert(thd->lex->query_tables != table_list);
7045
TABLE_LIST *tmp_table_list= table_list;
7046
if ((error= open_tables(thd, &tmp_table_list, &count, 0)))
5636
if (session->is_slave_error || session->is_fatal_error)
7048
if (thd->is_slave_error || thd->is_fatal_error)
5639
7051
Error reporting borrowed from Query_log_event with many excessive
5640
7052
simplifications (we don't honour --slave-skip-errors)
5642
uint32_t actual_error= session->main_da.sql_errno();
7054
uint actual_error= thd->main_da.sql_errno();
5643
7055
rli->report(ERROR_LEVEL, actual_error,
5644
_("Error '%s' on opening table `%s`.`%s`"),
5646
? session->main_da.message()
5647
: _("unexpected success or fatal error")),
7056
"Error '%s' on opening table `%s`.`%s`",
7057
(actual_error ? thd->main_da.message() :
7058
"unexpected success or fatal error"),
5648
7059
table_list->db, table_list->table_name);
5649
session->is_slave_error= 1;
7060
thd->is_slave_error= 1;
5723
7136
assert(m_dblen < 128);
5724
7137
assert(m_tbllen < 128);
5726
unsigned char const dbuf[]= { (unsigned char) m_dblen };
5727
unsigned char const tbuf[]= { (unsigned char) m_tbllen };
7139
uchar const dbuf[]= { (uchar) m_dblen };
7140
uchar const tbuf[]= { (uchar) m_tbllen };
5729
unsigned char cbuf[sizeof(m_colcnt)];
5730
unsigned char *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
7142
uchar cbuf[sizeof(m_colcnt)];
7143
uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
5731
7144
assert(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
5734
7147
Store the size of the field metadata.
5736
unsigned char mbuf[sizeof(m_field_metadata_size)];
5737
unsigned char *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
7149
uchar mbuf[sizeof(m_field_metadata_size)];
7150
uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
5739
7152
return (my_b_safe_write(file, dbuf, sizeof(dbuf)) ||
5740
my_b_safe_write(file, (const unsigned char*)m_dbnam, m_dblen+1) ||
7153
my_b_safe_write(file, (const uchar*)m_dbnam, m_dblen+1) ||
5741
7154
my_b_safe_write(file, tbuf, sizeof(tbuf)) ||
5742
my_b_safe_write(file, (const unsigned char*)m_tblnam, m_tbllen+1) ||
7155
my_b_safe_write(file, (const uchar*)m_tblnam, m_tbllen+1) ||
5743
7156
my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
5744
7157
my_b_safe_write(file, m_coltype, m_colcnt) ||
5745
7158
my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
5746
7159
my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
5747
7160
my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
7164
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5752
7167
Print some useful information for the SHOW BINARY LOG information
7171
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5756
7172
void Table_map_log_event::pack_info(Protocol *protocol)
6739
8226
set_if_smaller(ident_len,FN_REFLEN-1);
6740
8227
log_ident= buf + header_size;
8234
The default values for these variables should be values that are
8235
*incorrect*, i.e., values that cannot occur in an event. This way,
8236
they will always be printed for the first event.
8238
st_print_event_info::st_print_event_info()
8239
:flags2_inited(0), sql_mode_inited(0),
8240
auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
8241
lc_time_names_number(~0),
8242
charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
8243
thread_id(0), thread_id_printed(false),
8244
base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(false)
8247
Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
8248
program's startup, but these explicit memset() is for the day someone
8249
creates dynamic instances.
8251
memset(db, 0, sizeof(db));
8252
memset(charset, 0, sizeof(charset));
8253
memset(time_zone_str, 0, sizeof(time_zone_str));
8256
myf const flags = MYF(MY_WME | MY_NABP);
8257
open_cached_file(&head_cache, NULL, NULL, 0, flags);
8258
open_cached_file(&body_cache, NULL, NULL, 0, flags);