mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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
This commit is contained in:
189
sql/sql_show.cc
189
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
|
||||
|
Reference in New Issue
Block a user