mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +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.
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