diff options
-rwxr-xr-x | Build-tools/Do-compile | 1 | ||||
-rw-r--r-- | client/mysqltest.c | 7 | ||||
-rw-r--r-- | extra/resolveip.c | 2 | ||||
-rw-r--r-- | mysql-test/r/rpl_loaddata.result | 4 | ||||
-rw-r--r-- | mysql-test/r/rpl_loaddata_rule_m.result | 14 | ||||
-rw-r--r-- | mysql-test/r/rpl_loaddata_rule_s.result | 14 | ||||
-rw-r--r-- | mysql-test/r/rpl_log.result | 2 | ||||
-rw-r--r-- | mysql-test/t/rpl_loaddata.test | 17 | ||||
-rw-r--r-- | mysql-test/t/rpl_loaddata_rule_m-master.opt | 1 | ||||
-rw-r--r-- | mysql-test/t/rpl_loaddata_rule_m.test | 18 | ||||
-rw-r--r-- | mysql-test/t/rpl_loaddata_rule_s-slave.opt | 1 | ||||
-rw-r--r-- | mysql-test/t/rpl_loaddata_rule_s.test | 20 | ||||
-rw-r--r-- | mysql-test/t/rpl_log-slave.opt | 1 | ||||
-rw-r--r-- | mysql-test/t/rpl_log.test | 10 | ||||
-rw-r--r-- | sql/item.cc | 5 | ||||
-rw-r--r-- | sql/item.h | 1 | ||||
-rw-r--r-- | sql/log.cc | 1 | ||||
-rw-r--r-- | sql/log_event.cc | 69 | ||||
-rw-r--r-- | sql/log_event.h | 26 | ||||
-rw-r--r-- | sql/set_var.cc | 8 | ||||
-rw-r--r-- | sql/slave.cc | 80 | ||||
-rw-r--r-- | sql/sql_load.cc | 4 | ||||
-rw-r--r-- | sql/sql_repl.cc | 2 | ||||
-rw-r--r-- | sql/sql_show.cc | 72 | ||||
-rw-r--r-- | strings/ctype-tis620.c | 14 |
25 files changed, 268 insertions, 126 deletions
diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index 6cf577162ed..e5783dbf515 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -51,6 +51,7 @@ GetOptions( "with-low-memory", "with-other-libc=s", "with-small-disk", + "without-embedded", ) || usage(); usage() if ($opt_help); diff --git a/client/mysqltest.c b/client/mysqltest.c index 7a5712cc597..14a037a8e58 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -221,6 +221,13 @@ const char *command_names[]= "connection", "query", "connect", + /* the difference between sleep and real_sleep is that sleep will use + the delay from command line (--sleep) if there is one. + real_sleep always uses delay from it's argument. + the logic is that sometimes delays are cpu-dependent (and --sleep + can be used to set this delay. real_sleep is used for cpu-independent + delays + */ "sleep", "real_sleep", "inc", diff --git a/extra/resolveip.c b/extra/resolveip.c index 52d71d40a64..9851ec49605 100644 --- a/extra/resolveip.c +++ b/extra/resolveip.c @@ -109,7 +109,7 @@ static int get_options(int *argc,char ***argv) int main(int argc, char **argv) { struct hostent *hpaddr; - u_long taddr; + in_addr_t taddr; char *ip,**q; int error=0; diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result index 05bdad0fb84..e93f8487c32 100644 --- a/mysql-test/r/rpl_loaddata.result +++ b/mysql-test/r/rpl_loaddata.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; slave start; +reset master; create table t1(a int not null auto_increment, b int, primary key(a) ); load data infile '../../std_data/rpl_loaddata.dat' into table t1; create temporary table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60)); @@ -19,6 +20,9 @@ day id category name 2003-02-22 2461 b a a a @ % ' " a 2003-03-22 2161 c asdf 2003-04-22 2416 a bbbbb +show binlog events from 898; +Log_name Pos Event_type Server_id Orig_log_pos Info +slave-bin.001 898 Query 1 898 use test; insert into t3 select * from t2 drop table t1; drop table t2; drop table t3; diff --git a/mysql-test/r/rpl_loaddata_rule_m.result b/mysql-test/r/rpl_loaddata_rule_m.result new file mode 100644 index 00000000000..8d8ed749c71 --- /dev/null +++ b/mysql-test/r/rpl_loaddata_rule_m.result @@ -0,0 +1,14 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +reset master; +create database test2; +create table t1(a int, b int, unique(b)); +use test2; +load data infile '../../std_data/rpl_loaddata.dat' into table test.t1; +show binlog events from 79; +Log_name Pos Event_type Server_id Orig_log_pos Info +drop database test2; diff --git a/mysql-test/r/rpl_loaddata_rule_s.result b/mysql-test/r/rpl_loaddata_rule_s.result new file mode 100644 index 00000000000..a84368501a9 --- /dev/null +++ b/mysql-test/r/rpl_loaddata_rule_s.result @@ -0,0 +1,14 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +reset master; +create table t1(a int, b int, unique(b)); +load data infile '../../std_data/rpl_loaddata.dat' into table test.t1; +select count(*) from t1; +count(*) +2 +show binlog events from 79; +Log_name Pos Event_type Server_id Orig_log_pos Info diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index fbec0542e4b..26e465f9c3b 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -84,7 +84,7 @@ slave-bin.001 200 Query 1 200 use test; insert into t1 values (NULL) slave-bin.001 263 Query 1 263 use test; drop table t1 slave-bin.001 311 Query 1 311 use test; create table t1 (word char(20) not null) slave-bin.001 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=581 -slave-bin.001 1065 Exec_load 1 1056 ;file_id=1 +slave-bin.001 1065 Exec_load 1 1065 ;file_id=1 slave-bin.001 1088 Query 1 1088 use test; drop table t1 slave-bin.001 1136 Query 1 1136 use test; create table t5 (a int) slave-bin.001 1194 Query 1 1194 use test; drop table t5 diff --git a/mysql-test/t/rpl_loaddata.test b/mysql-test/t/rpl_loaddata.test index 0a07dd7549b..65e07aaa823 100644 --- a/mysql-test/t/rpl_loaddata.test +++ b/mysql-test/t/rpl_loaddata.test @@ -12,6 +12,10 @@ source include/master-slave.inc; +connection slave; +reset master; +connection master; + create table t1(a int not null auto_increment, b int, primary key(a) ); load data infile '../../std_data/rpl_loaddata.dat' into table t1; @@ -27,6 +31,16 @@ sync_with_master; select * from t1; select * from t3; +# We want to be sure that LOAD DATA is in the slave's binlog. +# But we can't simply read this binlog, because the file_id is uncertain (would +# cause test failures). So instead, we test if the binlog looks long enough to +# contain LOAD DATA. That is, I (Guilhem) have done SHOW BINLOG EVENTS on my +# machine, saw that the last event is 'create table t3' and is at position 898 +# when things go fine. If LOAD DATA was not logged, the binlog would be shorter +# than 898 bytes and there would be an error in SHOW BINLOG EVENTS. Of course, +# if someone changes the content of '../../std_data/rpl_loaddata2.dat', 898 will +# have to be changed too. +show binlog events from 898; connection master; @@ -38,6 +52,9 @@ create table t1(a int, b int, unique(b)); save_master_pos; connection slave; sync_with_master; + +# See if slave stops when there's a duplicate entry for key error in LOAD DATA + insert into t1 values(1,10); connection master; diff --git a/mysql-test/t/rpl_loaddata_rule_m-master.opt b/mysql-test/t/rpl_loaddata_rule_m-master.opt new file mode 100644 index 00000000000..9d4a8f0b95e --- /dev/null +++ b/mysql-test/t/rpl_loaddata_rule_m-master.opt @@ -0,0 +1 @@ +--binlog_ignore_db=test diff --git a/mysql-test/t/rpl_loaddata_rule_m.test b/mysql-test/t/rpl_loaddata_rule_m.test new file mode 100644 index 00000000000..18f295f8ce2 --- /dev/null +++ b/mysql-test/t/rpl_loaddata_rule_m.test @@ -0,0 +1,18 @@ +# See if the master logs LOAD DATA INFILE correctly when binlog_*_db rules +# exist. +# This is for BUG#1100 (LOAD DATA INFILE was half-logged). + +source include/master-slave.inc; +connection slave; +reset master; + +# Test logging on master + +connection master; +# 'test' is the current database +create database test2; +create table t1(a int, b int, unique(b)); +use test2; +load data infile '../../std_data/rpl_loaddata.dat' into table test.t1; +show binlog events from 79; # should be nothing +drop database test2; diff --git a/mysql-test/t/rpl_loaddata_rule_s-slave.opt b/mysql-test/t/rpl_loaddata_rule_s-slave.opt new file mode 100644 index 00000000000..9d4a8f0b95e --- /dev/null +++ b/mysql-test/t/rpl_loaddata_rule_s-slave.opt @@ -0,0 +1 @@ +--binlog_ignore_db=test diff --git a/mysql-test/t/rpl_loaddata_rule_s.test b/mysql-test/t/rpl_loaddata_rule_s.test new file mode 100644 index 00000000000..1ea4f6825f5 --- /dev/null +++ b/mysql-test/t/rpl_loaddata_rule_s.test @@ -0,0 +1,20 @@ +# See if the slave logs (in its own binlog, with --log-slave-updates) a +# replicated LOAD DATA INFILE correctly when it has binlog_*_db rules. +# This is for BUG#1100 (LOAD DATA INFILE was half-logged). + +source include/master-slave.inc; +connection slave; +reset master; + +connection master; +# 'test' is the current database +create table t1(a int, b int, unique(b)); +load data infile '../../std_data/rpl_loaddata.dat' into table test.t1; + +# Test logging on slave; + +save_master_pos; +connection slave; +sync_with_master; +select count(*) from t1; # check that LOAD was replicated +show binlog events from 79; # should be nothing diff --git a/mysql-test/t/rpl_log-slave.opt b/mysql-test/t/rpl_log-slave.opt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/mysql-test/t/rpl_log-slave.opt @@ -0,0 +1 @@ + diff --git a/mysql-test/t/rpl_log.test b/mysql-test/t/rpl_log.test index ad962b585a1..e01b3e4e09c 100644 --- a/mysql-test/t/rpl_log.test +++ b/mysql-test/t/rpl_log.test @@ -5,6 +5,16 @@ connection slave; slave stop; reset master; reset slave; +# We are going to read the slave's binlog which contains file_id (for some LOAD +# DATA INFILE); to make it repeatable (not influenced by other tests), we need +# to stop and start the slave, to be sure file_id will start from 1. +# This can be done with 'server_stop slave', but +# this would require the manager, so most of the time the test will be skipped +# :( +# To workaround this, I (Guilhem) add a (empty) rpl_log-slave.opt (because when +# mysql-test-run finds such a file it restarts the slave before doing the +# test). That's not very elegant but I could find no better way, sorry. + let $VERSION=`select version()`; connection master; diff --git a/sql/item.cc b/sql/item.cc index 79501755cbf..0e9085180cd 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -389,6 +389,11 @@ void Item_string::make_field(Send_field *tmp_field) init_make_field(tmp_field,FIELD_TYPE_STRING); } +void Item_empty_string::make_field(Send_field *tmp_field) +{ + init_make_field(tmp_field,FIELD_TYPE_VAR_STRING); +} + void Item_datetime::make_field(Send_field *tmp_field) { init_make_field(tmp_field,FIELD_TYPE_DATETIME); diff --git a/sql/item.h b/sql/item.h index 1631bf76135..25650e85434 100644 --- a/sql/item.h +++ b/sql/item.h @@ -356,6 +356,7 @@ class Item_empty_string :public Item_string public: Item_empty_string(const char *header,uint length) :Item_string("",0) { name=(char*) header; max_length=length;} + void make_field(Send_field *field); unsigned int size_of() { return sizeof(*this);} }; diff --git a/sql/log.cc b/sql/log.cc index 7e12297d8ae..ee774ea3700 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1068,6 +1068,7 @@ bool MYSQL_LOG::write(Log_event* event_info) #else IO_CACHE *file = &log_file; #endif + DBUG_PRINT("info",("event type=%d",event_info->get_type_code())); /* In the future we need to add to the following if tests like "do the involved tables match (to be implemented) diff --git a/sql/log_event.cc b/sql/log_event.cc index a4883599b2b..9e7546dd635 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1605,11 +1605,12 @@ void Create_file_log_event::pack_info(String* packet) #endif #ifndef MYSQL_CLIENT -Append_block_log_event::Append_block_log_event(THD* thd_arg, char* block_arg, +Append_block_log_event::Append_block_log_event(THD* thd_arg, const char* db_arg, + char* block_arg, uint block_len_arg, bool using_trans) :Log_event(thd_arg,0, using_trans), block(block_arg), - block_len(block_len_arg), file_id(thd_arg->file_id) + block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg) { } #endif @@ -1653,8 +1654,9 @@ void Append_block_log_event::pack_info(String* packet) net_store_data(packet, buf1); } -Delete_file_log_event::Delete_file_log_event(THD* thd_arg, bool using_trans) - :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id) +Delete_file_log_event::Delete_file_log_event(THD* thd_arg, const char* db_arg, + bool using_trans) + :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg) { } #endif @@ -1699,8 +1701,9 @@ void Delete_file_log_event::pack_info(String* packet) #ifndef MYSQL_CLIENT -Execute_load_log_event::Execute_load_log_event(THD* thd_arg, bool using_trans) - :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id) +Execute_load_log_event::Execute_load_log_event(THD* thd_arg, const char* db_arg, + bool using_trans) + :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg) { } #endif @@ -1904,7 +1907,19 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, DBUG_ASSERT(thd->query == 0); thd->query = 0; // Should not be needed thd->query_error = 0; - + + /* + We test replicate_*_db rules. Note that we have already prepared the file to + load, even if we are going to ignore and delete it now. So it is possible + that we did a lot of disk writes for nothing. In other words, a big LOAD + DATA INFILE on the master will still consume a lot of space on the slave + (space in the relay log + space of temp files: twice the space of the file + to load...) even if it will finally be ignored. + TODO: fix this; this can be done by testing rules in + Create_file_log_event::exec_event() and then discarding Append_block and + al. Another way is do the filtering in the I/O thread (more efficient: no + disk writes at all). + */ if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { thd->set_time((time_t)when); @@ -2209,7 +2224,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli) init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0, MYF(MY_WME|MY_NABP))) { - slave_print_error(rli,my_errno, "Could not open file '%s'", fname_buf); + slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf); goto err; } @@ -2220,7 +2235,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli) if (write_base(&file)) { strmov(p, ".info"); // to have it right in the error message - slave_print_error(rli,my_errno, "Could not write to file '%s'", fname_buf); + slave_print_error(rli,my_errno, "Error in Create_file event: could not write to file '%s'", fname_buf); goto err; } end_io_cache(&file); @@ -2230,16 +2245,14 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli) if ((fd = my_open(fname_buf, O_WRONLY|O_CREAT|O_BINARY|O_TRUNC, MYF(MY_WME))) < 0) { - slave_print_error(rli,my_errno, "Could not open file '%s'", fname_buf); + slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf); goto err; } if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP))) { - slave_print_error(rli,my_errno, "Write to '%s' failed", fname_buf); + slave_print_error(rli,my_errno, "Error in Create_file event: write to '%s' failed", fname_buf); goto err; } - if (mysql_bin_log.is_open()) - mysql_bin_log.write(this); error=0; // Everything is ok err: @@ -2258,8 +2271,6 @@ int Delete_file_log_event::exec_event(struct st_relay_log_info* rli) (void) my_delete(fname, MYF(MY_WME)); memcpy(p, ".info", 6); (void) my_delete(fname, MYF(MY_WME)); - if (mysql_bin_log.is_open()) - mysql_bin_log.write(this); return Log_event::exec_event(rli); } @@ -2273,16 +2284,14 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli) memcpy(p, ".data", 6); if ((fd = my_open(fname, O_WRONLY|O_APPEND|O_BINARY, MYF(MY_WME))) < 0) { - slave_print_error(rli,my_errno, "Could not open file '%s'", fname); + slave_print_error(rli,my_errno, "Error in Append_block event: could not open file '%s'", fname); goto err; } if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP))) { - slave_print_error(rli,my_errno, "Write to '%s' failed", fname); + slave_print_error(rli,my_errno, "Error in Append_block event: write to '%s' failed", fname); goto err; } - if (mysql_bin_log.is_open()) - mysql_bin_log.write(this); error=0; err: @@ -2297,7 +2306,6 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) char *p= slave_load_file_stem(fname, file_id, server_id); int fd; int error = 1; - ulong save_options; IO_CACHE file; Load_log_event* lev = 0; @@ -2306,7 +2314,7 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0, MYF(MY_WME|MY_NABP))) { - slave_print_error(rli,my_errno, "Could not open file '%s'", fname); + slave_print_error(rli,my_errno, "Error in Exec_load event: could not open file '%s'", fname); goto err; } if (!(lev = (Load_log_event*)Log_event::read_log_event(&file, @@ -2314,21 +2322,16 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) (bool)0)) || lev->get_type_code() != NEW_LOAD_EVENT) { - slave_print_error(rli,0, "File '%s' appears corrupted", fname); + slave_print_error(rli,0, "Error in Exec_load event: file '%s' appears corrupted", fname); goto err; } - /* - We want to disable binary logging in slave thread because we need the file - events to appear in the same order as they do on the master relative to - other events, so that we can preserve ascending order of log sequence - numbers - needed to handle failover . - */ - save_options = thd->options; - thd->options &= ~ (ulong) (OPTION_BIN_LOG); + lev->thd = thd; /* lev->exec_event should use rli only for errors - i.e. should not advance rli's position + i.e. should not advance rli's position. + lev->exec_event is the place where the table is loaded (it calls + mysql_load()). */ if (lev->exec_event(0,rli,1)) { @@ -2349,15 +2352,11 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) tmp, fname); my_free(tmp,MYF(0)); } - thd->options= save_options; goto err; } - thd->options = save_options; (void) my_delete(fname, MYF(MY_WME)); memcpy(p, ".data", 6); (void) my_delete(fname, MYF(MY_WME)); - if (mysql_bin_log.is_open()) - mysql_bin_log.write(this); error = 0; err: diff --git a/sql/log_event.h b/sql/log_event.h index 1031b940528..227c0243b9c 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -687,9 +687,20 @@ public: char* block; uint block_len; uint file_id; - + /* + 'db' is filled when the event is created in mysql_load() (the event needs to + have a 'db' member to be well filtered by binlog-*-db rules). 'db' is not + written to the binlog (it's not used by Append_block_log_event::write()), so + it can't be read in the Append_block_log_event(const char* buf, int + event_len) constructor. + In other words, 'db' is used only for filtering by binlog-*-db rules. + Create_file_log_event is different: its 'db' (which is inherited from + Load_log_event) is written to the binlog and can be re-read. + */ + const char* db; + #ifndef MYSQL_CLIENT - Append_block_log_event(THD* thd, char* block_arg, + Append_block_log_event(THD* thd, const char* db_arg, char* block_arg, uint block_len_arg, bool using_trans); int exec_event(struct st_relay_log_info* rli); void pack_info(String* packet); @@ -703,6 +714,7 @@ public: int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;} bool is_valid() { return block != 0; } int write_data(IO_CACHE* file); + const char* get_db() { return db; } }; @@ -710,9 +722,10 @@ class Delete_file_log_event: public Log_event { public: uint file_id; + const char* db; /* see comment in Append_block_log_event */ #ifndef MYSQL_CLIENT - Delete_file_log_event(THD* thd, bool using_trans); + Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans); void pack_info(String* packet); int exec_event(struct st_relay_log_info* rli); #else @@ -725,15 +738,17 @@ public: int get_data_size() { return DELETE_FILE_HEADER_LEN ;} bool is_valid() { return file_id != 0; } int write_data(IO_CACHE* file); + const char* get_db() { return db; } }; class Execute_load_log_event: public Log_event { public: uint file_id; - + const char* db; /* see comment in Append_block_log_event */ + #ifndef MYSQL_CLIENT - Execute_load_log_event(THD* thd, bool using_trans); + Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans); void pack_info(String* packet); int exec_event(struct st_relay_log_info* rli); #else @@ -746,6 +761,7 @@ public: int get_data_size() { return EXEC_LOAD_HEADER_LEN ;} bool is_valid() { return file_id != 0; } int write_data(IO_CACHE* file); + const char* get_db() { return db; } }; #ifdef MYSQL_CLIENT diff --git a/sql/set_var.cc b/sql/set_var.cc index 6dc36e312cb..8c0859fbca4 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -530,15 +530,15 @@ struct show_var_st init_vars[]= { {"log_error", (char*) log_error_file, SHOW_CHAR}, {"port", (char*) &mysql_port, SHOW_INT}, {"protocol_version", (char*) &protocol_version, SHOW_INT}, - {sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS}, - {sys_readonly.name, (char*) &sys_readonly, SHOW_SYS}, - {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS}, - {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank, SHOW_SYS}, #ifdef HAVE_QUERY_CACHE {sys_query_cache_limit.name,(char*) &sys_query_cache_limit, SHOW_SYS}, {sys_query_cache_size.name, (char*) &sys_query_cache_size, SHOW_SYS}, {sys_query_cache_type.name, (char*) &sys_query_cache_type, SHOW_SYS}, #endif /* HAVE_QUERY_CACHE */ + {sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS}, + {sys_readonly.name, (char*) &sys_readonly, SHOW_SYS}, + {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS}, + {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank, SHOW_SYS}, {sys_server_id.name, (char*) &sys_server_id, SHOW_SYS}, {sys_slave_net_timeout.name,(char*) &sys_slave_net_timeout, SHOW_SYS}, {"skip_external_locking", (char*) &my_disable_locking, SHOW_MY_BOOL}, diff --git a/sql/slave.cc b/sql/slave.cc index 145144072c9..32ed228e119 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2757,7 +2757,7 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev) if (unlikely(net_request_file(net,cev->fname))) { sql_print_error("Slave I/O: failed requesting download of '%s'", - cev->fname); + cev->fname); goto err; } @@ -2767,56 +2767,56 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev) in the loop */ { - Append_block_log_event aev(thd,0,0,0); + Append_block_log_event aev(thd,0,0,0,0); for (;;) { if (unlikely((num_bytes=my_net_read(net)) == packet_error)) { - sql_print_error("Network read error downloading '%s' from master", - cev->fname); - goto err; + sql_print_error("Network read error downloading '%s' from master", + cev->fname); + goto err; } if (unlikely(!num_bytes)) /* eof */ { - send_ok(net); /* 3.23 master wants it */ - Execute_load_log_event xev(thd,0); - xev.log_pos = mi->master_log_pos; - if (unlikely(mi->rli.relay_log.append(&xev))) - { - sql_print_error("Slave I/O: error writing Exec_load event to \ + send_ok(net); /* 3.23 master wants it */ + Execute_load_log_event xev(thd,0,0); + xev.log_pos = mi->master_log_pos; + if (unlikely(mi->rli.relay_log.append(&xev))) + { + sql_print_error("Slave I/O: error writing Exec_load event to \ relay log"); - goto err; - } - mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total); - break; + goto err; + } + mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total); + break; } if (unlikely(cev_not_written)) { - cev->block = (char*)net->read_pos; - cev->block_len = num_bytes; - cev->log_pos = mi->master_log_pos; - if (unlikely(mi->rli.relay_log.append(cev))) - { - sql_print_error("Slave I/O: error writing Create_file event to \ + cev->block = (char*)net->read_pos; + cev->block_len = num_bytes; + cev->log_pos = mi->master_log_pos; + if (unlikely(mi->rli.relay_log.append(cev))) + { + sql_print_error("Slave I/O: error writing Create_file event to \ relay log"); - goto err; - } - cev_not_written=0; - mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total); + goto err; + } + cev_not_written=0; + mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total); } else { - aev.block = (char*)net->read_pos; - aev.block_len = num_bytes; - aev.log_pos = mi->master_log_pos; - if (unlikely(mi->rli.relay_log.append(&aev))) - { - sql_print_error("Slave I/O: error writing Append_block event to \ + aev.block = (char*)net->read_pos; + aev.block_len = num_bytes; + aev.log_pos = mi->master_log_pos; + if (unlikely(mi->rli.relay_log.append(&aev))) + { + sql_print_error("Slave I/O: error writing Append_block event to \ relay log"); - goto err; - } - mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ; + goto err; + } + mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ; } } } @@ -2900,6 +2900,12 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf, tmp_buf[event_len]=0; // Create_file constructor wants null-term buffer buf = (const char*)tmp_buf; } + /* + This will transform LOAD_EVENT into CREATE_FILE_EVENT, ask the master to + send the loaded file, and write it to the relay log in the form of + Append_block/Exec_load (the SQL thread needs the data, as that thread is not + connected to the master). + */ Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg, 1 /*old format*/ ); if (unlikely(!ev)) @@ -2929,6 +2935,12 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf, inc_pos= 0; break; case CREATE_FILE_EVENT: + /* + Yes it's possible to have CREATE_FILE_EVENT here, even if we're in + queue_old_event() which is for 3.23 events which don't comprise + CREATE_FILE_EVENT. This is because read_log_event() above has just + transformed LOAD_EVENT into CREATE_FILE_EVENT. + */ { /* We come here when and only when tmp_buf != 0 */ DBUG_ASSERT(tmp_buf); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 4911b1a6b75..2e7bf1d5d78 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -299,7 +299,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, which is nonsense. */ read_info.end_io_cache(); - Delete_file_log_event d(thd, log_delayed); + Delete_file_log_event d(thd, db, log_delayed); mysql_bin_log.write(&d); } } @@ -331,7 +331,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, read_info.end_io_cache(); // make sure last block gets logged if (lf_info.wrote_create_file) { - Execute_load_log_event e(thd, log_delayed); + Execute_load_log_event e(thd, db, log_delayed); mysql_bin_log.write(&e); } } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index cdd0bca4a0e..5a42614dff4 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1216,7 +1216,7 @@ int log_loaded_block(IO_CACHE* file) lf_info->last_pos_in_file = file->pos_in_file; if (lf_info->wrote_create_file) { - Append_block_log_event a(lf_info->thd, buffer, block_len, + Append_block_log_event a(lf_info->thd, lf_info->db, buffer, block_len, lf_info->log_delayed); mysql_bin_log.write(&a); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 0321eb3cbba..515c5da0422 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -566,49 +566,49 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) DBUG_RETURN(1); } + char buff[1024]; + String packet(buff,sizeof(buff)); + packet.length(0); + net_store_data(&packet,convert, table->table_name); + /* + A hack - we need to reserve some space for the length before + we know what it is - let's assume that the length of create table + statement will fit into 3 bytes ( 16 MB max :-) ) + */ + ulong store_len_offset = packet.length(); + packet.length(store_len_offset + 4); + if (store_create_info(thd, table, &packet)) + DBUG_RETURN(-1); + ulong create_len = packet.length() - store_len_offset - 4; + if (create_len > 0x00ffffff) // better readable in HEX ... + { + /* + Just in case somebody manages to create a table + with *that* much stuff in the definition + */ + DBUG_RETURN(1); + } + + /* + Now we have to store the length in three bytes, even if it would fit + into fewer bytes, so we cannot use net_store_data() anymore, + and do it ourselves + */ + char* p = (char*)packet.ptr() + store_len_offset; + *p++ = (char) 253; // The client the length is stored using 3-bytes + int3store(p, create_len); + List<Item> field_list; field_list.push_back(new Item_empty_string("Table",NAME_LEN)); - field_list.push_back(new Item_empty_string("Create Table",1024)); + field_list.push_back(new Item_empty_string("Create Table", + max(packet.length(),1024))); // 1024 is for not to confuse old clients if (send_fields(thd,field_list,1)) DBUG_RETURN(1); - String *packet = &thd->packet; - { - packet->length(0); - net_store_data(packet,convert, table->table_name); - /* - A hack - we need to reserve some space for the length before - we know what it is - let's assume that the length of create table - statement will fit into 3 bytes ( 16 MB max :-) ) - */ - ulong store_len_offset = packet->length(); - packet->length(store_len_offset + 4); - if (store_create_info(thd, table, packet)) - DBUG_RETURN(-1); - ulong create_len = packet->length() - store_len_offset - 4; - if (create_len > 0x00ffffff) // better readable in HEX ... - { - /* - Just in case somebody manages to create a table - with *that* much stuff in the definition - */ - DBUG_RETURN(1); - } - - /* - Now we have to store the length in three bytes, even if it would fit - into fewer bytes, so we cannot use net_store_data() anymore, - and do it ourselves - */ - char* p = (char*)packet->ptr() + store_len_offset; - *p++ = (char) 253; // The client the length is stored using 3-bytes - int3store(p, create_len); + if (my_net_write(&thd->net, (char*)packet.ptr(), packet.length())) + DBUG_RETURN(1); - // now we are in business :-) - if (my_net_write(&thd->net, (char*)packet->ptr(), packet->length())) - DBUG_RETURN(1); - } send_eof(&thd->net); DBUG_RETURN(0); } diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 885d4406cd6..edadadf3a43 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -49,7 +49,7 @@ #include "m_ctype.h" #include "t_ctype.h" -static uchar* thai2sortable(const uchar *tstr,uint len); +static uchar* thai2sortable(const uchar *tstr,int len); #define BUFFER_MULTIPLY 4 #define buffsize(s) (BUFFER_MULTIPLY * (strlen(s) + 1)) @@ -456,7 +456,7 @@ uchar NEAR sort_order_tis620[]= /* NOTE: isn't it faster to alloc buffer in calling function? */ -static uchar* thai2sortable(const uchar * tstr,uint len) +static uchar* thai2sortable(const uchar * tstr,int len) { /* We use only 3 levels (neglect capitalization). */ @@ -467,16 +467,16 @@ static uchar* thai2sortable(const uchar * tstr,uint len) uint bufSize; uint RightSize; - len= (uint) strnlen((char*) tstr,len); + len= (int) strnlen((char*) tstr,len); bufSize= (uint) buffsize((char*) tstr); RightSize= sizeof(uchar) * (len + 1); - if (!(outBuf= pLeft1= pRight1= + if (!(outBuf= pLeft1= pRight1= (uchar *)malloc(sizeof(uchar) * bufSize + RightSize*2))) return (uchar*) tstr; pLeft2= pRight2= pRight1 + sizeof(uchar) * bufSize; pLeft3= pRight3= pRight2 + RightSize; - while (--len) + while (--len > 0) { int *t_ctype0= t_ctype[p[0]]; if (isldvowel(*p) && isconsnt(p[1])) @@ -567,8 +567,8 @@ int my_strcoll_tis620(const uchar * s1, const uchar * s2) { uchar *tc1, *tc2; int i; - tc1= thai2sortable(s1, (uint) strlen((char*)s1)); - tc2= thai2sortable(s2, (uint) strlen((char*)s2)); + tc1= thai2sortable(s1, (int) strlen((char*)s1)); + tc2= thai2sortable(s2, (int) strlen((char*)s2)); i= strcmp((char*)tc1, (char*)tc2); free(tc1); free(tc2); |