From 21f4e8aadbe9d8d79254c7a15878d497ebce8ae0 Mon Sep 17 00:00:00 2001 From: "tnurnberg@mysql.com" <> Date: Mon, 8 May 2006 04:37:58 +0200 Subject: [PATCH 01/11] Bug#10418: LOAD_FILE does not behave like in manual if file does not exist load_file() string-function should return NULL rather than throw an error if the file doesn't exist, as per the manual. --- mysql-test/r/func_str.result | 7 +++++++ mysql-test/r/outfile.result | Bin 959 -> 988 bytes mysql-test/t/func_str.test | 9 ++++++++- mysql-test/t/outfile.test | 1 - sql/item_strfunc.cc | 2 +- 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index ae6578795f6..0609624af18 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1000,3 +1000,10 @@ t 1000000 1 drop table t1; +select load_file("lkjlkj"); +load_file("lkjlkj") +NULL +select ifnull(load_file("lkjlkj"),"it's null"); +ifnull(load_file("lkjlkj"),"it's null") +it's null +End of 4.1 tests diff --git a/mysql-test/r/outfile.result b/mysql-test/r/outfile.result index 5eb24a78ef0d0242fcdd2f0ad1dfbf47f9d60dac..bcafae831d560242e84f6ab21d5d454deaf87079 100644 GIT binary patch delta 25 hcmdnbeusU-U&e{cG$y}ic_ptr(), mysql_real_data_home, "", MY_RELATIVE_PATH | MY_UNPACK_FILENAME); - if (!my_stat(path, &stat_info, MYF(MY_WME))) + if (!my_stat(path, &stat_info, MYF(0))) goto err; if (!(stat_info.st_mode & S_IROTH)) From a15415cc04e896e41df664ecaaf8e152a055b436 Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Tue, 9 May 2006 11:01:50 +0200 Subject: [PATCH 02/11] BUG#16803 "ln -s /dev/null .mysql_history" doesn't work! - Add a check to see if the .mysql_history file a symlink to /dev/null and in such case, skip reading and writing to it. --- client/mysql.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/client/mysql.cc b/client/mysql.cc index 7b46aaf67ce..dcf80ff2b0b 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -448,6 +448,14 @@ int main(int argc,char *argv[]) MYF(MY_WME)); if (histfile) sprintf(histfile,"%s/.mysql_history",getenv("HOME")); + char link_name[FN_REFLEN]; + if (my_readlink(link_name, histfile, 0) == 0 && + strncmp(link_name, "/dev/null", 10) == 0) + { + /* The .mysql_history file is a symlink to /dev/null, don't use it */ + my_free(histfile, MYF(MY_ALLOW_ZERO_PTR)); + histfile= 0; + } } if (histfile) { @@ -484,7 +492,7 @@ sig_handler mysql_end(int sig) { mysql_close(&mysql); #ifdef HAVE_READLINE - if (!status.batch && !quick && !opt_html && !opt_xml) + if (!status.batch && !quick && !opt_html && !opt_xml && histfile) { /* write-history */ if (verbose) From d1417ad55a1b1b53abdde1034ba3fd52599c8244 Mon Sep 17 00:00:00 2001 From: "igor@rurik.mysql.com" <> Date: Thu, 11 May 2006 19:47:00 -0700 Subject: [PATCH 03/11] Added a test case for bug #18940:in 5.0 the optimizer chose a worse execution plan than in 4.1 for some queries. It happened due the fact that at some conditions the optimizer always preferred range or full index scan access methods to lookup access methods even when the latter were much cheaper. The problem was not observed in 4.1 for the reported query because the WHERE condition was not of a form that could cause the problem. Equality propagation introduced on 5.0 added an extra predicate and changed the WHERE condition. The new condition provoked the optimizer to make a bad choice. The problem was fixed by the patch for bug 17379. --- mysql-test/r/select.result | 19 +++++++++++++++++++ mysql-test/t/select.test | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 3aae29a922e..335637b787f 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3427,3 +3427,22 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE A range PRIMARY PRIMARY 12 NULL 3 Using where 1 SIMPLE B ref PRIMARY PRIMARY 8 const,test.A.e 10 drop table t1, t2; +CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX(b)); +INSERT INTO t1 VALUES (1, 3), (9,4), (7,5), (4,5), (6,2), +(3,1), (5,1), (8,9), (2,2), (0,9); +CREATE TABLE t2 (c int, d int, f int, INDEX(c,f)); +INSERT INTO t2 VALUES +(1,0,0), (1,0,1), (2,0,0), (2,0,1), (3,0,0), (4,0,1), +(5,0,0), (5,0,1), (6,0,0), (0,0,1), (7,0,0), (7,0,1), +(0,0,0), (0,0,1), (8,0,0), (8,0,1), (9,0,0), (9,0,1); +EXPLAIN +SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where +1 SIMPLE t2 ref c c 5 test.t1.a 2 Using where +EXPLAIN +SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where +1 SIMPLE t2 ref c c 5 test.t1.a 2 Using where +DROP TABLE t1, t2; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 033350d138a..4b6ae921b9b 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2899,3 +2899,24 @@ select 'In next EXPLAIN, B.rows must be exactly 10:' Z; explain select * from t2 A, t2 B where A.a=5 and A.b=5 and A.C<5 and B.a=5 and B.b=A.e and (B.b =1 or B.b = 3 or B.b=5); drop table t1, t2; + +# +#Bug #18940: selection of optimal execution plan caused by equality +# propagation (the bug was fixed by the patch for bug #17379) + +CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX(b)); +INSERT INTO t1 VALUES (1, 3), (9,4), (7,5), (4,5), (6,2), + (3,1), (5,1), (8,9), (2,2), (0,9); + +CREATE TABLE t2 (c int, d int, f int, INDEX(c,f)); +INSERT INTO t2 VALUES + (1,0,0), (1,0,1), (2,0,0), (2,0,1), (3,0,0), (4,0,1), + (5,0,0), (5,0,1), (6,0,0), (0,0,1), (7,0,0), (7,0,1), + (0,0,0), (0,0,1), (8,0,0), (8,0,1), (9,0,0), (9,0,1); + +EXPLAIN +SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6; +EXPLAIN +SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0; + +DROP TABLE t1, t2; From d3dd0752277589882ed5c427078e382f8613f56f Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Fri, 12 May 2006 09:13:37 +0200 Subject: [PATCH 04/11] Bug#19709 rpl_tmporary fails on powermacg5 - Don't kill the active connection to the server, instead read the connection id, switch connection and kill the first one from there. --- mysql-test/r/rpl_temporary.result | 2 -- mysql-test/t/rpl_temporary.test | 14 ++++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/rpl_temporary.result b/mysql-test/r/rpl_temporary.result index 42e7712750c..da85ef5104d 100644 --- a/mysql-test/r/rpl_temporary.result +++ b/mysql-test/r/rpl_temporary.result @@ -109,8 +109,6 @@ create temporary table t102 (id int); set @session.pseudo_thread_id=200; create temporary table t201 (id int); create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int); -set @con1_id=connection_id(); -kill @con1_id; create table t1(f int); insert into t1 values (1); select * from t1 /* must be 1 */; diff --git a/mysql-test/t/rpl_temporary.test b/mysql-test/t/rpl_temporary.test index facf0d68d2b..7d2222ea79a 100644 --- a/mysql-test/t/rpl_temporary.test +++ b/mysql-test/t/rpl_temporary.test @@ -169,8 +169,18 @@ create temporary table t102 (id int); set @session.pseudo_thread_id=200; create temporary table t201 (id int); create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int); -set @con1_id=connection_id(); -kill @con1_id; + +# +# Don't kill our own connection to the server as +# the result code differs depending on platform. +# +# Select the id to kill into a variable of mysqltest +let $con1_id= `select connection_id()`; +# Switch connection to avoid killing our own connection +connection master; +--disable_query_log +eval kill $con1_id; +--enable_query_log #now do something to show that slave is ok after DROP temp tables connection master; From aa0b249fdd48990b5c114cb815943c70e4fb7b1d Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Fri, 12 May 2006 11:00:34 +0200 Subject: [PATCH 05/11] Correct spelling errors --- include/sslopt-longopts.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h index f444a7eb7ce..b0769af10fe 100644 --- a/include/sslopt-longopts.h +++ b/include/sslopt-longopts.h @@ -39,7 +39,7 @@ 0, 0, 0, 0, 0, 0}, #ifdef MYSQL_CLIENT {"ssl-verify-server-cert", OPT_SSL_VERIFY_SERVER_CERT, - "Verify servers \"Common Name\" in it's cert against hostname used when connecting. This option is disabled by default.", + "Verify server's \"Common Name\" in its cert against hostname used when connecting. This option is disabled by default.", (gptr*) &opt_ssl_verify_server_cert, (gptr*) &opt_ssl_verify_server_cert, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif From c8944add73cbcfa5c176142b23c90fd77f9f1ceb Mon Sep 17 00:00:00 2001 From: "gluh@eagle.intranet.mysql.r18.ru" <> Date: Fri, 12 May 2006 15:09:25 +0500 Subject: [PATCH 06/11] Fix for bug#19236 bad COLUMNS.CHARACTER_MAXIMUM_LENGHT and CHARACTER_OCTET_LENGTH --- mysql-test/r/information_schema.result | 8 ++++++++ mysql-test/r/join.result | 4 ++-- mysql-test/t/information_schema.test | 9 +++++++++ sql/sql_show.cc | 2 +- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 5224971890a..7d244cbe19c 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1091,3 +1091,11 @@ group by column_type order by num; column_type group_concat(table_schema, '.', table_name) num varchar(20) information_schema.COLUMNS 1 varchar(7) information_schema.ROUTINES,information_schema.VIEWS 2 +create table t1(f1 char(1) not null, f2 char(9) not null) +default character set utf8; +select CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH from +information_schema.columns where table_schema='test' and table_name = 't1'; +CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH +1 3 +9 27 +drop table t1; diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index ecf76d477a0..86288caf398 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -700,8 +700,8 @@ ERROR 42S22: Unknown column 't1.b' in 'on clause' select * from information_schema.statistics join information_schema.columns using(table_name,column_name) where table_name='user'; TABLE_NAME COLUMN_NAME TABLE_CATALOG TABLE_SCHEMA NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT TABLE_CATALOG TABLE_SCHEMA ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT -user Host NULL mysql 0 mysql PRIMARY 1 A NULL NULL NULL BTREE NULL mysql 1 NO char 20 60 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references -user User NULL mysql 0 mysql PRIMARY 2 A 5 NULL NULL BTREE NULL mysql 2 NO char 5 16 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references +user Host NULL mysql 0 mysql PRIMARY 1 A NULL NULL NULL BTREE NULL mysql 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references +user User NULL mysql 0 mysql PRIMARY 2 A 5 NULL NULL BTREE NULL mysql 2 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references drop table t1; drop table t2; drop table t3; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 11178adbc9b..f8032d71440 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -802,3 +802,12 @@ from information_schema.columns where table_schema='information_schema' and (column_type = 'varchar(7)' or column_type = 'varchar(20)') group by column_type order by num; + +# +# Bug#19236 bad COLUMNS.CHARACTER_MAXIMUM_LENGHT and CHARACTER_OCTET_LENGTH +# +create table t1(f1 char(1) not null, f2 char(9) not null) +default character set utf8; +select CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH from +information_schema.columns where table_schema='test' and table_name = 't1'; +drop table t1; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 126abb96f61..1484274b3dc 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2662,7 +2662,7 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, field->real_type() == MYSQL_TYPE_STRING) // For binary type { uint32 octet_max_length= field->max_length(); - if (octet_max_length != (uint32) 4294967295U) + if (is_blob && octet_max_length != (uint32) 4294967295U) octet_max_length /= field->charset()->mbmaxlen; longlong char_max_len= is_blob ? (longlong) octet_max_length / field->charset()->mbminlen : From cc8e75901ac3eeb4693d0abf24a8b04e01c52ddc Mon Sep 17 00:00:00 2001 From: "tnurnberg@mysql.com" <> Date: Fri, 12 May 2006 12:31:22 +0200 Subject: [PATCH 07/11] merge fixies BUG#10418 4.1 -> 5.0 --- mysql-test/r/outfile.result | Bin 1106 -> 1159 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/mysql-test/r/outfile.result b/mysql-test/r/outfile.result index b75b53e51a513e3bc00a8e185e83230c3c2d4f53..040dff576f87ba9c615679088f44846babb424f9 100644 GIT binary patch delta 19 bcmcb_(ayPH1=GZ38k1)+@oZksw3-nBPN4^9 delta 12 TcmZqYyu`6#1=HrcOsg0HA+ZGl From a23a8780e43eeec21a053d3bc8b1cfb05114be15 Mon Sep 17 00:00:00 2001 From: "gluh@eagle.intranet.mysql.r18.ru" <> Date: Fri, 12 May 2006 17:34:36 +0500 Subject: [PATCH 08/11] Fix for bug#18177 any access to INFORMATION_SCHEMA.ROUTINES crashes replaced get_field(MEM_ROOT *mem, Field *field) with get_field(MEM_ROOT *mem, Field *field, String *res). It allows to avoid strlen(). --- mysql-test/r/information_schema.result | 9 +++++++++ mysql-test/t/information_schema.test | 11 +++++++++++ sql/sql_show.cc | 23 ++++++++++++----------- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 7d244cbe19c..633b11e1f1b 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1099,3 +1099,12 @@ CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH 1 3 9 27 drop table t1; +use mysql; +INSERT INTO `proc` VALUES ('test','','PROCEDURE','','SQL','CONTAINS_SQL', +'NO','DEFINER','','','BEGIN\r\n \r\nEND','root@%','2006-03-02 18:40:03', +'2006-03-02 18:40:03','',''); +select routine_name from information_schema.routines; +routine_name + +delete from proc where name=''; +use test; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index f8032d71440..e96f1ef4bbd 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -811,3 +811,14 @@ default character set utf8; select CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH from information_schema.columns where table_schema='test' and table_name = 't1'; drop table t1; + +# +# Bug#18177 any access to INFORMATION_SCHEMA.ROUTINES crashes +# +use mysql; +INSERT INTO `proc` VALUES ('test','','PROCEDURE','','SQL','CONTAINS_SQL', +'NO','DEFINER','','','BEGIN\r\n \r\nEND','root@%','2006-03-02 18:40:03', +'2006-03-02 18:40:03','',''); +select routine_name from information_schema.routines; +delete from proc where name=''; +use test; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1484274b3dc..70bdef302df 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2854,17 +2854,18 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, const char *wild, bool full_access, const char *sp_user) { String tmp_string; + String sp_db, sp_name, definer; TIME time; LEX *lex= thd->lex; CHARSET_INFO *cs= system_charset_info; - const char *sp_db, *sp_name, *definer; - sp_db= get_field(thd->mem_root, proc_table->field[0]); - sp_name= get_field(thd->mem_root, proc_table->field[1]); - definer= get_field(thd->mem_root, proc_table->field[11]); + get_field(thd->mem_root, proc_table->field[0], &sp_db); + get_field(thd->mem_root, proc_table->field[1], &sp_name); + get_field(thd->mem_root, proc_table->field[11], &definer); if (!full_access) - full_access= !strcmp(sp_user, definer); - if (!full_access && check_some_routine_access(thd, sp_db, sp_name, - proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE)) + full_access= !strcmp(sp_user, definer.ptr()); + if (!full_access && check_some_routine_access(thd, sp_db.ptr(), sp_name.ptr(), + proc_table->field[2]->val_int() == + TYPE_ENUM_PROCEDURE)) return 0; if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC && @@ -2874,13 +2875,13 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, lex->orig_sql_command == SQLCOM_END) { restore_record(table, s->default_values); - if (!wild || !wild[0] || !wild_compare(sp_name, wild, 0)) + if (!wild || !wild[0] || !wild_compare(sp_name.ptr(), wild, 0)) { int enum_idx= proc_table->field[5]->val_int(); - table->field[3]->store(sp_name, strlen(sp_name), cs); + table->field[3]->store(sp_name.ptr(), sp_name.length(), cs); get_field(thd->mem_root, proc_table->field[3], &tmp_string); table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs); - table->field[2]->store(sp_db, strlen(sp_db), cs); + table->field[2]->store(sp_db.ptr(), sp_db.length(), cs); get_field(thd->mem_root, proc_table->field[2], &tmp_string); table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs); if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION) @@ -2912,7 +2913,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs); get_field(thd->mem_root, proc_table->field[15], &tmp_string); table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs); - table->field[19]->store(definer, strlen(definer), cs); + table->field[19]->store(definer.ptr(), definer.length(), cs); return schema_table_store_record(thd, table); } } From fe9934c9fe7a783fac72d04ab7a47b7b9a72489c Mon Sep 17 00:00:00 2001 From: "tomas@poseidon.ndb.mysql.com" <> Date: Mon, 15 May 2006 16:23:59 +0200 Subject: [PATCH 09/11] Bug #16875 Using stale MySQLD FRM files can cause restored cluster to fail - invalidate ndb dict cache on cluster disconnect (ClusterMgr.cpp) - add check for correct frm on external lock when table cache is found invalid --- mysql-test/r/ndb_autodiscover3.result | 9 +++ mysql-test/t/ndb_autodiscover3.test | 65 +++++++++++++++++++ ndb/include/ndbapi/ndb_cluster_connection.hpp | 1 + ndb/src/ndbapi/ClusterMgr.cpp | 5 ++ ndb/src/ndbapi/ClusterMgr.hpp | 1 + ndb/src/ndbapi/DictCache.cpp | 36 ++++++++++ ndb/src/ndbapi/DictCache.hpp | 3 + ndb/src/ndbapi/TransporterFacade.hpp | 6 ++ ndb/src/ndbapi/ndb_cluster_connection.cpp | 6 ++ .../ndbapi/ndb_cluster_connection_impl.hpp | 1 + sql/ha_ndbcluster.cc | 17 ++++- 11 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/ndb_autodiscover3.result create mode 100644 mysql-test/t/ndb_autodiscover3.test diff --git a/mysql-test/r/ndb_autodiscover3.result b/mysql-test/r/ndb_autodiscover3.result new file mode 100644 index 00000000000..9773addd928 --- /dev/null +++ b/mysql-test/r/ndb_autodiscover3.result @@ -0,0 +1,9 @@ +drop table if exists t1; +create table t1 (a int key) engine=ndbcluster; +begin; +insert into t1 values (1); +insert into t1 values (2); +ERROR HY000: Got temporary error 4025 'Node failure caused abort of transaction' from ndbcluster +commit; +ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster +drop table t1; diff --git a/mysql-test/t/ndb_autodiscover3.test b/mysql-test/t/ndb_autodiscover3.test new file mode 100644 index 00000000000..73b4bf8b94f --- /dev/null +++ b/mysql-test/t/ndb_autodiscover3.test @@ -0,0 +1,65 @@ +-- source include/have_ndb.inc +-- source include/have_multi_ndb.inc +-- source include/not_embedded.inc + + +--disable_warnings +drop table if exists t1, t2; +--enable_warnings + +# +# Transaction ongoing while cluster is restarted +# +--connection server1 +create table t1 (a int key) engine=ndbcluster; + +begin; +insert into t1 values (1); + +--exec $NDB_MGM --no-defaults -e "all restart" >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT + +--error 1297 +insert into t1 values (2); +--error 1296 +commit; + +drop table t1; + +# +# Stale cache after restart -i +# +--connection server1 +create table t2 (a int, b int, primary key(a,b)) engine=ndbcluster; +insert into t2 values (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1); +select * from t2 order by a limit 3; + +--exec $NDB_MGM --no-defaults -e "all restart -i" >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT + +--connection server2 +create table t2 (a int key) engine=ndbcluster; +insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +select * from t2 order by a limit 3; + +# server 1 should have a stale cache, and in this case wrong frm, transaction must be retried +--connection server1 +--error 1015 +select * from t2 order by a limit 3; +select * from t2 order by a limit 3; + +--exec $NDB_MGM --no-defaults -e "all restart -i" >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT + +--connection server1 +show tables; +create table t2 (a int key) engine=ndbcluster; +insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +select * from t2 order by a limit 3; + +# server 2 should have a stale cache, but with right frm, transaction need not be retried +--connection server2 +select * from t2 order by a limit 3; + +drop table t2; +# End of 4.1 tests diff --git a/ndb/include/ndbapi/ndb_cluster_connection.hpp b/ndb/include/ndbapi/ndb_cluster_connection.hpp index 0e559700716..3fe66bd2d44 100644 --- a/ndb/include/ndbapi/ndb_cluster_connection.hpp +++ b/ndb/include/ndbapi/ndb_cluster_connection.hpp @@ -83,6 +83,7 @@ public: void set_optimized_node_selection(int val); unsigned no_db_nodes(); + unsigned get_connect_count() const; #endif private: diff --git a/ndb/src/ndbapi/ClusterMgr.cpp b/ndb/src/ndbapi/ClusterMgr.cpp index 543bdf1155e..cd559a544a8 100644 --- a/ndb/src/ndbapi/ClusterMgr.cpp +++ b/ndb/src/ndbapi/ClusterMgr.cpp @@ -70,6 +70,7 @@ ClusterMgr::ClusterMgr(TransporterFacade & _facade): noOfAliveNodes= 0; noOfConnectedNodes= 0; theClusterMgrThread= 0; + m_connect_count = 0; DBUG_VOID_RETURN; } @@ -456,6 +457,10 @@ ClusterMgr::reportNodeFailed(NodeId nodeId){ theNode.nfCompleteRep = false; if(noOfAliveNodes == 0){ + theFacade.m_globalDictCache.lock(); + theFacade.m_globalDictCache.invalidate_all(); + theFacade.m_globalDictCache.unlock(); + m_connect_count ++; NFCompleteRep rep; for(Uint32 i = 1; i > * curr = m_tableHash.getNext(0); + int sz = 0; + while(curr != 0){ + sz += curr->theData->size(); + curr = m_tableHash.getNext(curr); + } + return sz; +} + +void +GlobalDictCache::invalidate_all() +{ + DBUG_ENTER("GlobalDictCache::invalidate_all"); + NdbElement_t > * curr = m_tableHash.getNext(0); + while(curr != 0){ + Vector * vers = curr->theData; + if (vers->size()) + { + TableVersion * ver = & vers->back(); + ver->m_impl->m_status = NdbDictionary::Object::Invalid; + ver->m_status = DROPPED; + if (ver->m_refCount == 0) + { + delete ver->m_impl; + vers->erase(vers->size() - 1); + } + } + curr = m_tableHash.getNext(curr); + } + DBUG_VOID_RETURN; +} + void GlobalDictCache::release(NdbTableImpl * tab){ unsigned i; diff --git a/ndb/src/ndbapi/DictCache.hpp b/ndb/src/ndbapi/DictCache.hpp index 7f2ee457476..52bd57ea217 100644 --- a/ndb/src/ndbapi/DictCache.hpp +++ b/ndb/src/ndbapi/DictCache.hpp @@ -71,6 +71,9 @@ public: void alter_table_rep(const char * name, Uint32 tableId, Uint32 tableVersion, bool altered); + + unsigned get_size(); + void invalidate_all(); public: enum Status { OK = 0, diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp index 7e010d45945..b8963b8d0e1 100644 --- a/ndb/src/ndbapi/TransporterFacade.hpp +++ b/ndb/src/ndbapi/TransporterFacade.hpp @@ -264,6 +264,12 @@ TransporterFacade::unlock_mutex() #include "ClusterMgr.hpp" +inline +unsigned Ndb_cluster_connection_impl::get_connect_count() const +{ + return TransporterFacade::instance()->theClusterMgr->m_connect_count; +} + inline bool TransporterFacade::check_send_size(Uint32 node_id, Uint32 send_size) diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index a313a973a42..df744fb3261 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -236,6 +236,12 @@ Ndb_cluster_connection::wait_until_ready(int timeout, } while (1); } +unsigned Ndb_cluster_connection::get_connect_count() const +{ + return m_impl.get_connect_count(); +} + + /* diff --git a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp index 620eac296a3..ee561c1d6af 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp +++ b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp @@ -49,6 +49,7 @@ class Ndb_cluster_connection_impl : public Ndb_cluster_connection void init_get_next_node(Ndb_cluster_connection_node_iter &iter); Uint32 get_next_node(Ndb_cluster_connection_node_iter &iter); + inline unsigned get_connect_count() const; private: friend class Ndb; friend class NdbImpl; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 876d5d2f8fd..c0eae685a52 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3306,8 +3306,23 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) { m_table= (void *)tab; m_table_version = tab->getObjectVersion(); - if (!(my_errno= build_index_list(ndb, table, ILBP_OPEN))) + if ((my_errno= build_index_list(ndb, table, ILBP_OPEN))) DBUG_RETURN(my_errno); + + const void *data, *pack_data; + uint length, pack_length; + if (readfrm(table->path, &data, &length) || + packfrm(data, length, &pack_data, &pack_length) || + pack_length != tab->getFrmLength() || + memcmp(pack_data, tab->getFrmData(), pack_length)) + { + my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR)); + my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR)); + NdbError err= ndb->getNdbError(NDB_INVALID_SCHEMA_OBJECT); + DBUG_RETURN(ndb_to_mysql_error(&err)); + } + my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR)); + my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR)); } m_table_info= tab_info; } From 271c72aa03ba0b7f5613a7d5cfea9fcb5620f99c Mon Sep 17 00:00:00 2001 From: "tomas@poseidon.ndb.mysql.com" <> Date: Mon, 15 May 2006 17:16:21 +0200 Subject: [PATCH 10/11] Bug #16875 , correction of previous patch --- mysql-test/r/ndb_autodiscover3.result | 38 ++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ndb_autodiscover3.result b/mysql-test/r/ndb_autodiscover3.result index 9773addd928..8bc1b968436 100644 --- a/mysql-test/r/ndb_autodiscover3.result +++ b/mysql-test/r/ndb_autodiscover3.result @@ -1,4 +1,4 @@ -drop table if exists t1; +drop table if exists t1, t2; create table t1 (a int key) engine=ndbcluster; begin; insert into t1 values (1); @@ -7,3 +7,39 @@ ERROR HY000: Got temporary error 4025 'Node failure caused abort of transaction' commit; ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster drop table t1; +create table t2 (a int, b int, primary key(a,b)) engine=ndbcluster; +insert into t2 values (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1); +select * from t2 order by a limit 3; +a b +1 1 +2 1 +3 1 +create table t2 (a int key) engine=ndbcluster; +insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +select * from t2 order by a limit 3; +a +1 +2 +3 +select * from t2 order by a limit 3; +ERROR HY000: Can't lock file (errno: 241) +select * from t2 order by a limit 3; +a +1 +2 +3 +show tables; +Tables_in_test +create table t2 (a int key) engine=ndbcluster; +insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +select * from t2 order by a limit 3; +a +1 +2 +3 +select * from t2 order by a limit 3; +a +1 +2 +3 +drop table t2; From ca4b18fb15468ee8082417a71b2d53ef97300893 Mon Sep 17 00:00:00 2001 From: "tomas@poseidon.ndb.mysql.com" <> Date: Mon, 15 May 2006 20:29:50 +0200 Subject: [PATCH 11/11] correction of merge --- sql/ha_ndbcluster.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 8baaf6d76b5..3d9bd2dbe0f 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3517,7 +3517,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) const void *data, *pack_data; uint length, pack_length; - if (readfrm(table->path, &data, &length) || + if (readfrm(table->s->path, &data, &length) || packfrm(data, length, &pack_data, &pack_length) || pack_length != tab->getFrmLength() || memcmp(pack_data, tab->getFrmData(), pack_length))