diff options
author | unknown <magnus@neptunus.(none)> | 2004-09-13 14:46:38 +0200 |
---|---|---|
committer | unknown <magnus@neptunus.(none)> | 2004-09-13 14:46:38 +0200 |
commit | 692b1e6958b72c82f14f7c950b54101a3e7bf96d (patch) | |
tree | 8eed62b1151616d8bdb119967ec4713ddc6852b9 /sql/sql_show.cc | |
parent | 73579639138e6204cb2df891c58e8e6f4eaa8dd7 (diff) | |
download | mariadb-git-692b1e6958b72c82f14f7c950b54101a3e7bf96d.tar.gz |
WL1424 Multiple MySQL Servers: SHOW TABLES etc. should detect new and delete old tables.
include/my_base.h:
Added new bit to table create options
Removed old error code HA_ERR_OLD_METADAT and reused it for HA_ERR_NO_SUCH_TABLE.
mysql-test/r/ndb_autodiscover.result:
Updated test cases
mysql-test/t/ndb_autodiscover.test:
Updated test cases
mysql-test/t/ndb_autodiscover2.test:
Updated test cases
sql/discover.cc:
Moved function create_table_from_handler to handler.cc
sql/ha_ndbcluster.cc:
Improved discover functionality
Added .ndb file
Changed error code mappings for a table that does not exist in engine
Check for ndb object in THD
Updated ndbcluster_discover, ndbcluster_list_tables and ndbcluster_can_discover
sql/ha_ndbcluster.h:
Improved discover
sql/handler.cc:
Added new error message mapping.
Moved function ha_create_table_from_engine to handler level
Added new functions ha_can_discover, ha_list_tables and ha_table_exists
sql/handler.h:
Added new error message mapping.
Moved function ha_create_table_from_engine to handler level
Added new functions ha_can_discover, ha_list_tables and ha_table_exists
sql/mysql_priv.h:
Removed create_table_from_handler, moved to handler.h
sql/sql_base.cc:
Renamed function create_table_from_handler
sql/sql_show.cc:
Added new function mysql_discover_files and mysql_list_files.
Modified mysql_find_files to discover new and delete "old" files/tables.
sql/sql_table.cc:
Renamed create_table_from_handler
Call ha_create_table_from_engine, in order to discover the the frm file before it can be dropped.
sql/table.cc:
Added mapping of the error code HA_ERR_NO_SUCH_TABLE
Diffstat (limited to 'sql/sql_show.cc')
-rw-r--r-- | sql/sql_show.cc | 189 |
1 files changed, 173 insertions, 16 deletions
diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 57c5f01d0bf..42c48ab8d21 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -358,30 +358,59 @@ int mysqld_show_column_types(THD *thd) } + +/* + Ask all engines if they can provide a list of available tables. + Returns a list of available tables. +*/ + +int +mysql_discover_tables(THD *thd, HASH *ha_tables, const char *db, bool dir) +{ + DBUG_ENTER("mysql_discover_files"); + + if (dir) + DBUG_RETURN(0); // Discover of directories(databases) not supported yet + + // Get list of files in storage engine + if (ha_list_tables(thd, ha_tables, db)) + DBUG_RETURN(-1); + + DBUG_PRINT("info",("discovered: %d files", ha_tables->records)); + DBUG_RETURN(0); +} + + +/* + List all files or directories in a given location + Returns + files - list of files where wild card has been applied + all_files - list of all files + dsc_files - list of files which are discoverable +*/ + int -mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, - const char *wild, bool dir) +mysql_list_files(THD *thd, const char *db, const char *path, const char *wild, + bool dir, List<char> *files, HASH *all_files, HASH* dsc_files) { uint i; - char *ext; + char *ext, **dsc_ext; MY_DIR *dirp; FILEINFO *file; #ifndef NO_EMBEDDED_ACCESS_CHECKS uint col_access=thd->col_access; #endif TABLE_LIST table_list; - DBUG_ENTER("mysql_find_files"); + DBUG_ENTER("mysql_list_files"); - if (wild && !wild[0]) - wild=0; bzero((char*) &table_list,sizeof(table_list)); - + if (!(dirp = my_dir(path,MYF(MY_WME | (dir ? MY_WANT_STAT : 0))))) DBUG_RETURN(-1); - for (i=0 ; i < (uint) dirp->number_off_files ; i++) + for (i= 0; i < (uint)dirp->number_off_files; i++) { - file=dirp->dir_entry+i; + file= dirp->dir_entry+i; if (dir) { /* Return databases */ #ifdef USE_SYMDIR @@ -391,7 +420,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, /* Only show the sym file if it points to a directory */ char buff[FN_REFLEN], *end; MY_STAT status; - *ext=0; /* Remove extension */ + *ext= 0; /* Remove extension */ unpack_dirname(buff, file->name); end= strend(buff); if (end != buff && end[-1] == FN_LIBCHAR) @@ -410,11 +439,36 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, } else { - // Return only .frm files which aren't temp files. - if (my_strcasecmp(system_charset_info, ext=fn_ext(file->name),reg_ext) || - is_prefix(file->name,tmp_file_prefix)) - continue; - *ext=0; + // Don't process temp files + if (is_prefix(file->name, tmp_file_prefix)) + continue; + + ext= fn_ext(file->name); + // Check for files that indicates the table can be discovered + if (ha_can_discover(thd, file->name)) + { + DBUG_PRINT("info", ("Discoverable file found: %s", file->name)); + *ext= 0; + if (my_hash_insert(dsc_files, (byte*)thd->strdup(file->name))) + { + my_dirend(dirp); + DBUG_RETURN(-1); + } + continue; + } + + // Return only .frm files + if (my_strcasecmp(system_charset_info, ext,reg_ext)) + continue; + *ext=0; + + // Insert into list of all .frm files + if (my_hash_insert(all_files, (byte*)thd->strdup(file->name))) + { + my_dirend(dirp); + DBUG_RETURN(-1); + } + if (wild) { if (lower_case_table_names) @@ -443,11 +497,114 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, DBUG_RETURN(-1); } } - DBUG_PRINT("info",("found: %d files", files->elements)); my_dirend(dirp); DBUG_RETURN(0); } +extern "C" byte* ha_tables_get_key(const char *entry, uint *length, + my_bool not_used __attribute__((unused))) +{ + *length= strlen(entry); + return (byte*) entry; +} + + +int +mysql_find_files(THD *thd,List<char> *files, const char *db, + const char *path, const char *wild, bool dir) +{ + int error= -1; + uint i; + bool discovery_performed= false; + DBUG_ENTER("mysql_find_files"); + DBUG_PRINT("enter", ("db: %s, path: %s, wild: %s, dir: %d", + db, path, wild, dir)); + + if (wild && !wild[0]) + wild=0; + + HASH ha_tables, all_files, dsc_files; + if (hash_init(&ha_tables,system_charset_info,32,0,0, + (hash_get_key) ha_tables_get_key,0,0) || + hash_init(&all_files,system_charset_info,32,0,0, + (hash_get_key) ha_tables_get_key,0,0) || + hash_init(&dsc_files,system_charset_info,32,0,0, + (hash_get_key) ha_tables_get_key,0,0)) + goto err_end; + + if (mysql_discover_tables(thd, &ha_tables, db, dir)) + goto err_end; + + if (mysql_list_files(thd, db, path, wild, dir, + files, &all_files, &dsc_files)) + goto err_end; + + /* + Discovery part 1 + Loop through handler files and see if any of them should be discovered + */ + for (i= 0; i < ha_tables.records; i++) + { + const char *name = hash_element(&ha_tables, i); + if (hash_search(&all_files, name, strlen(name))) + continue; + + // Table was in handler, but not in list of all tables + DBUG_PRINT("info", ("Table to discover[%d]: %s", i, name)); + pthread_mutex_lock(&LOCK_open); + ha_create_table_from_engine(thd, db, name, true); + pthread_mutex_unlock(&LOCK_open); + discovery_performed= true; + } + + /* + Discovery part2 + Loop through dsc files and see if any of them need to be deleted + */ + for (i= 0; i < dsc_files.records; i++) + { + const char *name = hash_element(&dsc_files, i); + if (hash_search(&ha_tables, name, strlen(name))) + continue; + + // Table was only on disk and not in handler + DBUG_PRINT("info", ("Table[%d]: %s only exists on disk", i, name)); + + // Verify that handler agrees table is gone. + if (ha_table_exists(thd, db, name) == 0) + { + // 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*)name; + (void)mysql_rm_table_part2_with_lock(thd, &table_list, + /* if_exists */ true, + /* drop_temporary */ false, + /* dont_log_query*/ true); + discovery_performed= true; + } + } + + if (discovery_performed) + { + // Call mysql_list_files one more time to get an updated list + DBUG_PRINT("info", ("Calling mysql_list_files one more time")); + files->empty(); + if (mysql_list_files(thd, db, path, wild, dir, + files, &all_files, &dsc_files)) + goto err_end; + } + + DBUG_PRINT("info",("found: %d files", files->elements)); + error = 0; +err_end: + hash_free(&ha_tables); + hash_free(&all_files); + hash_free(&dsc_files); + DBUG_RETURN(error); +} + /*************************************************************************** Extended version of mysqld_show_tables |