mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Added some missing mutex_locks() when manipulating the table cache.
This should fix some possible table cache corruptions when doing OPTIMIZE or REPAIR table when other threads are opening new tables. sql/sql_base.cc: Added missing mutex unlock on error condition sql/sql_insert.cc: Added TODO item sql/sql_show.cc: Added missing pthread_mutex_lock(&LOCK_open) when calling query_table_status(). sql/sql_table.cc: Added missing pthread_mutex_lock(&LOCK_open) when calling hash_delete(), unlock_table_name() and remove_table_from_cache(). BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
This commit is contained in:
@ -25,3 +25,4 @@ zak@balfor.local
|
|||||||
monty@narttu.
|
monty@narttu.
|
||||||
monty@mashka.mysql.fi
|
monty@mashka.mysql.fi
|
||||||
bar@bar.udmsearch.izhnet.ru
|
bar@bar.udmsearch.izhnet.ru
|
||||||
|
monty@narttu.mysql.fi
|
||||||
|
@ -279,6 +279,16 @@ void intern_close_table(TABLE *table)
|
|||||||
VOID(closefrm(table)); // close file
|
VOID(closefrm(table)); // close file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove table from the open table cache
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
free_cache_entry()
|
||||||
|
table Table to remove
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
We need to have a lock on LOCK_open when calling this
|
||||||
|
*/
|
||||||
|
|
||||||
static void free_cache_entry(TABLE *table)
|
static void free_cache_entry(TABLE *table)
|
||||||
{
|
{
|
||||||
@ -833,7 +843,10 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
|
|||||||
|
|
||||||
/* make a new table */
|
/* make a new table */
|
||||||
if (!(table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME))))
|
if (!(table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME))))
|
||||||
|
{
|
||||||
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
|
}
|
||||||
if (open_unireg_entry(thd, table,db,table_name,alias,1) ||
|
if (open_unireg_entry(thd, table,db,table_name,alias,1) ||
|
||||||
!(table->table_cache_key=memdup_root(&table->mem_root,(char*) key,
|
!(table->table_cache_key=memdup_root(&table->mem_root,(char*) key,
|
||||||
key_length)))
|
key_length)))
|
||||||
@ -1181,7 +1194,6 @@ bool wait_for_tables(THD *thd)
|
|||||||
/* Now we can open all tables without any interference */
|
/* Now we can open all tables without any interference */
|
||||||
thd->proc_info="Reopen tables";
|
thd->proc_info="Reopen tables";
|
||||||
result=reopen_tables(thd,0,0);
|
result=reopen_tables(thd,0,0);
|
||||||
|
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
thd->proc_info=0;
|
thd->proc_info=0;
|
||||||
@ -1372,9 +1384,9 @@ int open_tables(THD *thd,TABLE_LIST *start)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*prev_table=0;
|
*prev_table=0;
|
||||||
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
if (found)
|
if (found)
|
||||||
VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
|
VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
result= -1; // Fatal error
|
result= -1; // Fatal error
|
||||||
|
@ -1419,6 +1419,11 @@ bool select_create::send_eof()
|
|||||||
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
|
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
|
||||||
VOID(pthread_mutex_lock(&LOCK_open));
|
VOID(pthread_mutex_lock(&LOCK_open));
|
||||||
mysql_unlock_tables(thd, lock);
|
mysql_unlock_tables(thd, lock);
|
||||||
|
/*
|
||||||
|
TODO:
|
||||||
|
Check if we can remove the following two rows.
|
||||||
|
We should be able to just keep the table in the table cache.
|
||||||
|
*/
|
||||||
if (!table->tmp_table)
|
if (!table->tmp_table)
|
||||||
hash_delete(&open_cache,(byte*) table);
|
hash_delete(&open_cache,(byte*) table);
|
||||||
lock=0; table=0;
|
lock=0; table=0;
|
||||||
|
@ -117,6 +117,7 @@ int mysqld_show_open_tables(THD *thd,const char *db,const char *wild)
|
|||||||
if (list_open_tables(thd,&tables,db,wild))
|
if (list_open_tables(thd,&tables,db,wild))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&LOCK_open);
|
||||||
List_iterator<char> it(tables);
|
List_iterator<char> it(tables);
|
||||||
while ((table_name=it++))
|
while ((table_name=it++))
|
||||||
{
|
{
|
||||||
@ -124,13 +125,17 @@ int mysqld_show_open_tables(THD *thd,const char *db,const char *wild)
|
|||||||
net_store_data(&thd->packet,table_name);
|
net_store_data(&thd->packet,table_name);
|
||||||
net_store_data(&thd->packet,query_table_status(thd,db,table_name));
|
net_store_data(&thd->packet,query_table_status(thd,db,table_name));
|
||||||
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
|
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
send_eof(&thd->net);
|
send_eof(&thd->net);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
** List all tables in a database (fast version)
|
** List all tables in a database (fast version)
|
||||||
** A table is a .frm file in the current databasedir
|
** A table is a .frm file in the current databasedir
|
||||||
|
@ -147,8 +147,8 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
|
|||||||
|
|
||||||
error = 0;
|
error = 0;
|
||||||
err:
|
err:
|
||||||
VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
|
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
|
VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
|
||||||
|
|
||||||
pthread_mutex_lock(&thd->mysys_var->mutex);
|
pthread_mutex_lock(&thd->mysys_var->mutex);
|
||||||
thd->mysys_var->current_mutex= 0;
|
thd->mysys_var->current_mutex= 0;
|
||||||
@ -160,7 +160,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
|
|||||||
my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr());
|
my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr());
|
||||||
error=1;
|
error=1;
|
||||||
}
|
}
|
||||||
if(error)
|
if (error)
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
send_ok(&thd->net);
|
send_ok(&thd->net);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@ -711,7 +711,9 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
table->reginfo.lock_type=TL_WRITE;
|
table->reginfo.lock_type=TL_WRITE;
|
||||||
if (!((*lock)=mysql_lock_tables(thd,&table,1)))
|
if (!((*lock)=mysql_lock_tables(thd,&table,1)))
|
||||||
{
|
{
|
||||||
|
VOID(pthread_mutex_lock(&LOCK_open));
|
||||||
hash_delete(&open_cache,(byte*) table);
|
hash_delete(&open_cache,(byte*) table);
|
||||||
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
quick_rm_table(create_info->db_type,db,name);
|
quick_rm_table(create_info->db_type,db,name);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@ -859,7 +861,9 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
|
|||||||
reg_ext, 4),
|
reg_ext, 4),
|
||||||
MYF(MY_WME)))
|
MYF(MY_WME)))
|
||||||
{
|
{
|
||||||
|
pthread_mutex_lock(&LOCK_open);
|
||||||
unlock_table_name(thd, table);
|
unlock_table_name(thd, table);
|
||||||
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
DBUG_RETURN(send_check_errmsg(thd, table, "restore",
|
DBUG_RETURN(send_check_errmsg(thd, table, "restore",
|
||||||
"Failed copying .frm file"));
|
"Failed copying .frm file"));
|
||||||
}
|
}
|
||||||
@ -870,7 +874,9 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
|
|||||||
|
|
||||||
if (generate_table(thd, table, 0))
|
if (generate_table(thd, table, 0))
|
||||||
{
|
{
|
||||||
|
pthread_mutex_lock(&LOCK_open);
|
||||||
unlock_table_name(thd, table);
|
unlock_table_name(thd, table);
|
||||||
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
thd->net.no_send_ok = save_no_send_ok;
|
thd->net.no_send_ok = save_no_send_ok;
|
||||||
DBUG_RETURN(send_check_errmsg(thd, table, "restore",
|
DBUG_RETURN(send_check_errmsg(thd, table, "restore",
|
||||||
"Failed generating table from .frm file"));
|
"Failed generating table from .frm file"));
|
||||||
@ -930,9 +936,12 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
// now we should be able to open the partially restored table
|
// now we should be able to open the partially restored table
|
||||||
// to finish the restore in the handler later on
|
// to finish the restore in the handler later on
|
||||||
if (!(table->table = reopen_name_locked_table(thd, table)))
|
if (!(table->table = reopen_name_locked_table(thd, table)))
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&LOCK_open);
|
||||||
unlock_table_name(thd, table);
|
unlock_table_name(thd, table);
|
||||||
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!table->table)
|
if (!table->table)
|
||||||
{
|
{
|
||||||
const char *err_msg;
|
const char *err_msg;
|
||||||
@ -1031,8 +1040,12 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
if (fatal_error)
|
if (fatal_error)
|
||||||
table->table->version=0; // Force close of table
|
table->table->version=0; // Force close of table
|
||||||
else if (open_for_modify)
|
else if (open_for_modify)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&LOCK_open);
|
||||||
remove_table_from_cache(thd, table->table->table_cache_key,
|
remove_table_from_cache(thd, table->table->table_cache_key,
|
||||||
table->table->real_name);
|
table->table->real_name);
|
||||||
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
|
}
|
||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
if (my_net_write(&thd->net, (char*) packet->ptr(),
|
if (my_net_write(&thd->net, (char*) packet->ptr(),
|
||||||
packet->length()))
|
packet->length()))
|
||||||
@ -1648,8 +1661,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
error=1;
|
error=1;
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
VOID(pthread_cond_broadcast(&COND_refresh));
|
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
|
VOID(pthread_cond_broadcast(&COND_refresh));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_BERKELEY_DB
|
#ifdef HAVE_BERKELEY_DB
|
||||||
|
Reference in New Issue
Block a user