From dd934da9159a6eb69fdd7fdd91a78c801a0b7caa Mon Sep 17 00:00:00 2001 From: unknown 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/t/outfile.test: expect NULL rather than error if file given to load_file() doesn't exist mysql-test/t/func_str.test: show that load_file() will return NULL rather than throw an error if file doesn't exist mysql-test/r/outfile.result: expect NULL rather than error if file given to load_file() doesn't exist mysql-test/r/func_str.result: expect NULL rather than error if file given to load_file() doesn't exist sql/item_strfunc.cc: load_file() should return NULL as per the docs if file not found, rather than throw an error --- 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 4a25f40090f1a2ad0124f28e3eb0a9ccbc1cb55c Mon Sep 17 00:00:00 2001 From: unknown 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: Add check to detect if the "mysql_history" file is a symlink to /dev/null. In that case, don't create histfile variable. That will make read_history and write_history to be skipped. --- 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 5c6d923f3095f5eca3abaa5277350bec90e4970c Mon Sep 17 00:00:00 2001 From: unknown 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: Added a test case for bug #18940. The problem was fixed by the patch for bug 17379. mysql-test/t/select.test: Added a test case for bug #18940. 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 acf1879938049f2c429d9a4aa7559ec9f495721d Mon Sep 17 00:00:00 2001 From: unknown 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: Update test result mysql-test/t/rpl_temporary.test: Don't kill our own connection to the server as the result code differs depending on platform. --- 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 f7d265a99c7687c5a22e57824f0abefee6ad24a1 Mon Sep 17 00:00:00 2001 From: unknown 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 af797c16fe81f94bd61c1a6e1fab7c71f2a13d3c Mon Sep 17 00:00:00 2001 From: unknown 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: Fix for bug#19236 bad COLUMNS.CHARACTER_MAXIMUM_LENGHT and CHARACTER_OCTET_LENGTH test case mysql-test/r/join.result: Fix for bug#19236 bad COLUMNS.CHARACTER_MAXIMUM_LENGHT and CHARACTER_OCTET_LENGTH result fix mysql-test/t/information_schema.test: Fix for bug#19236 bad COLUMNS.CHARACTER_MAXIMUM_LENGHT and CHARACTER_OCTET_LENGTH test case --- 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 e52288b5bf86507e0a5cc4aca6d3bd41d79ce63d Mon Sep 17 00:00:00 2001 From: unknown 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 9ffa09be96e39a753d70176b9b25cc1a298a9159 Mon Sep 17 00:00:00 2001 From: unknown 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: Fix for bug#18177 any access to INFORMATION_SCHEMA.ROUTINES crashes test case mysql-test/t/information_schema.test: Fix for bug#18177 any access to INFORMATION_SCHEMA.ROUTINES crashes test case --- 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 37f940ce86615ed0ae16e210ebc4fa92e8dfb2a6 Mon Sep 17 00:00:00 2001 From: unknown 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 ndb/include/ndbapi/ndb_cluster_connection.hpp: Bug #16875 Using stale MySQLD FRM files can cause restored cluster to fail ndb/src/ndbapi/ClusterMgr.cpp: Bug #16875 Using stale MySQLD FRM files can cause restored cluster to fail ndb/src/ndbapi/ClusterMgr.hpp: Bug #16875 Using stale MySQLD FRM files can cause restored cluster to fail ndb/src/ndbapi/DictCache.cpp: Bug #16875 Using stale MySQLD FRM files can cause restored cluster to fail ndb/src/ndbapi/DictCache.hpp: Bug #16875 Using stale MySQLD FRM files can cause restored cluster to fail ndb/src/ndbapi/TransporterFacade.hpp: Bug #16875 Using stale MySQLD FRM files can cause restored cluster to fail ndb/src/ndbapi/ndb_cluster_connection.cpp: Bug #16875 Using stale MySQLD FRM files can cause restored cluster to fail ndb/src/ndbapi/ndb_cluster_connection_impl.hpp: Bug #16875 Using stale MySQLD FRM files can cause restored cluster to fail sql/ha_ndbcluster.cc: Bug #16875 Using stale MySQLD FRM files can cause restored cluster to fail mysql-test/r/ndb_autodiscover3.result: Bug #16875 Using stale MySQLD FRM files can cause restored cluster to fail mysql-test/t/ndb_autodiscover3.test: Bug #16875 Using stale MySQLD FRM files can cause restored cluster to fail --- 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 e399658517f7d9efbc133870aace09b7bfc6f1b0 Mon Sep 17 00:00:00 2001 From: unknown 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 326ebe4c5bc162a42adff43c138af144a02cdcb0 Mon Sep 17 00:00:00 2001 From: unknown 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))