Commit 4014c093 authored by unknown's avatar unknown

Fix for BUG#4500 "set character set replicates incorrectly"

We must not reset the charset in slave after each statement, otherwise the SET CHARACTER SET is cancelled immediately.
Instead, we write a SET CHARACTER SET DEFAULT to the master's binlog when needed (like we already do for SET FOREIGN_KEY_CHECKS);
such writing is not necessary in 4.1 (in 4.1 the bug does not exist, as the SET ONE_SHOT syntax is used).
I have written a test and it works, but I'm not pushing the test as it requires building with all charsets.
I have noticed differences between what is inserted in the master's table in 4.0 and 4.1, and alerted Bar.


sql/log.cc:
  When SET CHARACTER SET has been used, we must reset the charset after the writing the statement, in the binlog.
  In 4.1, this resetting is already achieved by the SET ONE_SHOT syntax.
sql/log_event.cc:
  In slave, we must not simply reset the charset after each statement: if we do this, the charset gets
  immediately after executing the SET CHARACTER SET! (BUG#4500).
parent 434d385a
...@@ -1208,13 +1208,25 @@ bool MYSQL_LOG::write(Log_event* event_info) ...@@ -1208,13 +1208,25 @@ bool MYSQL_LOG::write(Log_event* event_info)
/* Write log events to reset the 'run environment' of the SQL command */ /* Write log events to reset the 'run environment' of the SQL command */
if (thd && thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) if (thd)
{
if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS)
{ {
Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=1", 24, 0); Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=1", 24, 0);
e.set_log_pos(this); e.set_log_pos(this);
if (e.write(file)) if (e.write(file))
goto err; goto err;
} }
#if MYSQL_VERSION_ID < 40100
if (thd->variables.convert_set)
{
Query_log_event e(thd, "SET CHARACTER SET DEFAULT", 25, 0);
e.set_log_pos(this);
if (e.write(file))
goto err;
}
#endif
}
/* /*
Tell for transactional table handlers up to which position in the Tell for transactional table handlers up to which position in the
......
...@@ -1932,8 +1932,6 @@ end: ...@@ -1932,8 +1932,6 @@ end:
thd->query= 0; // just to be sure thd->query= 0; // just to be sure
thd->query_length= 0; thd->query_length= 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
// assume no convert for next query unless set explictly
thd->variables.convert_set = 0;
close_thread_tables(thd); close_thread_tables(thd);
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC)); free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
return (thd->query_error ? thd->query_error : Log_event::exec_event(rli)); return (thd->query_error ? thd->query_error : Log_event::exec_event(rli));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment