From 79780cbd9cf079dc767c6beb759191efa1a7ef23 Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Thu, 19 Jun 2003 15:38:52 +0500 Subject: [PATCH 1/8] Fix for bug #616 mysqld crash / SSL with SQLyog --- sql/sql_parse.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index bb06713ec4c..3b3da6d35b3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -583,6 +583,11 @@ check_connections(THD *thd) if (thd->client_capabilities & CLIENT_SSL) { /* Do the SSL layering. */ + if (!ssl_acceptor_fd) + { + inc_host_errors(&thd->remote.sin_addr); + return(ER_HANDSHAKE_ERROR); + } DBUG_PRINT("info", ("IO layer change in progress...")); if (sslaccept(ssl_acceptor_fd, net->vio, thd->variables.net_wait_timeout)) { From 10c81fb52d88436aaebfc2fb8a0952b7f59ce50f Mon Sep 17 00:00:00 2001 From: "miguel@hegel.(none)" <> Date: Thu, 19 Jun 2003 12:38:14 -0400 Subject: [PATCH 2/8] Fix error msg. Bug #681 --- BitKeeper/etc/logging_ok | 1 + sql/nt_servc.cc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 092b6f3f2a5..9a826cffbfc 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -44,6 +44,7 @@ jorge@linux.jorge.mysql.com kaj@work.mysql.com lenz@kallisto.mysql.com lenz@mysql.com +miguel@hegel.(none) miguel@hegel.br miguel@hegel.local miguel@light. diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index b917c91ce15..b18d3d00d88 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -462,7 +462,7 @@ BOOL NTService::SeekStatus(LPCSTR szInternName, int OperationType) { /* a remove operation */ if (!(service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS ))) - printf("The service doesn't exists!\n"); + printf("The service doesn't exist!\n"); else { SERVICE_STATUS ss; From def18de12c49070e7ad52fd515bd0de4d90a0da9 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Fri, 20 Jun 2003 13:54:22 +0200 Subject: [PATCH 3/8] Warn that --log-slave-updates is used without --log-bin and disabled (WL#998) --- sql/mysqld.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0f3500248c0..318128f77e4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2322,6 +2322,12 @@ The server will not act as a slave."); opt_binlog_index_name,LOG_BIN); using_update_log=1; } + else if (opt_log_slave_updates) + { + sql_print_error("\ +Warning: you need to use --log-bin to make --log-slave-updates work. \ +Now disabling --log-slave-updates."); + } if (opt_bootstrap) { From 6f5cae43580cc792b2a42f049b79ead7e22919d7 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Fri, 20 Jun 2003 15:19:51 +0200 Subject: [PATCH 4/8] - added $(EXEEXT) to gen_lex_hash generation/execution to fix a build problem on Windows/cygwin (BUG#668) --- sql/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/Makefile.am b/sql/Makefile.am index a589f1379f9..e2494e50d96 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -114,8 +114,8 @@ sql_yacc.o: sql_yacc.cc sql_yacc.h $(CXXCOMPILE) $(LM_CFLAGS) -c $< lex_hash.h: lex.h gen_lex_hash.cc sql_yacc.h - $(MAKE) gen_lex_hash - ./gen_lex_hash > $@ + $(MAKE) gen_lex_hash$(EXEEXT) + ./gen_lex_hash$(EXEEXT) > $@ # Hack to ensure that lex_hash.h is built early sql_lex.o: lex_hash.h From e8a8b8c346b700aa246d089122e5880b2b40e5ae Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Fri, 20 Jun 2003 15:48:52 +0200 Subject: [PATCH 5/8] fix for BUG#691 (4.0 mysqlbinlog couldn't read 3.23 binlog). Safe parenthesis. --- client/mysqlbinlog.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 75b875b4f4e..9ef340197a7 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -396,8 +396,8 @@ static int check_header(IO_CACHE* file) if (buf[4] == START_EVENT) { uint event_len; - event_len = uint4korr(buf + 4); - old_format = (event_len < LOG_EVENT_HEADER_LEN + START_HEADER_LEN); + event_len = uint4korr(buf + EVENT_LEN_OFFSET); + old_format = (event_len < (LOG_EVENT_HEADER_LEN + START_HEADER_LEN)); } } my_b_seek(file, pos); From 04e5a6baa9e9a33539585456dce316e8e2fd1227 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sat, 21 Jun 2003 18:10:59 +0200 Subject: [PATCH 6/8] Always send a fake Rotate event (this is roughly 70 bytes) when starting binlog_dump. This way 3.23.58 slaves will always detect a 4.0.14 master (and stop) immediately. BUG#198. --- mysql-test/r/rpl_log.result | 2 +- mysql-test/r/rpl_log_pos.result | 2 +- sql/sql_repl.cc | 43 ++++++++++++++++++++++----------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index 425c376af1e..316bf1f3dd0 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -93,6 +93,6 @@ slave-bin.002 62 Query 1 168 use test; insert into t1 values (1) slave-bin.002 122 Query 1 228 use test; drop table t1 show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.002 276 slave-relay-bin.002 1522 master-bin.002 Yes Yes 0 0 276 1526 +127.0.0.1 root MASTER_PORT 1 master-bin.002 276 slave-relay-bin.002 1563 master-bin.002 Yes Yes 0 0 276 1567 show binlog events in 'slave-bin.005' from 4; Error when executing command SHOW BINLOG EVENTS: Could not find target log diff --git a/mysql-test/r/rpl_log_pos.result b/mysql-test/r/rpl_log_pos.result index e76b565813f..3224e84fa31 100644 --- a/mysql-test/r/rpl_log_pos.result +++ b/mysql-test/r/rpl_log_pos.result @@ -21,7 +21,7 @@ Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Lo slave start; show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 73 slave-relay-bin.001 4 master-bin.001 No Yes 0 0 73 4 +127.0.0.1 root MASTER_PORT 1 master-bin.001 73 slave-relay-bin.001 45 master-bin.001 No Yes 0 0 73 45 slave stop; change master to master_log_pos=173; slave start; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index e3af076da1f..a3cfe442b0f 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -51,7 +51,7 @@ int check_binlog_magic(IO_CACHE* log, const char** errmsg) } static int fake_rotate_event(NET* net, String* packet, char* log_file_name, - const char**errmsg) + ulonglong position, const char**errmsg) { char header[LOG_EVENT_HEADER_LEN], buf[ROTATE_HEADER_LEN]; memset(header, 0, 4); // when does not matter @@ -69,7 +69,7 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name, packet->append(header, sizeof(header)); /* We need to split the next statement because of problem with cxx */ - int4store(buf,4); // tell slave to skip magic number + int4store(buf,position); int4store(buf+4,0); packet->append(buf, ROTATE_HEADER_LEN); packet->append(p,ident_len); @@ -382,17 +382,30 @@ impossible position"; */ packet->set("\0", 1); - // if we are at the start of the log - if (pos == BIN_LOG_HEADER_SIZE) + /* + Before 4.0.14 we called fake_rotate_event below only if + (pos == BIN_LOG_HEADER_SIZE), because if this is false then the slave + already knows the binlog's name. + Now we always call fake_rotate_event; if the slave already knew the log's + name (ex: CHANGE MASTER TO MASTER_LOG_FILE=...) this is useless but does not + harm much. It is nice for 3.23 (>=.58) slaves which test Rotate events + to see if the master is 4.0 (then they choose to stop because they can't + replicate 4.0); by always calling fake_rotate_event we are sure that 3.23.58 + and newer will detect the problem as soon as replication starts (BUG#198). + Always calling fake_rotate_event makes sending of normal + (=from-binlog) Rotate events a priori unneeded, but it is not so simple: the + 2 Rotate events are not equivalent, the normal one is before the Stop event, + the fake one is after. If we don't send the normal one, then the Stop event + will be interpreted (by existing 4.0 slaves) as "the master stopped", which + is wrong. So for safety, given that we want minimum modification of 4.0, we + send the normal and fake Rotates. + */ + if (fake_rotate_event(net, packet, log_file_name, pos, &errmsg)) { - // tell the client log name with a fake rotate_event - if (fake_rotate_event(net, packet, log_file_name, &errmsg)) - { - my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; - goto err; - } - packet->set("\0", 1); + my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; + goto err; } + packet->set("\0", 1); while (!net->error && net->vio != 0 && !thd->killed) { @@ -585,10 +598,12 @@ Increase max_allowed_packet on master"; end_io_cache(&log); (void) my_close(file, MYF(MY_WME)); - // fake Rotate_log event just in case it did not make it to the log - // otherwise the slave make get confused about the offset + /* + Even if the previous log contained a Rotate_log_event, we still fake + one. + */ if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0 || - fake_rotate_event(net, packet, log_file_name, &errmsg)) + fake_rotate_event(net, packet, log_file_name, BIN_LOG_HEADER_SIZE, &errmsg)) { my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; goto err; From 9990ce576b666980904ae8202b079bdd8fdd00ba Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sun, 22 Jun 2003 14:10:46 +0200 Subject: [PATCH 7/8] Fixed cleanup_load_tmpdir() which deleted nothing. --- sql/log_event.cc | 9 ++++++--- sql/sql_repl.cc | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index ff968babcf0..727b2052969 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -168,12 +168,15 @@ static void cleanup_load_tmpdir() uint i; if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME)))) return; - + char fname[FN_REFLEN]; for (i=0 ; i < (uint)dirp->number_off_files; i++) { file=dirp->dir_entry+i; if (is_prefix(file->name,"SQL_LOAD-")) - my_delete(file->name, MYF(0)); + { + fn_format(fname,file->name,slave_load_tmpdir,"",0); + my_delete(fname, MYF(0)); + } } my_dirend(dirp); @@ -813,7 +816,7 @@ Rotate_log_event::Rotate_log_event(const char* buf, int event_len, int Rotate_log_event::write_data(IO_CACHE* file) { char buf[ROTATE_HEADER_LEN]; - int8store(buf, pos + R_POS_OFFSET); + int8store(buf + R_POS_OFFSET, pos); return (my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) || my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len)); } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index a3cfe442b0f..d0ed1a19d96 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -68,9 +68,12 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name, int4store(header + LOG_POS_OFFSET, 0); packet->append(header, sizeof(header)); - /* We need to split the next statement because of problem with cxx */ - int4store(buf,position); - int4store(buf+4,0); + /* + An old comment said talked about a need for splitting the int8store below + into 2 int4store because of a problem with cxx; I can't understand that as + we already use int8store in Rotatel_log_event::write_data(). + */ + int8store(buf+R_POS_OFFSET,position); packet->append(buf, ROTATE_HEADER_LEN); packet->append(p,ident_len); if (my_net_write(net, (char*)packet->ptr(), packet->length())) From e2efb08c505d6e5edafb06bfebf3b089815dbf27 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Sun, 22 Jun 2003 16:20:06 +0300 Subject: [PATCH 8/8] dict0dict.h, dict0dict.c, ha_innodb.cc: In ORDER BY MySQL seems to set the key read flag also in the case where the primary key contains only a prefix of a column - not the whole column; to prevent potential bugs retrieve the whole column if the index contains a prefix of it --- innobase/dict/dict0dict.c | 40 ++++++++++++++++++++++++++++++++++++ innobase/include/dict0dict.h | 10 +++++++++ sql/ha_innodb.cc | 11 ++++++---- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 2fc05b1923f..b1d7b5f762e 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -494,6 +494,46 @@ dict_index_get_nth_col_pos( return(ULINT_UNDEFINED); } +/************************************************************************ +Returns TRUE if the index contains a column or a prefix of that column. */ + +ibool +dict_index_contains_col_or_prefix( +/*==============================*/ + /* out: TRUE if contains the column or its + prefix */ + dict_index_t* index, /* in: index */ + ulint n) /* in: column number */ +{ + dict_field_t* field; + dict_col_t* col; + ulint pos; + ulint n_fields; + + ut_ad(index); + ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); + + if (index->type & DICT_CLUSTERED) { + + return(TRUE); + } + + col = dict_table_get_nth_col(index->table, n); + + n_fields = dict_index_get_n_fields(index); + + for (pos = 0; pos < n_fields; pos++) { + field = dict_index_get_nth_field(index, pos); + + if (col == field->col) { + + return(TRUE); + } + } + + return(FALSE); +} + /************************************************************************ Looks for a matching field in an index. The column and the prefix len have to be the same. */ diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index e88c6a52bcb..b5ec5381db2 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -569,6 +569,16 @@ dict_index_get_nth_col_pos( dict_index_t* index, /* in: index */ ulint n); /* in: column number */ /************************************************************************ +Returns TRUE if the index contains a column or a prefix of that column. */ + +ibool +dict_index_contains_col_or_prefix( +/*==============================*/ + /* out: TRUE if contains the column or its + prefix */ + dict_index_t* index, /* in: index */ + ulint n); /* in: column number */ +/************************************************************************ Looks for a matching field in an index. The column and the prefix len has to be the same. */ diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 795cffc0776..a6528209b3e 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -1863,7 +1863,11 @@ build_template( if (prebuilt->read_just_key) { /* MySQL has instructed us that it is enough to - fetch the columns in the key */ + fetch the columns in the key; looks like MySQL + can set this flag also when there is only a + prefix of the column in the key: in that case we + retrieve the whole column from the clustered + index */ fetch_all_in_key = TRUE; } else { @@ -1924,9 +1928,8 @@ build_template( field = table->field[i]; if (templ_type == ROW_MYSQL_REC_FIELDS - && !(fetch_all_in_key && - ULINT_UNDEFINED != dict_index_get_nth_col_pos( - index, i)) + && !(fetch_all_in_key + && dict_index_contains_col_or_prefix(index, i)) && thd->query_id != field->query_id && thd->query_id != (field->query_id ^ MAX_ULONG_BIT) && thd->query_id !=