From: Martin Skold Date: June 14 2012 11:49am Subject: bzr push into mysql-5.1-telco-7.1 branch (Martin.Skold:4569 to 4571) Bug#13824846 Bug#14185126 List-Archive: http://lists.mysql.com/commits/144222 X-Bug: 13824846,14185126 Message-Id: <20120614114920.BA1309F8D7F@quadfish> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 4571 Martin Skold 2012-06-14 Bug#13824846,Bug#14185126: Cleaning away stray files at server startup or at cluster reconnect (after restart) modified: mysql-test/suite/ndb/r/ndb_reconnect.result mysql-test/suite/ndb/t/ndb_reconnect.test sql/ha_ndbcluster.cc sql/ha_ndbcluster.h sql/ha_ndbcluster_binlog.cc 4570 Martin Skold 2012-06-14 WL#1735 Handler: "discover" database: publisized function make_db_list modified: sql/sql_show.cc sql/sql_show.h 4569 magnus.blaudd@stripped 2012-06-13 [merge] Merge 7.0 -> 7.1 modified: sql/ha_ndbcluster.cc === modified file 'mysql-test/suite/ndb/r/ndb_reconnect.result' --- a/mysql-test/suite/ndb/r/ndb_reconnect.result 2009-02-03 13:35:56 +0000 +++ b/mysql-test/suite/ndb/r/ndb_reconnect.result 2012-06-14 11:48:36 +0000 @@ -26,3 +26,33 @@ a b c 1 row 1 2 insert into t1 values (2, "row 1", 37); drop table t1; +create table t1(a int, b varchar(10), c date) engine=ndb; +CREATE TRIGGER trg1 BEFORE UPDATE ON t1 FOR EACH ROW BEGIN +SET new.c = '1901-01-01 01:01:01'; +End // +insert into t1 values (1, "row 1", NULL),(2, "row 2", NULL); +select * from t1 order by a; +a b c +1 row 1 NULL +2 row 2 NULL +create table t2(a int, b varchar(10), c date) engine=myisam; +CREATE TRIGGER trg2 BEFORE UPDATE ON t2 FOR EACH ROW BEGIN +SET new.c = '1901-01-01 01:01:01'; +End // +create table t1(a int, b varchar(10), c date) engine=ndb; +CREATE TRIGGER trg1 BEFORE UPDATE ON t1 FOR EACH ROW BEGIN +SET new.c = '1902-02-02 02:02:02'; +End // +insert into t1 values (1, "row 1", NULL),(2, "row 2", NULL); +select * from t1 order by a; +a b c +1 row 1 NULL +2 row 2 NULL +create table t2(a int, b varchar(10), c date) engine=myisam; +ERROR 42S01: Table 't2' already exists +drop table t2; +create table t2(a int, b varchar(10), c date) engine=myisam; +CREATE TRIGGER trg2 BEFORE UPDATE ON t2 FOR EACH ROW BEGIN +SET new.c = '1901-01-01 01:01:01'; +End // +drop table t1, t2; === modified file 'mysql-test/suite/ndb/t/ndb_reconnect.test' --- a/mysql-test/suite/ndb/t/ndb_reconnect.test 2009-06-06 13:04:45 +0000 +++ b/mysql-test/suite/ndb/t/ndb_reconnect.test 2012-06-14 11:48:36 +0000 @@ -76,3 +76,66 @@ insert into t1 values (2, "row 1", 37); # cleanup drop table t1; + +# +#Bug #13824846 FRM FILES ARE CREATED FOR MYSQLD, BUT TABLE DOES NOT EXIST IN CLUSTER +# + +connection default; +create table t1(a int, b varchar(10), c date) engine=ndb; +delimiter //; +CREATE TRIGGER trg1 BEFORE UPDATE ON t1 FOR EACH ROW BEGIN + SET new.c = '1901-01-01 01:01:01'; +End // +delimiter ;// + +insert into t1 values (1, "row 1", NULL),(2, "row 2", NULL); +select * from t1 order by a; + +create table t2(a int, b varchar(10), c date) engine=myisam; +delimiter //; +CREATE TRIGGER trg2 BEFORE UPDATE ON t2 FOR EACH ROW BEGIN + SET new.c = '1901-01-01 01:01:01'; +End // +delimiter ;// + +# Restart cluster nodes and clear all meta-data +--exec $NDB_MGM --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" -e "all restart -i" >> $NDB_TOOLS_OUTPUT +# Wait for all nodes to enter "started" +--exec $NDB_WAITER --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" >> $NDB_TOOLS_OUTPUT + +# +# Wait until the connection to the +# cluster has been restored or timeout occurs +# +connection default; +--disable_result_log +--disable_query_log +--source include/ndb_not_readonly.inc +--enable_result_log +--enable_query_log + +# Create the table again to check there are no conflicts +create table t1(a int, b varchar(10), c date) engine=ndb; +delimiter //; +CREATE TRIGGER trg1 BEFORE UPDATE ON t1 FOR EACH ROW BEGIN + SET new.c = '1902-02-02 02:02:02'; +End // +delimiter ;// + +insert into t1 values (1, "row 1", NULL),(2, "row 2", NULL); +select * from t1 order by a; + +# Check that only ndb tables have been cleaned away +--error ER_TABLE_EXISTS_ERROR +create table t2(a int, b varchar(10), c date) engine=myisam; +drop table t2; +create table t2(a int, b varchar(10), c date) engine=myisam; +delimiter //; +CREATE TRIGGER trg2 BEFORE UPDATE ON t2 FOR EACH ROW BEGIN + SET new.c = '1901-01-01 01:01:01'; +End // +delimiter ;// + +# cleanup +drop table t1, t2; === modified file 'sql/ha_ndbcluster.cc' --- a/sql/ha_ndbcluster.cc 2012-06-13 19:10:06 +0000 +++ b/sql/ha_ndbcluster.cc 2012-06-14 11:48:36 +0000 @@ -11519,8 +11519,19 @@ ndbcluster_find_files(handlerton *hton, { DBUG_PRINT("info", ("NDB says %s does not exists", file_name->str)); it.remove(); - // Put in list of tables to remove from disk - delete_list.push_back(thd->strdup(file_name->str)); + if (thd == injector_thd && + thd_ndb->options & TNO_NO_REMOVE_STRAY_FILES) + { + /* + Don't delete anything when called from + the binlog thread. This is a kludge to avoid + that something is deleted when "Ndb schema dist" + uses find_files() to check for "local tables in db" + */ + } + else + // Put in list of tables to remove from disk + delete_list.push_back(thd->strdup(file_name->str)); } } === modified file 'sql/ha_ndbcluster.h' --- a/sql/ha_ndbcluster.h 2012-06-07 10:58:14 +0000 +++ b/sql/ha_ndbcluster.h 2012-06-14 11:48:36 +0000 @@ -254,14 +254,19 @@ enum THD_NDB_OPTIONS In participating mysqld, do not try to acquire global schema lock, as one other mysqld already has the lock. */ - TNO_NO_LOCK_SCHEMA_OP= 1 << 1 + TNO_NO_LOCK_SCHEMA_OP= 1 << 1, /* Skip drop of ndb table in delete_table. Used when calling mysql_rm_table_part2 in "show tables", as we do not want to remove ndb tables "by mistake". The table should not exist in ndb in the first place. */ - ,TNO_NO_NDB_DROP_TABLE= 1 << 2 + TNO_NO_NDB_DROP_TABLE= 1 << 2, + /* + In participating mysqld, do not remove stray files + when dropping tables + */ + TNO_NO_REMOVE_STRAY_FILES= 1 <<3 }; enum THD_NDB_TRANS_OPTIONS === modified file 'sql/ha_ndbcluster_binlog.cc' --- a/sql/ha_ndbcluster_binlog.cc 2012-03-28 15:30:10 +0000 +++ b/sql/ha_ndbcluster_binlog.cc 2012-06-14 11:48:36 +0000 @@ -1476,6 +1476,48 @@ static void ndb_notify_tables_writable() } /* + + */ + +static void clean_away_stray_files(THD *thd) +{ + /* + Clean-up any stray files for non-existing NDB tables + */ + LOOKUP_FIELD_VALUES lookup_field_values; + bool with_i_schema; + List db_names; + List_iterator_fast it(db_names); + LEX_STRING *db_name; + List tab_names; + char path[FN_REFLEN + 1]; + + DBUG_ENTER("clean_away_stray_files"); + bzero((char*) &lookup_field_values, sizeof(LOOKUP_FIELD_VALUES)); + if (make_db_list(thd, &db_names, &lookup_field_values, &with_i_schema)) + { + thd->clear_error(); + DBUG_PRINT("info", ("Failed to find databases")); + DBUG_VOID_RETURN; + } + it.rewind(); + while ((db_name= it++)) + { + DBUG_PRINT("info", ("Found database %s", db_name->str)); + sql_print_information("NDB: Cleaning stray tables from database '%s'", + db_name->str); + build_table_filename(path, sizeof(path) - 1, db_name->str, "", "", 0); + if (find_files(thd, &tab_names, db_name->str, path, NullS, 0) + != FIND_FILES_OK) + { + thd->clear_error(); + DBUG_PRINT("info", ("Failed to find tables")); + } + } + DBUG_VOID_RETURN; +} + +/* Ndb has no representation of the database schema objects. The mysql.ndb_schema table contains the latest schema operations done via a mysqld, and thus reflects databases created/dropped/altered @@ -1616,7 +1658,7 @@ static int ndbcluster_find_all_databases if (database_exists) { /* drop missing database */ - sql_print_information("NDB: Discovered reamining database '%s'", db); + sql_print_information("NDB: Discovered remaining database '%s'", db); } } } @@ -1694,35 +1736,38 @@ ndb_binlog_setup(THD *thd) } } + clean_away_stray_files(thd); + if (ndbcluster_find_all_databases(thd)) { return false; } - if (!ndbcluster_find_all_files(thd)) + if (ndbcluster_find_all_files(thd)) { - mysql_mutex_lock(&LOCK_open); - ndb_binlog_tables_inited= TRUE; - if (ndb_binlog_tables_inited && - ndb_binlog_running && ndb_binlog_is_ready) - { - if (opt_ndb_extra_logging) - sql_print_information("NDB Binlog: ndb tables writable"); - close_cached_tables(NULL, NULL, TRUE, FALSE, FALSE); - - /* - Signal any waiting thread that ndb table setup is - now complete - */ - ndb_notify_tables_writable(); - } - mysql_mutex_unlock(&LOCK_open); - /* Signal injector thread that all is setup */ - pthread_cond_signal(&injector_cond); + return false; + } - return true; // Setup completed -> OK + mysql_mutex_lock(&LOCK_open); + ndb_binlog_tables_inited= TRUE; + if (ndb_binlog_tables_inited && + ndb_binlog_running && ndb_binlog_is_ready) + { + if (opt_ndb_extra_logging) + sql_print_information("NDB Binlog: ndb tables writable"); + close_cached_tables(NULL, NULL, TRUE, FALSE, FALSE); + + /* + Signal any waiting thread that ndb table setup is + now complete + */ + ndb_notify_tables_writable(); } - return false; + mysql_mutex_unlock(&LOCK_open); + /* Signal injector thread that all is setup */ + pthread_cond_signal(&injector_cond); + + return true; // Setup completed -> OK } /* @@ -2943,6 +2988,7 @@ ndb_binlog_thread_handle_schema_event(TH case SOT_DROP_DB: /* Drop the database locally if it only contains ndb tables */ thd_ndb_options.set(TNO_NO_LOCK_SCHEMA_OP); + thd_ndb_options.set(TNO_NO_REMOVE_STRAY_FILES); if (! ndbcluster_check_if_local_tables_in_db(thd, schema->db)) { const int no_print_error[1]= {0}; === modified file 'sql/sql_show.cc' --- a/sql/sql_show.cc 2012-06-07 09:06:47 +0000 +++ b/sql/sql_show.cc 2012-06-14 11:44:50 +0000 @@ -2453,11 +2453,13 @@ void calc_sum_of_all_status(STATUS_VAR * /* This is only used internally, but we need it here as a forward reference */ extern ST_SCHEMA_TABLE schema_tables[]; +#ifdef MCP_WL1735 typedef struct st_lookup_field_values { LEX_STRING db_value, table_value; bool wild_db_value, wild_table_value; } LOOKUP_FIELD_VALUES; +#endif /* === modified file 'sql/sql_show.h' --- a/sql/sql_show.h 2011-06-30 15:55:35 +0000 +++ b/sql/sql_show.h 2012-06-14 11:44:50 +0000 @@ -26,12 +26,26 @@ struct st_ha_create_information; typedef st_ha_create_information HA_CREATE_INFO; struct TABLE_LIST; +#ifndef MCP_WL1735 +typedef struct st_lookup_field_values +{ + LEX_STRING db_value, table_value; + bool wild_db_value, wild_table_value; +} LOOKUP_FIELD_VALUES; +#endif + enum find_files_result { FIND_FILES_OK, FIND_FILES_OOM, FIND_FILES_DIR }; +#ifndef MCP_WL1735 +int make_db_list(THD *thd, List *files, + LOOKUP_FIELD_VALUES *lookup_field_vals, + bool *with_i_schema); +#endif + find_files_result find_files(THD *thd, List *files, const char *db, const char *path, const char *wild, bool dir); No bundle (reason: useless for push emails).