mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge mysqldev@production.mysql.com:my/mysql-5.1-release
into mysql.com:/home/bk/w3023-mysql-5.1-new
This commit is contained in:
429
sql/log_event.cc
429
sql/log_event.cc
@@ -1685,6 +1685,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, const char *query
|
||||
DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
|
||||
|
||||
clear_all_errors(thd, rli);
|
||||
rli->clear_tables_to_lock();
|
||||
|
||||
/*
|
||||
Note: We do not need to execute reset_one_shot_variables() if this
|
||||
@@ -5063,17 +5064,19 @@ char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
|
||||
Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
|
||||
MY_BITMAP const *cols, bool is_transactional)
|
||||
: Log_event(thd_arg, 0, is_transactional),
|
||||
m_row_count(0),
|
||||
m_table(tbl_arg),
|
||||
m_table_id(tid),
|
||||
m_width(tbl_arg->s->fields),
|
||||
m_rows_buf((byte*)my_malloc(opt_binlog_rows_event_max_size *
|
||||
sizeof(*m_rows_buf), MYF(MY_WME))),
|
||||
m_rows_cur(m_rows_buf),
|
||||
m_rows_end(m_rows_buf + opt_binlog_rows_event_max_size),
|
||||
m_width(tbl_arg ? tbl_arg->s->fields : 1),
|
||||
m_rows_buf(0), m_rows_cur(0), m_rows_end(0),
|
||||
m_flags(0)
|
||||
{
|
||||
DBUG_ASSERT(m_table && m_table->s);
|
||||
DBUG_ASSERT(m_table_id != ULONG_MAX);
|
||||
/*
|
||||
We allow a special form of dummy event when the table, and cols
|
||||
are null and the table id is ULONG_MAX.
|
||||
*/
|
||||
DBUG_ASSERT(tbl_arg && tbl_arg->s && tid != ULONG_MAX ||
|
||||
!tbl_arg && !cols && tid == ULONG_MAX);
|
||||
|
||||
if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
|
||||
set_flags(NO_FOREIGN_KEY_CHECKS_F);
|
||||
@@ -5084,7 +5087,11 @@ Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
|
||||
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
|
||||
(m_width + 7) & ~7UL,
|
||||
false)))
|
||||
memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols));
|
||||
{
|
||||
/* Cols can be zero if this is a dummy binrows event */
|
||||
if (likely(cols != NULL))
|
||||
memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols));
|
||||
}
|
||||
else
|
||||
m_cols.bitmap= 0; // to not free it
|
||||
}
|
||||
@@ -5095,6 +5102,7 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
|
||||
const Format_description_log_event
|
||||
*description_event)
|
||||
: Log_event(buf, description_event),
|
||||
m_row_count(0),
|
||||
m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
|
||||
{
|
||||
DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
|
||||
@@ -5120,8 +5128,6 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
|
||||
post_start+= RW_FLAGS_OFFSET;
|
||||
}
|
||||
|
||||
DBUG_ASSERT(m_table_id != ULONG_MAX);
|
||||
|
||||
m_flags= uint2korr(post_start);
|
||||
|
||||
byte const *const var_start= (const byte *)buf + common_header_len +
|
||||
@@ -5178,7 +5184,7 @@ int Rows_log_event::do_add_row_data(byte *const row_data,
|
||||
DBUG_DUMP("row_data", (const char*)row_data, min(length, 32));
|
||||
|
||||
DBUG_ASSERT(m_rows_buf <= m_rows_cur);
|
||||
DBUG_ASSERT(m_rows_buf < m_rows_end);
|
||||
DBUG_ASSERT(!m_rows_buf || m_rows_end && m_rows_buf < m_rows_end);
|
||||
DBUG_ASSERT(m_rows_cur <= m_rows_end);
|
||||
|
||||
/* The cast will always work since m_rows_cur <= m_rows_end */
|
||||
@@ -5186,12 +5192,12 @@ int Rows_log_event::do_add_row_data(byte *const row_data,
|
||||
{
|
||||
my_size_t const block_size= 1024;
|
||||
my_ptrdiff_t const old_alloc= m_rows_end - m_rows_buf;
|
||||
my_ptrdiff_t const new_alloc=
|
||||
old_alloc + block_size * (length / block_size + block_size - 1);
|
||||
my_ptrdiff_t const cur_size= m_rows_cur - m_rows_buf;
|
||||
my_ptrdiff_t const new_alloc=
|
||||
block_size * ((cur_size + length) / block_size + block_size - 1);
|
||||
|
||||
byte* const new_buf=
|
||||
(byte*)my_realloc((gptr)m_rows_buf, new_alloc, MYF(MY_WME));
|
||||
byte* const new_buf= (byte*)my_realloc((gptr)m_rows_buf, new_alloc,
|
||||
MYF(MY_ALLOW_ZERO_PTR|MY_WME));
|
||||
if (unlikely(!new_buf))
|
||||
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
||||
|
||||
@@ -5212,6 +5218,7 @@ int Rows_log_event::do_add_row_data(byte *const row_data,
|
||||
DBUG_ASSERT(m_rows_cur + length < m_rows_end);
|
||||
memcpy(m_rows_cur, row_data, length);
|
||||
m_rows_cur+= length;
|
||||
m_row_count++;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
#endif
|
||||
@@ -5255,10 +5262,29 @@ static char const *unpack_row(TABLE *table,
|
||||
int Rows_log_event::exec_event(st_relay_log_info *rli)
|
||||
{
|
||||
DBUG_ENTER("Rows_log_event::exec_event(st_relay_log_info*)");
|
||||
DBUG_ASSERT(m_table_id != ULONG_MAX);
|
||||
int error= 0;
|
||||
char const *row_start= (char const *)m_rows_buf;
|
||||
TABLE* table= rli->m_table_map.get_table(m_table_id);
|
||||
|
||||
/*
|
||||
If m_table_id == ULONG_MAX, then we have a dummy event that does
|
||||
not contain any data. In that case, we just remove all tables in
|
||||
the tables_to_lock list, close the thread tables, step the relay
|
||||
log position, and return with success.
|
||||
*/
|
||||
if (m_table_id == ULONG_MAX)
|
||||
{
|
||||
/*
|
||||
This one is supposed to be set: just an extra check so that
|
||||
nothing strange has happened.
|
||||
*/
|
||||
DBUG_ASSERT(get_flags(STMT_END_F));
|
||||
|
||||
rli->clear_tables_to_lock();
|
||||
close_thread_tables(thd);
|
||||
thd->clear_error();
|
||||
rli->inc_event_relay_log_pos();
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
'thd' has been set by exec_relay_log_event(), just before calling
|
||||
@@ -5267,85 +5293,51 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
|
||||
DBUG_ASSERT(rli->sql_thd == thd);
|
||||
|
||||
/*
|
||||
lock_tables() reads the contents of thd->lex, so they must be
|
||||
initialized, so we should call lex_start(); to be even safer, we call
|
||||
mysql_init_query() which does a more complete set of inits.
|
||||
If there is no locks taken, this is the first binrow event seen
|
||||
after the table map events. We should then lock all the tables
|
||||
used in the transaction and proceed with execution of the actual
|
||||
event.
|
||||
*/
|
||||
mysql_init_query(thd, NULL, 0);
|
||||
|
||||
if (table)
|
||||
if (!thd->lock)
|
||||
{
|
||||
bool need_reopen= 1; /* To execute the first lap of the loop below */
|
||||
|
||||
/*
|
||||
table == NULL means that this table should not be
|
||||
replicated (this was set up by Table_map_log_event::exec_event() which
|
||||
tested replicate-* rules).
|
||||
lock_tables() reads the contents of thd->lex, so they must be
|
||||
initialized, so we should call lex_start(); to be even safer, we
|
||||
call mysql_init_query() which does a more complete set of inits.
|
||||
*/
|
||||
TABLE_LIST table_list;
|
||||
bool need_reopen;
|
||||
uint count= 1;
|
||||
bzero(&table_list, sizeof(table_list));
|
||||
table_list.lock_type= TL_WRITE;
|
||||
table_list.next_global= table_list.next_local= 0;
|
||||
table_list.table= table;
|
||||
mysql_init_query(thd, NULL, 0);
|
||||
|
||||
for ( ; ; )
|
||||
while ((error= lock_tables(thd, rli->tables_to_lock,
|
||||
rli->tables_to_lock_count, &need_reopen)))
|
||||
{
|
||||
table_list.db= const_cast<char*>(table->s->db.str);
|
||||
table_list.alias= table_list.table_name=
|
||||
const_cast<char*>(table->s->table_name.str);
|
||||
|
||||
if ((error= lock_tables(thd, &table_list, count, &need_reopen)) == 0)
|
||||
break;
|
||||
if (!need_reopen)
|
||||
{
|
||||
slave_print_msg(ERROR_LEVEL, rli, error,
|
||||
"Error in %s event: error during table %s.%s lock",
|
||||
get_type_str(), table->s->db.str,
|
||||
table->s->table_name.str);
|
||||
"Error in %s event: when locking tables",
|
||||
get_type_str());
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
/*
|
||||
we need to store a local copy of the table names since the table object
|
||||
will become invalid after close_tables_for_reopen
|
||||
*/
|
||||
char *db= my_strdup(table->s->db.str, MYF(MY_WME));
|
||||
char *table_name= my_strdup(table->s->table_name.str, MYF(MY_WME));
|
||||
|
||||
if (db == 0 || table_name == 0)
|
||||
{
|
||||
/*
|
||||
Since the lock_tables() failed, the table is not locked, so
|
||||
we don't need to unlock them.
|
||||
*/
|
||||
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
||||
}
|
||||
|
||||
/*
|
||||
We also needs to flush the pending RBR event, since it keeps a
|
||||
pointer to an open table.
|
||||
So we need to reopen the tables.
|
||||
|
||||
ALTERNATIVE SOLUTION: Extract a pointer to the pending RBR
|
||||
event and reset the table pointer after the tables has been
|
||||
reopened.
|
||||
We need to flush the pending RBR event, since it keeps a
|
||||
pointer to an open table.
|
||||
|
||||
ALTERNATIVE SOLUTION (not implemented): Extract a pointer to
|
||||
the pending RBR event and reset the table pointer after the
|
||||
tables has been reopened.
|
||||
|
||||
NOTE: For this new scheme there should be no pending event:
|
||||
need to add code to assert that is the case.
|
||||
*/
|
||||
thd->binlog_flush_pending_rows_event(false);
|
||||
close_tables_for_reopen(thd, rli->tables_to_lock);
|
||||
|
||||
close_tables_for_reopen(thd, &table_list);
|
||||
|
||||
/* open the table again, same as in Table_map_event::exec_event */
|
||||
table_list.db= const_cast<char*>(db);
|
||||
table_list.alias= table_list.table_name= const_cast<char*>(table_name);
|
||||
table_list.updating= 1;
|
||||
TABLE_LIST *tables= &table_list;
|
||||
if ((error= open_tables(thd, &tables, &count, 0)) == 0)
|
||||
{
|
||||
/* reset some variables for the table list*/
|
||||
table_list.updating= 0;
|
||||
/* retrieve the new table reference and update the table map */
|
||||
table= table_list.table;
|
||||
error= rli->m_table_map.set_table(m_table_id, table);
|
||||
}
|
||||
else /* error in open_tables */
|
||||
if ((error= open_tables(thd, &rli->tables_to_lock,
|
||||
&rli->tables_to_lock_count, 0)))
|
||||
{
|
||||
if (thd->query_error || thd->is_fatal_error)
|
||||
{
|
||||
@@ -5355,19 +5347,41 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
|
||||
*/
|
||||
uint actual_error= thd->net.last_errno;
|
||||
slave_print_msg(ERROR_LEVEL, rli, actual_error,
|
||||
"Error '%s' on reopening table `%s`.`%s`",
|
||||
"Error '%s' on reopening tables",
|
||||
(actual_error ? thd->net.last_error :
|
||||
"unexpected success or fatal error"),
|
||||
db, table_name);
|
||||
"unexpected success or fatal error"));
|
||||
thd->query_error= 1;
|
||||
}
|
||||
}
|
||||
my_free((char*) db, MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free((char*) table_name, MYF(MY_ALLOW_ZERO_PTR));
|
||||
|
||||
if (error)
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
}
|
||||
/*
|
||||
When the open and locking succeeded, we add all the tables to
|
||||
the table map and remove them from tables to lock.
|
||||
*/
|
||||
|
||||
TABLE_LIST *ptr= rli->tables_to_lock;
|
||||
while (ptr)
|
||||
{
|
||||
rli->m_table_map.set_table(ptr->table_id, ptr->table);
|
||||
rli->touching_table(ptr->db, ptr->table_name, ptr->table_id);
|
||||
char *to_free= reinterpret_cast<char*>(ptr);
|
||||
ptr= ptr->next_global;
|
||||
my_free(to_free, MYF(MY_WME));
|
||||
}
|
||||
rli->tables_to_lock= 0;
|
||||
rli->tables_to_lock_count= 0;
|
||||
}
|
||||
|
||||
TABLE* table= rli->m_table_map.get_table(m_table_id);
|
||||
|
||||
if (table)
|
||||
{
|
||||
/*
|
||||
table == NULL means that this table should not be replicated
|
||||
(this was set up by Table_map_log_event::exec_event() which
|
||||
tested replicate-* rules).
|
||||
*/
|
||||
|
||||
/*
|
||||
It's not needed to set_time() but
|
||||
@@ -5401,12 +5415,16 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
|
||||
DBUG_ASSERT(row_end != NULL); // cannot happen
|
||||
DBUG_ASSERT(row_end <= (const char*)m_rows_end);
|
||||
|
||||
#if 0
|
||||
/* in_use can have been set to NULL in close_tables_for_reopen */
|
||||
THD* old_thd= table->in_use;
|
||||
if (!table->in_use)
|
||||
table->in_use= thd;
|
||||
#endif
|
||||
error= do_exec_row(table);
|
||||
#if 0
|
||||
table->in_use = old_thd;
|
||||
#endif
|
||||
switch (error)
|
||||
{
|
||||
/* Some recoverable errors */
|
||||
@@ -5520,52 +5538,25 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
if (table)
|
||||
if (table && (table->s->primary_key == MAX_KEY) && !cache_stmt)
|
||||
{
|
||||
/*
|
||||
As "table" is not NULL, we did a successful lock_tables(), without any
|
||||
prior LOCK TABLES and are not in prelocked mode, so this assertion should
|
||||
be true.
|
||||
------------ Temporary fix until WL#2975 is implemented ---------
|
||||
|
||||
This event is not the last one (no STMT_END_F). If we stop now
|
||||
(in case of terminate_slave_thread()), how will we restart? We
|
||||
have to restart from Table_map_log_event, but as this table is
|
||||
not transactional, the rows already inserted will still be
|
||||
present, and idempotency is not guaranteed (no PK) so we risk
|
||||
that repeating leads to double insert. So we desperately try to
|
||||
continue, hope we'll eventually leave this buggy situation (by
|
||||
executing the final Rows_log_event). If we are in a hopeless
|
||||
wait (reached end of last relay log and nothing gets appended
|
||||
there), we timeout after one minute, and notify DBA about the
|
||||
problem. When WL#2975 is implemented, just remove the member
|
||||
st_relay_log_info::unsafe_to_stop_at and all its occurences.
|
||||
*/
|
||||
DBUG_ASSERT(thd->lock);
|
||||
/*
|
||||
If we are here, there are more events to come which may use our mappings
|
||||
and our table. So don't clear mappings or close tables, just unlock
|
||||
tables.
|
||||
Why don't we lock the table once for all in
|
||||
Table_map_log_event::exec_event() ? Because we could have in binlog:
|
||||
BEGIN;
|
||||
Table_map t1 -> 1
|
||||
Write_rows to id 1
|
||||
Table_map t2 -> 2
|
||||
Write_rows to id 2
|
||||
Xid_log_event
|
||||
So we cannot lock t1 when executing the first Table_map, because at that
|
||||
moment we don't know we'll also have to lock t2, and all tables must be
|
||||
locked at once in MySQL.
|
||||
*/
|
||||
mysql_unlock_tables(thd, thd->lock);
|
||||
thd->lock= 0;
|
||||
if ((table->s->primary_key == MAX_KEY) &&
|
||||
!cache_stmt)
|
||||
{
|
||||
/*
|
||||
------------ Temporary fix until WL#2975 is implemented ---------
|
||||
This event is not the last one (no STMT_END_F). If we stop now (in
|
||||
case of terminate_slave_thread()), how will we restart? We have to
|
||||
restart from Table_map_log_event, but as this table is not
|
||||
transactional, the rows already inserted will still be present, and
|
||||
idempotency is not guaranteed (no PK) so we risk that repeating leads
|
||||
to double insert. So we desperately try to continue, hope we'll
|
||||
eventually leave this buggy situation (by executing the final
|
||||
Rows_log_event). If we are in a hopeless wait (reached end of last
|
||||
relay log and nothing gets appended there), we timeout after one
|
||||
minute, and notify DBA about the problem.
|
||||
When WL#2975 is implemented, just remove the member
|
||||
st_relay_log_info::unsafe_to_stop_at and all its occurences.
|
||||
*/
|
||||
rli->unsafe_to_stop_at= time(0);
|
||||
}
|
||||
rli->unsafe_to_stop_at= time(0);
|
||||
}
|
||||
|
||||
DBUG_ASSERT(error == 0);
|
||||
@@ -5579,7 +5570,6 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool Rows_log_event::write_data_header(IO_CACHE *file)
|
||||
{
|
||||
DBUG_ASSERT(m_table_id != ULONG_MAX);
|
||||
byte buf[ROWS_HEADER_LEN]; // No need to init the buffer
|
||||
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
|
||||
{
|
||||
@@ -5611,16 +5601,15 @@ bool Rows_log_event::write_data_body(IO_CACHE*file)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) && defined(DBUG_RBR)
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
void Rows_log_event::pack_info(Protocol *protocol)
|
||||
{
|
||||
char buf[256];
|
||||
char const *const flagstr= get_flags(STMT_END_F) ? "STMT_END_F" : "";
|
||||
char const *const dbnam= m_table->s->db.str;
|
||||
char const *const tblnam= m_table->s->table_name.str;
|
||||
my_size_t bytes= snprintf(buf, sizeof(buf),
|
||||
"%s.%s - %s", dbnam, tblnam, flagstr);
|
||||
protocol->store(buf, bytes, &my_charset_bin);
|
||||
char buf[256];
|
||||
char const *const flagstr=
|
||||
get_flags(STMT_END_F) ? " flags: STMT_END_F" : "";
|
||||
my_size_t bytes= snprintf(buf, sizeof(buf),
|
||||
"table_id: %lu%s", m_table_id, flagstr);
|
||||
protocol->store(buf, bytes, &my_charset_bin);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -5763,59 +5752,6 @@ Table_map_log_event::~Table_map_log_event()
|
||||
my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
|
||||
}
|
||||
|
||||
/*
|
||||
Find a table based on database name and table name.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
Currently, only the first table of the 'table_list' is located. If the
|
||||
table is found in the list of open tables for the thread, the 'table'
|
||||
field of 'table_list' is filled in.
|
||||
|
||||
PARAMETERS
|
||||
|
||||
thd Thread structure
|
||||
table_list List of tables to locate in the thd->open_tables list.
|
||||
count Pointer to a variable that will be set to the number of
|
||||
tables found. If the pointer is NULL, nothing will be stored.
|
||||
|
||||
RETURN VALUE
|
||||
|
||||
The number of tables found.
|
||||
|
||||
TO DO
|
||||
|
||||
Replace the list of table searches with a hash based on the combined
|
||||
database and table name. The handler_tables_hash is inappropriate since
|
||||
it hashes on the table alias. At the same time, the function can be
|
||||
extended to handle a full list of table names, in the same spirit as
|
||||
open_tables() and lock_tables().
|
||||
*/
|
||||
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
|
||||
static uint find_tables(THD *thd, TABLE_LIST *table_list, uint *count)
|
||||
{
|
||||
uint result= 0;
|
||||
|
||||
/* we verify that the caller knows our limitation */
|
||||
DBUG_ASSERT(table_list->next_global == 0);
|
||||
for (TABLE *table= thd->open_tables; table ; table= table->next)
|
||||
{
|
||||
if (strcmp(table->s->db.str, table_list->db) == 0
|
||||
&& strcmp(table->s->table_name.str, table_list->table_name) == 0)
|
||||
{
|
||||
/* Copy the table pointer into the table list. */
|
||||
table_list->table= table;
|
||||
result= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (count)
|
||||
*count= result;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Return value is an error code, one of:
|
||||
|
||||
@@ -5839,20 +5775,37 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli)
|
||||
thd->query_id= next_query_id();
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
TABLE_LIST table_list;
|
||||
TABLE_LIST *table_list;
|
||||
char *db_mem, *tname_mem;
|
||||
void *const memory=
|
||||
my_multi_malloc(MYF(MY_WME),
|
||||
&table_list, sizeof(TABLE_LIST),
|
||||
&db_mem, NAME_LEN + 1,
|
||||
&tname_mem, NAME_LEN + 1,
|
||||
NULL);
|
||||
|
||||
/*
|
||||
If memory is allocated, it the pointer to it should be stored in
|
||||
table_list. If this is not true, the memory will not be correctly
|
||||
free:ed later.
|
||||
*/
|
||||
DBUG_ASSERT(memory == NULL || memory == table_list);
|
||||
|
||||
uint32 dummy_len;
|
||||
bzero(&table_list, sizeof(table_list));
|
||||
table_list.db= const_cast<char *>
|
||||
(rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
|
||||
table_list.alias= table_list.table_name= const_cast<char*>(m_tblnam);
|
||||
table_list.lock_type= TL_WRITE;
|
||||
table_list.next_global= table_list.next_local= 0;
|
||||
table_list.updating= 1;
|
||||
bzero(table_list, sizeof(*table_list));
|
||||
table_list->db = db_mem;
|
||||
table_list->alias= table_list->table_name = tname_mem;
|
||||
table_list->lock_type= TL_WRITE;
|
||||
table_list->next_global= table_list->next_local= 0;
|
||||
table_list->table_id= m_table_id;
|
||||
table_list->updating= 1;
|
||||
strmov(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
|
||||
strmov(table_list->table_name, m_tblnam);
|
||||
|
||||
int error= 0;
|
||||
|
||||
if (rpl_filter->db_ok(table_list.db) &&
|
||||
(!rpl_filter->is_on() || rpl_filter->tables_ok("", &table_list)))
|
||||
if (rpl_filter->db_ok(table_list->db) &&
|
||||
(!rpl_filter->is_on() || rpl_filter->tables_ok("", table_list)))
|
||||
{
|
||||
/*
|
||||
Check if the slave is set to use SBR. If so, the slave should
|
||||
@@ -5878,36 +5831,32 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli)
|
||||
be a no-op.
|
||||
*/
|
||||
uint count;
|
||||
if (find_tables(thd, &table_list, &count) == 0)
|
||||
/*
|
||||
open_tables() reads the contents of thd->lex, so they must be
|
||||
initialized, so we should call lex_start(); to be even safer, we
|
||||
call mysql_init_query() which does a more complete set of inits.
|
||||
*/
|
||||
mysql_init_query(thd, NULL, 0);
|
||||
if ((error= open_tables(thd, &table_list, &count, 0)))
|
||||
{
|
||||
/*
|
||||
open_tables() reads the contents of thd->lex, so they must be
|
||||
initialized, so we should call lex_start(); to be even safer, we call
|
||||
mysql_init_query() which does a more complete set of inits.
|
||||
*/
|
||||
mysql_init_query(thd, NULL, 0);
|
||||
TABLE_LIST *tables= &table_list;
|
||||
if ((error= open_tables(thd, &tables, &count, 0)))
|
||||
if (thd->query_error || thd->is_fatal_error)
|
||||
{
|
||||
if (thd->query_error || thd->is_fatal_error)
|
||||
{
|
||||
/*
|
||||
Error reporting borrowed from Query_log_event with many excessive
|
||||
simplifications (we don't honour --slave-skip-errors)
|
||||
*/
|
||||
uint actual_error= thd->net.last_errno;
|
||||
slave_print_msg(ERROR_LEVEL, rli, actual_error,
|
||||
"Error '%s' on opening table `%s`.`%s`",
|
||||
(actual_error ? thd->net.last_error :
|
||||
"unexpected success or fatal error"),
|
||||
table_list.db, table_list.table_name);
|
||||
thd->query_error= 1;
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
/*
|
||||
Error reporting borrowed from Query_log_event with many excessive
|
||||
simplifications (we don't honour --slave-skip-errors)
|
||||
*/
|
||||
uint actual_error= thd->net.last_errno;
|
||||
slave_print_msg(ERROR_LEVEL, rli, actual_error,
|
||||
"Error '%s' on opening table `%s`.`%s`",
|
||||
(actual_error ? thd->net.last_error :
|
||||
"unexpected success or fatal error"),
|
||||
table_list->db, table_list->table_name);
|
||||
thd->query_error= 1;
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
m_table= table_list.table;
|
||||
m_table= table_list->table;
|
||||
|
||||
/*
|
||||
This will fail later otherwise, the 'in_use' field should be
|
||||
@@ -5985,19 +5934,16 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli)
|
||||
}
|
||||
|
||||
/*
|
||||
We record in the slave's information that the number m_table_id is
|
||||
mapped to the m_table object
|
||||
We record in the slave's information that the table should be
|
||||
locked by linking the table into the list of tables to lock, and
|
||||
tell the RLI that we are touching a table.
|
||||
*/
|
||||
if (!error)
|
||||
error= rli->m_table_map.set_table(m_table_id, m_table);
|
||||
|
||||
/*
|
||||
Tell the RLI that we are touching a table.
|
||||
|
||||
TODO: Maybe we can combine this with the previous operation?
|
||||
*/
|
||||
if (!error)
|
||||
rli->touching_table(m_dbnam, m_tblnam, m_table_id);
|
||||
{
|
||||
table_list->next_global= table_list->next_local= rli->tables_to_lock;
|
||||
rli->tables_to_lock= table_list;
|
||||
rli->tables_to_lock_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6064,12 +6010,17 @@ bool Table_map_log_event::write_data_body(IO_CACHE *file)
|
||||
field.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
void Table_map_log_event::pack_info(Protocol *protocol)
|
||||
{
|
||||
char buf[256];
|
||||
my_size_t bytes= my_snprintf(buf, sizeof(buf), "%s.%s", m_dbnam, m_tblnam);
|
||||
my_size_t bytes= snprintf(buf, sizeof(buf),
|
||||
"table_id: %lu (%s.%s)",
|
||||
m_table_id, m_dbnam, m_tblnam);
|
||||
protocol->store(buf, bytes, &my_charset_bin);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user