diff options
-rw-r--r-- | BitKeeper/etc/logging_ok | 1 | ||||
-rw-r--r-- | mysql-test/t/ndb_autodiscover.test | 34 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 167 | ||||
-rw-r--r-- | sql/ha_ndbcluster.h | 2 | ||||
-rw-r--r-- | sql/handler.cc | 4 | ||||
-rw-r--r-- | sql/handler.h | 2 | ||||
-rw-r--r-- | sql/sql_show.cc | 6 |
7 files changed, 144 insertions, 72 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index cc4f31cf414..6bedef8bf18 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -91,6 +91,7 @@ kostja@oak.local lenz@kallisto.mysql.com lenz@mysql.com magnus@neptunus.(none) +magnus@shellback.(none) marko@hundin.mysql.fi miguel@hegel.(none) miguel@hegel.br diff --git a/mysql-test/t/ndb_autodiscover.test b/mysql-test/t/ndb_autodiscover.test index 47a1155065b..50c94d7a6e4 100644 --- a/mysql-test/t/ndb_autodiscover.test +++ b/mysql-test/t/ndb_autodiscover.test @@ -215,9 +215,43 @@ drop table t6, t7; #show status like 'handler_discover%'; #drop table t4; # +# +# system exec $NDB_TOOLS_DIR/ndb_drop_table -d test t4 > /dev/null ; +# +# +# #show tables; +####################################################### +# Test that a table that has been dropped from NDB +# but still exists on disk is deleted from disk +# when SHOW TABLES is called +# +# +#flush status; +# +#create table t4( +# id int not null primary key, +# id2 int, +# name char(27) +#) engine=ndb; +#insert into t4 values (1, 76, "Automatic2"); +#select * from t4; +#flush tables; +# +# Remove the table from NDB +#system exec ../ndb/tools/ndb_drop_table -c localhost:9350 -d test t4 > /dev/null ; + +#system exec ../ndb/tools/ndb_show_tables > var/log/ndb_show_tables.log; + +#SHOW TABLES; + +# Is there another way to find out that the file is gone? +#--error 1146 +#select * from t4; + + ######################################################### # Test that a table that has been changed in NDB diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 5729b8a199c..7250ad81755 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3730,8 +3730,8 @@ int ndbcluster_table_exists(THD* thd, const char *db, const char *name) -extern "C" byte* ndb_tables_get_key(const char *entry, uint *length, - my_bool not_used __attribute__((unused))) +extern "C" byte* tables_get_key(const char *entry, uint *length, + my_bool not_used __attribute__((unused))) { *length= strlen(entry); return (byte*) entry; @@ -3739,43 +3739,49 @@ extern "C" byte* ndb_tables_get_key(const char *entry, uint *length, int ndbcluster_find_files(THD *thd,const char *db,const char *path, - const char *wild, bool dir) + const char *wild, bool dir, List<char> *files) { uint i; - NdbDictionary::Dictionary::List list; Ndb* ndb; char name[FN_REFLEN]; - HASH ndb_tables; - DBUG_ENTER("ndbcluster_list_tables"); + HASH ndb_tables, ok_tables; + NdbDictionary::Dictionary::List list; + DBUG_ENTER("ndbcluster_find_files"); DBUG_PRINT("enter", ("db: %s", db)); if (!(ndb= check_ndb_in_thd(thd))) DBUG_RETURN(HA_ERR_NO_CONNECTION); if (dir) - DBUG_RETURN(0); // Discover of databases not yet discovered + DBUG_RETURN(0); // Discover of databases not yet supported - if (hash_init(&ndb_tables, system_charset_info,32,0,0, - (hash_get_key)ndb_tables_get_key,0,0)) - { - DBUG_PRINT("info", ("Failed to init HASH ndb_tables")); - DBUG_RETURN(-1); - } - - /* List tables in NDB Cluster kernel */ + // List tables in NDB NDBDICT *dict= ndb->getDictionary(); if (dict->listObjects(list, NdbDictionary::Object::UserTable) != 0) ERR_RETURN(dict->getNdbError()); + if (hash_init(&ndb_tables, system_charset_info,list.count,0,0, + (hash_get_key)tables_get_key,0,0)) + { + DBUG_PRINT("error", ("Failed to init HASH ndb_tables")); + DBUG_RETURN(-1); + } + + if (hash_init(&ok_tables, system_charset_info,32,0,0, + (hash_get_key)tables_get_key,0,0)) + { + DBUG_PRINT("error", ("Failed to init HASH ok_tables")); + hash_free(&ndb_tables); + DBUG_RETURN(-1); + } + for (i= 0 ; i < list.count ; i++) { NdbDictionary::Dictionary::List::Element& t= list.elements[i]; - DBUG_PRINT("discover", ("%d, %s/%s", t.id, t.database, t.name)); - if (my_hash_insert(&ndb_tables, (byte*)thd->strdup(t.name))) - continue; + DBUG_PRINT("info", ("Found %s/%s in NDB", t.database, t.name)); - // Only discover files that fullfill wildcard + // Apply wildcard to list of tables in NDB if (wild) { if (lower_case_table_names) @@ -3786,66 +3792,97 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path, else if (wild_compare(t.name,wild,0)) continue; } + DBUG_PRINT("info", ("Inserting %s into ndb_tables hash", t.name)); + my_hash_insert(&ndb_tables, (byte*)thd->strdup(t.name)); + } - // Discover the file if it does not already exists on disk + char *file_name; + List_iterator<char> it(*files); + List<char> delete_list; + while ((file_name=it++)) + { + DBUG_PRINT("info", ("%s", file_name)); + if (hash_search(&ndb_tables, file_name, strlen(file_name))) + { + DBUG_PRINT("info", ("%s existed in NDB _and_ on disk ", file_name)); + // File existed in NDB and as frm file, put in ok_tables list + my_hash_insert(&ok_tables, (byte*)file_name); + continue; + } + + // File is not in NDB, check for .ndb file with this name (void)strxnmov(name, FN_REFLEN, - mysql_data_home,"/",t.database,"/",t.name,reg_ext,NullS); - DBUG_PRINT("discover", ("Check access for %s", name)); + mysql_data_home,"/",db,"/",file_name,ha_ndb_ext,NullS); + DBUG_PRINT("info", ("Check access for %s", name)); if (access(name, F_OK)) - { - DBUG_PRINT("discover", ("Table %s need disocver", name)); - pthread_mutex_lock(&LOCK_open); - ha_create_table_from_engine(thd, t.database, t.name, true); - pthread_mutex_unlock(&LOCK_open); + { + DBUG_PRINT("info", ("%s did not exist on disk", name)); + // .ndb file did not exist on disk, another table type + continue; } - } - /* - Find all .ndb files in current dir and check - if they still exists in NDB - */ - char *ext; - MY_DIR *dirp; - FILEINFO *file; - - if (!(dirp= my_dir(path,MYF(MY_WME | (dir ? MY_WANT_STAT : 0))))) - DBUG_RETURN(-1); + DBUG_PRINT("info", ("%s existed on disk", name)); + // The .ndb file exists on disk, but it's not in list of tables in ndb + // Verify that handler agrees table is gone. + if (ndbcluster_table_exists(thd, db, file_name) == 0) + { + DBUG_PRINT("info", ("NDB says %s does not exists", file_name)); + it.remove(); + // Put in list of tables to remove from disk + delete_list.push_back(thd->strdup(file_name)); + } + } - for (i= 0; i < (uint)dirp->number_off_files; i++) + // Check for new files to discover + DBUG_PRINT("info", ("Checking for new files to discover")); + List<char> create_list; + for (i= 0 ; i < ndb_tables.records ; i++) { - file= dirp->dir_entry+i; + file_name= hash_element(&ndb_tables, i); + if (!hash_search(&ok_tables, file_name, strlen(file_name))) { - ext= fn_ext(file->name); - if(!my_strcasecmp(system_charset_info, ext, ha_ndb_ext)) - { - DBUG_PRINT("discover", ("Found file: %s", file->name)); - *ext= 0; - - if (hash_search(&ndb_tables, file->name, strlen(file->name))) - continue; + DBUG_PRINT("info", ("%s must be discovered", file_name)); + // File is in list of ndb tables and not in ok_tables + // This table need to be created + create_list.push_back(thd->strdup(file_name)); + } + } - DBUG_PRINT("discover", ("File didn't exist in ndb_tables list")); + // Lock mutex before deleting and creating frm files + pthread_mutex_lock(&LOCK_open); - // Verify that handler agrees table is gone. - if (ndbcluster_table_exists(thd, db, file->name) == 0) - { - DBUG_PRINT("discover", ("Remove table %s/%s",db, file->name )); - // Delete the table and all related files - TABLE_LIST table_list; - bzero((char*) &table_list,sizeof(table_list)); - table_list.db= (char*) db; - table_list.real_name=(char*)file->name; - (void)mysql_rm_table_part2_with_lock(thd, &table_list, - /* if_exists */ true, - /* drop_temporary */ false, - /* dont_log_query*/ true); - } - } + if (!global_read_lock) + { + // Delete old files + List_iterator_fast<char> it3(delete_list); + while ((file_name=it3++)) + { + DBUG_PRINT("info", ("Remove table %s/%s",db, file_name )); + // Delete the table and all related files + TABLE_LIST table_list; + bzero((char*) &table_list,sizeof(table_list)); + table_list.db= (char*) db; + table_list.real_name=(char*)file_name; + (void)mysql_rm_table_part2(thd, &table_list, + /* if_exists */ true, + /* drop_temporary */ false, + /* dont_log_query*/ true); } } + // Create new files + List_iterator_fast<char> it2(create_list); + while ((file_name=it2++)) + { + DBUG_PRINT("info", ("Table %s need discovery", name)); + ha_create_table_from_engine(thd, db, file_name, true); + files->push_back(thd->strdup(file_name)); + } + + pthread_mutex_unlock(&LOCK_open); + + hash_free(&ok_tables); hash_free(&ndb_tables); - my_dirend(dirp); DBUG_RETURN(0); } diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 217ba84b00a..31492e2a4dd 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -281,7 +281,7 @@ void ndbcluster_close_connection(THD *thd); int ndbcluster_discover(THD* thd, const char* dbname, const char* name, const void** frmblob, uint* frmlen); int ndbcluster_find_files(THD *thd,const char *db,const char *path, - const char *wild, bool dir); + const char *wild, bool dir, List<char> *files); int ndbcluster_table_exists(THD* thd, const char *db, const char *name); int ndbcluster_drop_database(const char* path); diff --git a/sql/handler.cc b/sql/handler.cc index dc2f213640a..c7e7b08ba6e 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1471,7 +1471,7 @@ int ha_discover(THD* thd, const char* db, const char* name, int ha_find_files(THD *thd,const char *db,const char *path, - const char *wild, bool dir) + const char *wild, bool dir, List<char> *files) { int error= 0; DBUG_ENTER("ha_find_files"); @@ -1479,7 +1479,7 @@ ha_find_files(THD *thd,const char *db,const char *path, db, path, wild, dir)); #ifdef HAVE_NDBCLUSTER_DB if (have_ndbcluster == SHOW_OPTION_YES) - error= ndbcluster_find_files(thd, db, path, wild, dir); + error= ndbcluster_find_files(thd, db, path, wild, dir, files); #endif DBUG_RETURN(error); diff --git a/sql/handler.h b/sql/handler.h index fea03c5080e..9806d2e7499 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -566,7 +566,7 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache, int ha_discover(THD* thd, const char* dbname, const char* name, const void** frmblob, uint* frmlen); int ha_find_files(THD *thd,const char *db,const char *path, - const char *wild, bool dir); + const char *wild, bool dir,List<char>* files); int ha_table_exists(THD* thd, const char* db, const char* name); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 850e18db748..e94e36eae30 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -375,9 +375,6 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, if (wild && !wild[0]) wild=0; - if (ha_find_files(thd,db,path,wild,dir)) - DBUG_RETURN(-1); - bzero((char*) &table_list,sizeof(table_list)); if (!(dirp = my_dir(path,MYF(MY_WME | (dir ? MY_WANT_STAT : 0))))) @@ -449,6 +446,9 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, } DBUG_PRINT("info",("found: %d files", files->elements)); my_dirend(dirp); + + VOID(ha_find_files(thd,db,path,wild,dir,files)); + DBUG_RETURN(0); } |