summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/log_event.cc570
-rw-r--r--sql/log_event.h30
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/rpl_tblmap.cc18
-rw-r--r--sql/rpl_tblmap.h7
-rw-r--r--sql/rpl_utility.h5
-rw-r--r--sql/sql_base.cc9
-rw-r--r--sql/sql_repl.cc5
8 files changed, 641 insertions, 4 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index ff6afd013c5..0690e0b4f01 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1353,6 +1353,542 @@ void Log_event::print_header(IO_CACHE* file,
}
+/**
+ Prints a quoted string to io cache.
+ Control characters are displayed as hex sequence, e.g. \x00
+
+ @param[in] file IO cache
+ @param[in] prt Pointer to string
+ @param[in] length String length
+*/
+
+static void
+my_b_write_quoted(IO_CACHE *file, const uchar *ptr, uint length)
+{
+ const uchar *s;
+ my_b_printf(file, "'");
+ for (s= ptr; length > 0 ; s++, length--)
+ {
+ if (*s > 0x1F)
+ my_b_write(file, s, 1);
+ else
+ {
+ uchar hex[10];
+ size_t len= my_snprintf((char*) hex, sizeof(hex), "%s%02x", "\\x", *s);
+ my_b_write(file, hex, len);
+ }
+ }
+ my_b_printf(file, "'");
+}
+
+
+/**
+ Prints a bit string to io cache in format b'1010'.
+
+ @param[in] file IO cache
+ @param[in] ptr Pointer to string
+ @param[in] nbits Number of bits
+*/
+static void
+my_b_write_bit(IO_CACHE *file, const uchar *ptr, uint nbits)
+{
+ uint bitnum, nbits8= ((nbits + 7) / 8) * 8, skip_bits= nbits8 - nbits;
+ my_b_printf(file, "b'");
+ for (bitnum= skip_bits ; bitnum < nbits8; bitnum++)
+ {
+ int is_set= (ptr[(bitnum) / 8] >> (7 - bitnum % 8)) & 0x01;
+ my_b_write(file, (const uchar*) (is_set ? "1" : "0"), 1);
+ }
+ my_b_printf(file, "'");
+}
+
+
+/**
+ Prints a packed string to io cache.
+ The string consists of length packed to 1 or 2 bytes,
+ followed by string data itself.
+
+ @param[in] file IO cache
+ @param[in] ptr Pointer to string
+ @param[in] length String size
+
+ @retval - number of bytes scanned.
+*/
+static size_t
+my_b_write_quoted_with_length(IO_CACHE *file, const uchar *ptr, uint length)
+{
+ if (length < 256)
+ {
+ length= *ptr;
+ my_b_write_quoted(file, ptr + 1, length);
+ return length + 1;
+ }
+ else
+ {
+ length= uint2korr(ptr);
+ my_b_write_quoted(file, ptr + 2, length);
+ return length + 2;
+ }
+}
+
+
+/**
+ Prints a 32-bit number in both signed and unsigned representation
+
+ @param[in] file IO cache
+ @param[in] sl Signed number
+ @param[in] ul Unsigned number
+*/
+static void
+my_b_write_sint32_and_uint32(IO_CACHE *file, int32 si, uint32 ui)
+{
+ my_b_printf(file, "%d", si);
+ if (si < 0)
+ my_b_printf(file, " (%u)", ui);
+}
+
+
+/**
+ Print a packed value of the given SQL type into IO cache
+
+ @param[in] file IO cache
+ @param[in] ptr Pointer to string
+ @param[in] type Column type
+ @param[in] meta Column meta information
+ @param[out] typestr SQL type string buffer (for verbose output)
+ @param[out] typestr_length Size of typestr
+
+ @retval - number of bytes scanned from ptr.
+*/
+
+static size_t
+log_event_print_value(IO_CACHE *file, const uchar *ptr,
+ uint type, uint meta,
+ char *typestr, size_t typestr_length)
+{
+ uint32 length= 0;
+
+ if (type == MYSQL_TYPE_STRING)
+ {
+ if (meta >= 256)
+ {
+ uint byte0= meta >> 8;
+ uint byte1= meta & 0xFF;
+
+ if ((byte0 & 0x30) != 0x30)
+ {
+ /* a long CHAR() field: see #37426 */
+ length= byte1 | (((byte0 & 0x30) ^ 0x30) << 4);
+ type= byte0 | 0x30;
+ goto beg;
+ }
+
+ switch (byte0)
+ {
+ case MYSQL_TYPE_SET:
+ case MYSQL_TYPE_ENUM:
+ case MYSQL_TYPE_STRING:
+ type= byte0;
+ length= byte1;
+ break;
+
+ default:
+
+ {
+ char tmp[5];
+ my_snprintf(tmp, sizeof(tmp), "%04X", meta);
+ my_b_printf(file,
+ "!! Don't know how to handle column type=%d meta=%d (%s)",
+ type, meta, tmp);
+ return 0;
+ }
+ }
+ }
+ else
+ length= meta;
+ }
+
+
+beg:
+
+ switch (type) {
+ case MYSQL_TYPE_LONG:
+ {
+ int32 si= sint4korr(ptr);
+ uint32 ui= uint4korr(ptr);
+ my_b_write_sint32_and_uint32(file, si, ui);
+ my_snprintf(typestr, typestr_length, "INT");
+ return 4;
+ }
+
+ case MYSQL_TYPE_TINY:
+ {
+ my_b_write_sint32_and_uint32(file, (int) (signed char) *ptr,
+ (uint) (unsigned char) *ptr);
+ my_snprintf(typestr, typestr_length, "TINYINT");
+ return 1;
+ }
+
+ case MYSQL_TYPE_SHORT:
+ {
+ int32 si= (int32) sint2korr(ptr);
+ uint32 ui= (uint32) uint2korr(ptr);
+ my_b_write_sint32_and_uint32(file, si, ui);
+ my_snprintf(typestr, typestr_length, "SHORTINT");
+ return 2;
+ }
+
+ case MYSQL_TYPE_INT24:
+ {
+ int32 si= sint3korr(ptr);
+ uint32 ui= uint3korr(ptr);
+ my_b_write_sint32_and_uint32(file, si, ui);
+ my_snprintf(typestr, typestr_length, "MEDIUMINT");
+ return 3;
+ }
+
+ case MYSQL_TYPE_LONGLONG:
+ {
+ char tmp[64];
+ longlong si= sint8korr(ptr);
+ longlong10_to_str(si, tmp, -10);
+ my_b_printf(file, "%s", tmp);
+ if (si < 0)
+ {
+ ulonglong ui= uint8korr(ptr);
+ longlong10_to_str((longlong) ui, tmp, 10);
+ my_b_printf(file, " (%s)", tmp);
+ }
+ my_snprintf(typestr, typestr_length, "LONGINT");
+ return 8;
+ }
+
+ case MYSQL_TYPE_NEWDECIMAL:
+ {
+ uint precision= meta >> 8;
+ uint decimals= meta & 0xFF;
+ uint bin_size= my_decimal_get_binary_size(precision, decimals);
+ my_decimal dec;
+ binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) ptr, &dec,
+ precision, decimals);
+ int i, end;
+ char buff[512], *pos;
+ pos= buff;
+ pos+= my_sprintf(buff, (buff, "%s", dec.sign() ? "-" : ""));
+ end= ROUND_UP(dec.frac) + ROUND_UP(dec.intg)-1;
+ for (i=0; i < end; i++)
+ pos+= my_sprintf(pos, (pos, "%09d.", dec.buf[i]));
+ pos+= my_sprintf(pos, (pos, "%09d", dec.buf[i]));
+ my_b_printf(file, "%s", buff);
+ my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)",
+ precision, decimals);
+ return bin_size;
+ }
+
+ case MYSQL_TYPE_FLOAT:
+ {
+ float fl;
+ float4get(fl, ptr);
+ char tmp[320];
+ sprintf(tmp, "%-20g", (double) fl);
+ my_b_printf(file, "%s", tmp); /* my_snprintf doesn't support %-20g */
+ my_snprintf(typestr, typestr_length, "FLOAT");
+ return 4;
+ }
+
+ case MYSQL_TYPE_DOUBLE:
+ {
+ double dbl;
+ doubleget(dbl, ptr);
+ char tmp[320];
+ sprintf(tmp, "%-.20g", dbl); /* my_snprintf doesn't support %-20g */
+ my_b_printf(file, "%s", tmp);
+ strcpy(typestr, "DOUBLE");
+ return 8;
+ }
+
+ case MYSQL_TYPE_BIT:
+ {
+ /* Meta-data: bit_len, bytes_in_rec, 2 bytes */
+ uint nbits= ((meta >> 8) * 8) + (meta & 0xFF);
+ length= (nbits + 7) / 8;
+ my_b_write_bit(file, ptr, nbits);
+ my_snprintf(typestr, typestr_length, "BIT(%d)", nbits);
+ return length;
+ }
+
+ case MYSQL_TYPE_TIMESTAMP:
+ {
+ uint32 i32= uint4korr(ptr);
+ my_b_printf(file, "%d", i32);
+ my_snprintf(typestr, typestr_length, "TIMESTAMP");
+ return 4;
+ }
+
+ case MYSQL_TYPE_DATETIME:
+ {
+ uint d, t;
+ uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
+ d= i64 / 1000000;
+ t= i64 % 1000000;
+ my_b_printf(file, "%04d-%02d-%02d %02d:%02d:%02d",
+ d / 10000, (d % 10000) / 100, d % 100,
+ t / 10000, (t % 10000) / 100, t % 100);
+ my_snprintf(typestr, typestr_length, "DATETIME");
+ return 8;
+ }
+
+ case MYSQL_TYPE_TIME:
+ {
+ uint32 i32= uint3korr(ptr);
+ my_b_printf(file, "'%02d:%02d:%02d'",
+ i32 / 10000, (i32 % 10000) / 100, i32 % 100);
+ my_snprintf(typestr, typestr_length, "TIME");
+ return 3;
+ }
+
+ case MYSQL_TYPE_DATE:
+ {
+ uint i32= uint3korr(ptr);
+ my_b_printf(file , "'%04d:%02d:%02d'",
+ (i32 / (16L * 32L)), (i32 / 32L % 16L), (i32 % 32L));
+ my_snprintf(typestr, typestr_length, "DATE");
+ return 3;
+ }
+
+ case MYSQL_TYPE_YEAR:
+ {
+ uint32 i32= *ptr;
+ my_b_printf(file, "%04d", i32+ 1900);
+ my_snprintf(typestr, typestr_length, "YEAR");
+ return 1;
+ }
+
+ case MYSQL_TYPE_ENUM:
+ switch (length) {
+ case 1:
+ my_b_printf(file, "%d", (int) *ptr);
+ my_snprintf(typestr, typestr_length, "ENUM(1 byte)");
+ return 1;
+ case 2:
+ {
+ int32 i32= uint2korr(ptr);
+ my_b_printf(file, "%d", i32);
+ my_snprintf(typestr, typestr_length, "ENUM(2 bytes)");
+ return 2;
+ }
+ default:
+ my_b_printf(file, "!! Unknown ENUM packlen=%d", length);
+ return 0;
+ }
+ break;
+
+ case MYSQL_TYPE_SET:
+ my_b_write_bit(file, ptr , length * 8);
+ my_snprintf(typestr, typestr_length, "SET(%d bytes)", length);
+ return length;
+
+ case MYSQL_TYPE_BLOB:
+ switch (meta) {
+ case 1:
+ length= *ptr;
+ my_b_write_quoted(file, ptr + 1, length);
+ my_snprintf(typestr, typestr_length, "TINYBLOB/TINYTEXT");
+ return length + 1;
+ case 2:
+ length= uint2korr(ptr);
+ my_b_write_quoted(file, ptr + 2, length);
+ my_snprintf(typestr, typestr_length, "BLOB/TEXT");
+ return length + 2;
+ case 3:
+ length= uint3korr(ptr);
+ my_b_write_quoted(file, ptr + 3, length);
+ my_snprintf(typestr, typestr_length, "MEDIUMBLOB/MEDIUMTEXT");
+ return length + 3;
+ case 4:
+ length= uint4korr(ptr);
+ my_b_write_quoted(file, ptr + 4, length);
+ my_snprintf(typestr, typestr_length, "LONGBLOB/LONGTEXT");
+ return length + 4;
+ default:
+ my_b_printf(file, "!! Unknown BLOB packlen=%d", length);
+ return 0;
+ }
+
+ case MYSQL_TYPE_VARCHAR:
+ case MYSQL_TYPE_VAR_STRING:
+ length= meta;
+ my_snprintf(typestr, typestr_length, "VARSTRING(%d)", length);
+ return my_b_write_quoted_with_length(file, ptr, length);
+
+ case MYSQL_TYPE_STRING:
+ my_snprintf(typestr, typestr_length, "STRING(%d)", length);
+ return my_b_write_quoted_with_length(file, ptr, length);
+
+ default:
+ {
+ char tmp[5];
+ my_snprintf(tmp, sizeof(tmp), "%04x", meta);
+ my_b_printf(file,
+ "!! Don't know how to handle column type=%d meta=%d (%s)",
+ type, meta, tmp);
+ }
+ break;
+ }
+ *typestr= 0;
+ return 0;
+}
+
+
+/**
+ Print a packed row into IO cache
+
+ @param[in] file IO cache
+ @param[in] td Table definition
+ @param[in] print_event_into Print parameters
+ @param[in] cols_bitmap Column bitmaps.
+ @param[in] value Pointer to packed row
+ @param[in] prefix Row's SQL clause ("SET", "WHERE", etc)
+
+ @retval - number of bytes scanned.
+*/
+
+
+size_t
+Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
+ PRINT_EVENT_INFO *print_event_info,
+ MY_BITMAP *cols_bitmap,
+ const uchar *value, const uchar *prefix)
+{
+ const uchar *value0= value;
+ const uchar *null_bits= value;
+ char typestr[64]= "";
+
+ value+= (m_width + 7) / 8;
+
+ my_b_printf(file, "%s", prefix);
+
+ for (size_t i= 0; i < td->size(); i ++)
+ {
+ int is_null= (null_bits[i / 8] >> (i % 8)) & 0x01;
+
+ if (bitmap_is_set(cols_bitmap, i) == 0)
+ continue;
+
+ if (is_null)
+ {
+ my_b_printf(file, "### @%d=NULL", i + 1);
+ }
+ else
+ {
+ my_b_printf(file, "### @%d=", i + 1);
+ size_t size= log_event_print_value(file, value,
+ td->type(i), td->field_metadata(i),
+ typestr, sizeof(typestr));
+ if (!size)
+ return 0;
+
+ value+= size;
+ }
+
+ if (print_event_info->verbose > 1)
+ {
+ my_b_printf(file, " /* ");
+
+ if (typestr[0])
+ my_b_printf(file, "%s ", typestr);
+ else
+ my_b_printf(file, "type=%d ", td->type(i));
+
+ my_b_printf(file, "meta=%d nullable=%d is_null=%d ",
+ td->field_metadata(i),
+ td->maybe_null(i), is_null);
+ my_b_printf(file, "*/");
+ }
+
+ my_b_printf(file, "\n");
+ }
+ return value - value0;
+}
+
+
+/**
+ Print a row event into IO cache in human readable form (in SQL format)
+
+ @param[in] file IO cache
+ @param[in] print_event_into Print parameters
+*/
+void Rows_log_event::print_verbose(IO_CACHE *file,
+ PRINT_EVENT_INFO *print_event_info)
+{
+ Table_map_log_event *map;
+ table_def *td;
+ const char *sql_command, *sql_clause1, *sql_clause2;
+ Log_event_type type_code= get_type_code();
+
+ switch (type_code) {
+ case WRITE_ROWS_EVENT:
+ sql_command= "INSERT INTO";
+ sql_clause1= "### SET\n";
+ sql_clause2= NULL;
+ break;
+ case DELETE_ROWS_EVENT:
+ sql_command= "DELETE FROM";
+ sql_clause1= "### WHERE\n";
+ sql_clause2= NULL;
+ break;
+ case UPDATE_ROWS_EVENT:
+ sql_command= "UPDATE";
+ sql_clause1= "### WHERE\n";
+ sql_clause2= "### SET\n";
+ break;
+ default:
+ sql_command= sql_clause1= sql_clause2= NULL;
+ DBUG_ASSERT(0); /* Not possible */
+ }
+
+ if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
+ !(td= map->create_table_def()))
+ {
+ my_b_printf(file, "### Row event for unknown table #%d", m_table_id);
+ return;
+ }
+
+ for (const uchar *value= m_rows_buf; value < m_rows_end; )
+ {
+ size_t length;
+ my_b_printf(file, "### %s %s.%s\n",
+ sql_command,
+ map->get_db_name(), map->get_table_name());
+ /* Print the first image */
+ if (!(length= print_verbose_one_row(file, td, print_event_info,
+ &m_cols_ai, value,
+ (const uchar*) sql_clause1)))
+ goto end;
+ value+= length;
+
+ /* Print the second image (for UPDATE only) */
+ if (sql_clause2)
+ {
+ if (!(length= print_verbose_one_row(file, td, print_event_info,
+ &m_cols, value,
+ (const uchar*) sql_clause2)))
+ goto end;
+ value+= length;
+ }
+ }
+
+end:
+ delete td;
+}
+
+#ifdef MYSQL_CLIENT
+void free_table_map_log_event(Table_map_log_event *event)
+{
+ delete event;
+}
+#endif
+
void Log_event::print_base64(IO_CACHE* file,
PRINT_EVENT_INFO* print_event_info,
bool more)
@@ -1382,6 +1918,40 @@ void Log_event::print_base64(IO_CACHE* file,
if (!more)
my_b_printf(file, "'%s\n", print_event_info->delimiter);
+ if (print_event_info->verbose)
+ {
+ Rows_log_event *ev= NULL;
+
+ if (ptr[4] == TABLE_MAP_EVENT)
+ {
+ Table_map_log_event *map;
+ map= new Table_map_log_event((const char*) ptr, size,
+ glob_description_event);
+ print_event_info->m_table_map.set_table(map->get_table_id(), map);
+ }
+ else if (ptr[4] == WRITE_ROWS_EVENT)
+ {
+ ev= new Write_rows_log_event((const char*) ptr, size,
+ glob_description_event);
+ }
+ else if (ptr[4] == DELETE_ROWS_EVENT)
+ {
+ ev= new Delete_rows_log_event((const char*) ptr, size,
+ glob_description_event);
+ }
+ else if (ptr[4] == UPDATE_ROWS_EVENT)
+ {
+ ev= new Update_rows_log_event((const char*) ptr, size,
+ glob_description_event);
+ }
+
+ if (ev)
+ {
+ ev->print_verbose(file, print_event_info);
+ delete ev;
+ }
+ }
+
my_free(tmp_str, MYF(0));
DBUG_VOID_RETURN;
}
diff --git a/sql/log_event.h b/sql/log_event.h
index 76d92b23189..e1b00474361 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -34,6 +34,14 @@
#include <my_bitmap.h>
#include "rpl_constants.h"
+
+#ifdef MYSQL_CLIENT
+#include "rpl_utility.h"
+#include "hash.h"
+#include "rpl_tblmap.h"
+#include "rpl_tblmap.cc"
+#endif
+
#ifndef MYSQL_CLIENT
#include "rpl_record.h"
#include "rpl_reporting.h"
@@ -634,6 +642,11 @@ typedef struct st_print_event_info
uint8 common_header_len;
char delimiter[16];
+#ifdef MYSQL_CLIENT
+ uint verbose;
+ table_mapping m_table_map;
+#endif
+
/*
These two caches are used by the row-based replication events to
collect the header information and the main body of the events
@@ -3235,6 +3248,17 @@ public:
~Table_map_log_event();
+#ifdef MYSQL_CLIENT
+ table_def *create_table_def()
+ {
+ return new table_def(m_coltype, m_colcnt, m_field_metadata,
+ m_field_metadata_size, m_null_bits);
+ }
+ ulong get_table_id() const { return m_table_id; }
+ const char *get_table_name() const { return m_tblnam; }
+ const char *get_db_name() const { return m_dbnam; }
+#endif
+
virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; }
virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ }
@@ -3365,6 +3389,12 @@ public:
#ifdef MYSQL_CLIENT
/* not for direct call, each derived has its own ::print() */
virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0;
+ void print_verbose(IO_CACHE *file,
+ PRINT_EVENT_INFO *print_event_info);
+ size_t print_verbose_one_row(IO_CACHE *file, table_def *td,
+ PRINT_EVENT_INFO *print_event_info,
+ MY_BITMAP *cols_bitmap,
+ const uchar *ptr, const uchar *prefix);
#endif
#ifndef MYSQL_CLIENT
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index f6ba5fc9739..c9a806ef74a 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1078,6 +1078,7 @@ void table_cache_free(void);
bool table_def_init(void);
void table_def_free(void);
void assign_new_table_id(TABLE_SHARE *share);
+void reset_table_id_sequence();
uint cached_open_tables(void);
uint cached_table_definitions(void);
void kill_mysql(void);
diff --git a/sql/rpl_tblmap.cc b/sql/rpl_tblmap.cc
index 6c8b494dfa9..a004c354263 100644
--- a/sql/rpl_tblmap.cc
+++ b/sql/rpl_tblmap.cc
@@ -19,7 +19,11 @@
#include "rpl_tblmap.h"
+#ifdef MYSQL_CLIENT
+#define MAYBE_TABLE_NAME(T) ("")
+#else
#define MAYBE_TABLE_NAME(T) ((T) ? (T)->s->table_name.str : "<>")
+#endif
#define TABLE_ID_HASH_SIZE 32
#define TABLE_ID_CHUNK 256
@@ -42,11 +46,14 @@ table_mapping::table_mapping()
table_mapping::~table_mapping()
{
+#ifdef MYSQL_CLIENT
+ clear_tables();
+#endif
hash_free(&m_table_ids);
free_root(&m_mem_root, MYF(0));
}
-st_table* table_mapping::get_table(ulong table_id)
+TABLE* table_mapping::get_table(ulong table_id)
{
DBUG_ENTER("table_mapping::get_table(ulong)");
DBUG_PRINT("enter", ("table_id: %lu", table_id));
@@ -104,8 +111,12 @@ int table_mapping::set_table(ulong table_id, TABLE* table)
m_free= m_free->next;
}
else
+ {
+#ifdef MYSQL_CLIENT
+ free_table_map_log_event(e->table);
+#endif
hash_delete(&m_table_ids,(uchar *)e);
-
+ }
e->table_id= table_id;
e->table= table;
my_hash_insert(&m_table_ids,(uchar *)e);
@@ -140,6 +151,9 @@ void table_mapping::clear_tables()
for (uint i= 0; i < m_table_ids.records; i++)
{
entry *e= (entry *)hash_element(&m_table_ids, i);
+#ifdef MYSQL_CLIENT
+ free_table_map_log_event(e->table);
+#endif
e->next= m_free;
m_free= e;
}
diff --git a/sql/rpl_tblmap.h b/sql/rpl_tblmap.h
index 446833d5ed6..3b5b10be580 100644
--- a/sql/rpl_tblmap.h
+++ b/sql/rpl_tblmap.h
@@ -17,8 +17,15 @@
#define TABLE_MAPPING_H
/* Forward declarations */
+#ifndef MYSQL_CLIENT
struct st_table;
typedef st_table TABLE;
+#else
+class Table_map_log_event;
+typedef Table_map_log_event TABLE;
+void free_table_map_log_event(TABLE *table);
+#endif
+
/*
CLASS table_mapping
diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h
index 375715c7858..8e2f4a7374f 100644
--- a/sql/rpl_utility.h
+++ b/sql/rpl_utility.h
@@ -236,7 +236,9 @@ public:
@retval 1 if the table definition is not compatible with @c table
@retval 0 if the table definition is compatible with @c table
*/
+#ifndef MYSQL_CLIENT
int compatible_with(Relay_log_info const *rli, TABLE *table) const;
+#endif
private:
ulong m_size; // Number of elements in the types array
@@ -247,6 +249,8 @@ private:
uchar *m_memory;
};
+
+#ifndef MYSQL_CLIENT
/**
Extend the normal table list with a few new fields needed by the
slave thread, but nowhere else.
@@ -288,6 +292,7 @@ namespace {
};
}
+#endif
#define DBUG_PRINT_BITSET(N,FRM,BS) \
do { \
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 39dd815e738..6d394e04b4a 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -3693,9 +3693,10 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name)
share->table_map_id is not ~0UL.
*/
+static ulong last_table_id= ~0UL;
+
void assign_new_table_id(TABLE_SHARE *share)
{
- static ulong last_table_id= ~0UL;
DBUG_ENTER("assign_new_table_id");
@@ -3719,6 +3720,12 @@ void assign_new_table_id(TABLE_SHARE *share)
DBUG_VOID_RETURN;
}
+void reset_table_id_sequence()
+{
+ pthread_mutex_lock(&LOCK_open);
+ last_table_id= ~0UL;
+ pthread_mutex_unlock(&LOCK_open);
+}
/**
Compare metadata versions of an element obtained from the table
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 932b7a67b4d..44f4e8ffee8 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1285,13 +1285,16 @@ bool change_master(THD* thd, Master_info* mi)
int reset_master(THD* thd)
{
+ int rc;
if (!mysql_bin_log.is_open())
{
my_message(ER_FLUSH_MASTER_BINLOG_CLOSED,
ER(ER_FLUSH_MASTER_BINLOG_CLOSED), MYF(ME_BELL+ME_WAITTANG));
return 1;
}
- return mysql_bin_log.reset_logs(thd);
+ if (!(rc= mysql_bin_log.reset_logs(thd)))
+ reset_table_id_sequence();
+ return rc;
}
int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,