From 10d5cba09992fc0204debd2297c1d9468f71eb40 Mon Sep 17 00:00:00 2001 From: Date: Mon, 10 Aug 2009 11:46:55 +0800 Subject: [PATCH 1/3] 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 --- mysql-test/include/rpl_loaddata_charset.inc | 35 ++++++++++++++++++ mysql-test/r/rpl_loaddata_charset.result | 41 +++++++++++++++++++++ mysql-test/std_data/loaddata_utf8.dat | 3 ++ mysql-test/t/rpl_loaddata_charset.test | 17 +++++++++ sql/log_event.cc | 9 +++++ 5 files changed, 105 insertions(+) create mode 100644 mysql-test/include/rpl_loaddata_charset.inc create mode 100644 mysql-test/std_data/loaddata_utf8.dat diff --git a/mysql-test/include/rpl_loaddata_charset.inc b/mysql-test/include/rpl_loaddata_charset.inc new file mode 100644 index 00000000000..f94ff4ed069 --- /dev/null +++ b/mysql-test/include/rpl_loaddata_charset.inc @@ -0,0 +1,35 @@ +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; diff --git a/mysql-test/r/rpl_loaddata_charset.result b/mysql-test/r/rpl_loaddata_charset.result index 929d06e74cf..47fee19cf5d 100644 --- a/mysql-test/r/rpl_loaddata_charset.result +++ b/mysql-test/r/rpl_loaddata_charset.result @@ -35,3 +35,44 @@ C3BF D0AA D0AA 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; diff --git a/mysql-test/std_data/loaddata_utf8.dat b/mysql-test/std_data/loaddata_utf8.dat new file mode 100644 index 00000000000..fc7a28229d4 --- /dev/null +++ b/mysql-test/std_data/loaddata_utf8.dat @@ -0,0 +1,3 @@ +一二三 +四五六 +七八九 diff --git a/mysql-test/t/rpl_loaddata_charset.test b/mysql-test/t/rpl_loaddata_charset.test index 7f2389cb9f6..05dbdd01b39 100644 --- a/mysql-test/t/rpl_loaddata_charset.test +++ b/mysql-test/t/rpl_loaddata_charset.test @@ -31,3 +31,20 @@ select hex(a) from t1; connection master; drop table t1; 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; diff --git a/sql/log_event.cc b/sql/log_event.cc index 9b0f8e97a28..336ad6599ca 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1918,6 +1918,8 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, { const char *new_db= rewrite_db(db); int expected_error,actual_error= 0; + HA_CREATE_INFO db_options; + /* 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 @@ -1926,6 +1928,13 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, */ thd->catalog= catalog_len ? (char *) catalog : (char *)""; 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_offset= auto_increment_offset; From dd273d5bb462f3b55f1a1297fda73bad8af27107 Mon Sep 17 00:00:00 2001 From: Date: Tue, 11 Aug 2009 13:24:10 +0800 Subject: [PATCH 2/3] 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 --- mysql-test/include/rpl_loaddata_charset.inc | 35 ++++++++++++++++ mysql-test/std_data/loaddata_utf8.dat | 3 ++ .../suite/rpl/r/rpl_loaddata_charset.result | 41 +++++++++++++++++++ .../suite/rpl/t/rpl_loaddata_charset.test | 17 ++++++++ sql/log_event.cc | 10 +++++ 5 files changed, 106 insertions(+) create mode 100644 mysql-test/include/rpl_loaddata_charset.inc create mode 100644 mysql-test/std_data/loaddata_utf8.dat diff --git a/mysql-test/include/rpl_loaddata_charset.inc b/mysql-test/include/rpl_loaddata_charset.inc new file mode 100644 index 00000000000..0e445446a38 --- /dev/null +++ b/mysql-test/include/rpl_loaddata_charset.inc @@ -0,0 +1,35 @@ +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/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; diff --git a/mysql-test/std_data/loaddata_utf8.dat b/mysql-test/std_data/loaddata_utf8.dat new file mode 100644 index 00000000000..fc7a28229d4 --- /dev/null +++ b/mysql-test/std_data/loaddata_utf8.dat @@ -0,0 +1,3 @@ +一二三 +四五六 +七八九 diff --git a/mysql-test/suite/rpl/r/rpl_loaddata_charset.result b/mysql-test/suite/rpl/r/rpl_loaddata_charset.result index 7ba67150cb9..e0971b84e3d 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddata_charset.result +++ b/mysql-test/suite/rpl/r/rpl_loaddata_charset.result @@ -35,3 +35,44 @@ C3BF D0AA D0AA 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/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; diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_charset.test b/mysql-test/suite/rpl/t/rpl_loaddata_charset.test index c191d29d5a3..031a0f6c351 100644 --- a/mysql-test/suite/rpl/t/rpl_loaddata_charset.test +++ b/mysql-test/suite/rpl/t/rpl_loaddata_charset.test @@ -31,3 +31,20 @@ select hex(a) from t1; connection master; drop table t1; 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; diff --git a/sql/log_event.cc b/sql/log_event.cc index e7cbbaba38e..146a35afe2e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2949,6 +2949,8 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, { LEX_STRING new_db; int expected_error,actual_error= 0; + HA_CREATE_INFO db_options; + /* Colleagues: please never free(thd->catalog) in MySQL. This would lead to bugs as here thd->catalog is a part of an alloced block, @@ -2960,6 +2962,14 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, new_db.length= db_len; new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length); thd->set_db(new_db.str, new_db.length); /* 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_offset= auto_increment_offset; From 7850ae8b35e0727b372317c491f4fd9a79faa947 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Tue, 11 Aug 2009 14:18:26 +0200 Subject: [PATCH 3/3] Bug#44622: Using PARTITIONs with ARCHIVE engine reports 0 bytes in i_s.TABLES Problem was that ha_archive::info did not use the flag argument correctly fixed so that it updated the correct values depending on the flag. --- mysql-test/r/partition_archive.result | 22 ++++++++++++++++++++++ mysql-test/t/partition_archive.test | 21 +++++++++++++++++++++ storage/archive/ha_archive.cc | 23 +++++++++++++++-------- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/partition_archive.result b/mysql-test/r/partition_archive.result index de64b09e042..186a7930251 100644 --- a/mysql-test/r/partition_archive.result +++ b/mysql-test/r/partition_archive.result @@ -1,3 +1,25 @@ +CREATE TABLE t1 (f1 DATE NOT NULL) +ENGINE = ARCHIVE PARTITION BY RANGE (TO_DAYS(f1)) +(partition p1 values less than (733751), +partition p2 values less than MAXVALUE); +INSERT INTO t1 VALUES(CURRENT_DATE); +SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; +DATA_LENGTH INDEX_LENGTH +190 0 +SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; +DATA_LENGTH INDEX_LENGTH +190 0 +DROP TABLE t1; +CREATE TABLE t1 (f1 DATE NOT NULL) +ENGINE = ARCHIVE; +INSERT INTO t1 VALUES(CURRENT_DATE); +SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; +DATA_LENGTH INDEX_LENGTH +8658 0 +SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; +DATA_LENGTH INDEX_LENGTH +8658 0 +DROP TABLE t1; drop database if exists db99; drop table if exists t1; create database db99; diff --git a/mysql-test/t/partition_archive.test b/mysql-test/t/partition_archive.test index fad57107b7d..39551991702 100644 --- a/mysql-test/t/partition_archive.test +++ b/mysql-test/t/partition_archive.test @@ -10,6 +10,27 @@ --source include/have_partition.inc --source include/have_archive.inc +let $MYSQLD_DATADIR= `select @@datadir`; + +# +# Bug#44622: Using PARTITIONs with ARCHIVE engine reports 0 bytes in i_s.TABLES +# +CREATE TABLE t1 (f1 DATE NOT NULL) +ENGINE = ARCHIVE PARTITION BY RANGE (TO_DAYS(f1)) +(partition p1 values less than (733751), + partition p2 values less than MAXVALUE); + +INSERT INTO t1 VALUES(CURRENT_DATE); + +SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; +SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; +DROP TABLE t1; +CREATE TABLE t1 (f1 DATE NOT NULL) +ENGINE = ARCHIVE; +INSERT INTO t1 VALUES(CURRENT_DATE); +SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; +SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; +DROP TABLE t1; # # Bug 17310 Partitions: Bugs with archived partitioned tables diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 1146b2eb73a..1474071d52b 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1466,20 +1466,27 @@ int ha_archive::info(uint flag) DBUG_PRINT("ha_archive", ("Stats rows is %d\n", (int)stats.records)); /* Costs quite a bit more to get all information */ - if (flag & HA_STATUS_TIME) + if (flag & (HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE)) { MY_STAT file_stat; // Stat information for the data file VOID(my_stat(share->data_file_name, &file_stat, MYF(MY_WME))); - stats.mean_rec_length= table->s->reclength + buffer.alloced_length(); - stats.data_file_length= file_stat.st_size; - stats.create_time= (ulong) file_stat.st_ctime; - stats.update_time= (ulong) file_stat.st_mtime; - stats.max_data_file_length= share->rows_recorded * stats.mean_rec_length; + if (flag & HA_STATUS_TIME) + stats.update_time= (ulong) file_stat.st_mtime; + if (flag & HA_STATUS_CONST) + { + stats.max_data_file_length= share->rows_recorded * stats.mean_rec_length; + stats.create_time= (ulong) file_stat.st_ctime; + } + if (flag & HA_STATUS_VARIABLE) + { + stats.delete_length= 0; + stats.data_file_length= file_stat.st_size; + stats.index_file_length=0; + stats.mean_rec_length= table->s->reclength + buffer.alloced_length(); + } } - stats.delete_length= 0; - stats.index_file_length=0; if (flag & HA_STATUS_AUTO) {