Commit 10d5cba0 authored by 's avatar

BUG#45516 SQL thread does not use database charset properly

  
Replication SQL thread does not set database default charset to 
thd->variables.collation_database properly, when executing LOAD DATA binlog.
This bug can be repeated by using "LOAD DATA" command in STATEMENT mode.
  
This patch adds code to find the default character set of the current database 
then assign it to thd->db_charset when slave server begins to execute a relay log.
The test of this bug is added into rpl_loaddata_charset.test 
parent 1c07007f
connection master;
--disable_warnings
DROP DATABASE IF EXISTS mysqltest;
--enable_warnings
CREATE DATABASE mysqltest CHARSET UTF8;
USE mysqltest;
CREATE TABLE t (cl varchar(100)) CHARSET UTF8;
if (!$LOAD_LOCAL)
{
LOAD DATA INFILE '../std_data_ln/loaddata_utf8.dat' INTO TABLE t
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
}
if ($LOAD_LOCAL)
{
LOAD DATA LOCAL INFILE './std_data/loaddata_utf8.dat' INTO TABLE t
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
}
save_master_pos;
echo ----------content on master----------;
SELECT hex(cl) FROM t;
connection slave;
sync_with_master;
echo ----------content on slave----------;
USE mysqltest;
SELECT hex(cl) FROM t;
connection master;
DROP DATABASE mysqltest;
save_master_pos;
connection slave;
sync_with_master;
...@@ -35,3 +35,44 @@ C3BF ...@@ -35,3 +35,44 @@ C3BF
D0AA D0AA
D0AA D0AA
drop table t1; drop table t1;
-------------test bug#45516------------------
DROP DATABASE IF EXISTS mysqltest;
CREATE DATABASE mysqltest CHARSET UTF8;
USE mysqltest;
CREATE TABLE t (cl varchar(100)) CHARSET UTF8;
LOAD DATA LOCAL INFILE './std_data/loaddata_utf8.dat' INTO TABLE t
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
----------content on master----------
SELECT hex(cl) FROM t;
hex(cl)
E4B880E4BA8CE4B889
E59B9BE4BA94E585AD
E4B883E585ABE4B99D
----------content on slave----------
USE mysqltest;
SELECT hex(cl) FROM t;
hex(cl)
E4B880E4BA8CE4B889
E59B9BE4BA94E585AD
E4B883E585ABE4B99D
DROP DATABASE mysqltest;
DROP DATABASE IF EXISTS mysqltest;
CREATE DATABASE mysqltest CHARSET UTF8;
USE mysqltest;
CREATE TABLE t (cl varchar(100)) CHARSET UTF8;
LOAD DATA INFILE '../std_data_ln/loaddata_utf8.dat' INTO TABLE t
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
----------content on master----------
SELECT hex(cl) FROM t;
hex(cl)
E4B880E4BA8CE4B889
E59B9BE4BA94E585AD
E4B883E585ABE4B99D
----------content on slave----------
USE mysqltest;
SELECT hex(cl) FROM t;
hex(cl)
E4B880E4BA8CE4B889
E59B9BE4BA94E585AD
E4B883E585ABE4B99D
DROP DATABASE mysqltest;
一二三
四五六
七八九
...@@ -31,3 +31,20 @@ select hex(a) from t1; ...@@ -31,3 +31,20 @@ select hex(a) from t1;
connection master; connection master;
drop table t1; drop table t1;
sync_slave_with_master; sync_slave_with_master;
#
# Bug#45516
# When slave SQL thread executing LOAD DATA command, the
# thd->variables.collation_database was not set properly to the default
# database charset
#
echo -------------test bug#45516------------------;
# LOAD DATA INFILE
let $LOAD_LOCAL=1;
source include/rpl_loaddata_charset.inc;
# LOAD DATA LOCAL INFILE
let $LOAD_LOCAL=0;
source include/rpl_loaddata_charset.inc;
...@@ -1918,6 +1918,8 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, ...@@ -1918,6 +1918,8 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli,
{ {
const char *new_db= rewrite_db(db); const char *new_db= rewrite_db(db);
int expected_error,actual_error= 0; int expected_error,actual_error= 0;
HA_CREATE_INFO db_options;
/* /*
Colleagues: please never free(thd->catalog) in MySQL. This would lead to Colleagues: please never free(thd->catalog) in MySQL. This would lead to
bugs as here thd->catalog is a part of an alloced block, not an entire bugs as here thd->catalog is a part of an alloced block, not an entire
...@@ -1926,6 +1928,13 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, ...@@ -1926,6 +1928,13 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli,
*/ */
thd->catalog= catalog_len ? (char *) catalog : (char *)""; thd->catalog= catalog_len ? (char *) catalog : (char *)"";
thd->set_db(new_db, (uint) strlen(new_db)); /* allocates a copy of 'db' */ thd->set_db(new_db, (uint) strlen(new_db)); /* allocates a copy of 'db' */
/*
Setting the character set and collation of the current database thd->db.
*/
load_db_opt_by_name(thd, thd->db, &db_options);
if (db_options.default_table_charset)
thd->db_charset= db_options.default_table_charset;
thd->variables.auto_increment_increment= auto_increment_increment; thd->variables.auto_increment_increment= auto_increment_increment;
thd->variables.auto_increment_offset= auto_increment_offset; thd->variables.auto_increment_offset= auto_increment_offset;
......
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