Commit c0a68902 authored by monty@narttu.mysql.fi's avatar monty@narttu.mysql.fi
Browse files

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.
parent 6899a4e3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,3 +25,4 @@ zak@balfor.local
monty@narttu.
monty@mashka.mysql.fi
bar@bar.udmsearch.izhnet.ru
monty@narttu.mysql.fi
+14 −2
Original line number Diff line number Diff line
@@ -279,6 +279,16 @@ void intern_close_table(TABLE *table)
    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)
{
@@ -833,7 +843,10 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,

    /* make a new table */
    if (!(table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME))))
    {
      VOID(pthread_mutex_unlock(&LOCK_open));
      DBUG_RETURN(NULL);
    }
    if (open_unireg_entry(thd, table,db,table_name,alias,1) ||
	!(table->table_cache_key=memdup_root(&table->mem_root,(char*) key,
					     key_length)))
@@ -1181,7 +1194,6 @@ bool wait_for_tables(THD *thd)
    /* Now we can open all tables without any interference */
    thd->proc_info="Reopen tables";
    result=reopen_tables(thd,0,0);
     
  }
  pthread_mutex_unlock(&LOCK_open);
  thd->proc_info=0;
@@ -1372,9 +1384,9 @@ int open_tables(THD *thd,TABLE_LIST *start)
	  }
	}
	*prev_table=0;
	pthread_mutex_unlock(&LOCK_open);
	if (found)
	  VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
	pthread_mutex_unlock(&LOCK_open);
	goto restart;
      }
      result= -1;				// Fatal error
+5 −0
Original line number Diff line number Diff line
@@ -1419,6 +1419,11 @@ bool select_create::send_eof()
    table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
    VOID(pthread_mutex_lock(&LOCK_open));
    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)
      hash_delete(&open_cache,(byte*) table);
    lock=0; table=0;
+6 −1
Original line number Diff line number Diff line
@@ -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))
    DBUG_RETURN(-1);

  pthread_mutex_lock(&LOCK_open);
  List_iterator<char> it(tables);
  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,query_table_status(thd,db,table_name));
    if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
    {
      pthread_mutex_unlock(&LOCK_open);
      DBUG_RETURN(-1);
    }

  }
  pthread_mutex_unlock(&LOCK_open);
  send_eof(&thd->net);
  DBUG_RETURN(0);
}


/***************************************************************************
** List all tables in a database (fast version)
** A table is a .frm file in the current databasedir
+17 −4
Original line number Diff line number Diff line
@@ -147,8 +147,8 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
  
  error = 0;
 err:  
  VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
  pthread_mutex_unlock(&LOCK_open);
  VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh

  pthread_mutex_lock(&thd->mysys_var->mutex);
  thd->mysys_var->current_mutex= 0;
@@ -711,7 +711,9 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
  table->reginfo.lock_type=TL_WRITE;
  if (!((*lock)=mysql_lock_tables(thd,&table,1)))
  {
    VOID(pthread_mutex_lock(&LOCK_open));
    hash_delete(&open_cache,(byte*) table);
    VOID(pthread_mutex_unlock(&LOCK_open));
    quick_rm_table(create_info->db_type,db,name);
    DBUG_RETURN(0);
  }
@@ -859,7 +861,9 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
			 reg_ext, 4),
	       MYF(MY_WME)))
    {
      pthread_mutex_lock(&LOCK_open);
      unlock_table_name(thd, table);
      pthread_mutex_unlock(&LOCK_open);
      DBUG_RETURN(send_check_errmsg(thd, table, "restore",
				    "Failed copying .frm file"));
    }
@@ -870,7 +874,9 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)

    if (generate_table(thd, table, 0))
    {
      pthread_mutex_lock(&LOCK_open);
      unlock_table_name(thd, table);
      pthread_mutex_unlock(&LOCK_open);
      thd->net.no_send_ok = save_no_send_ok;
      DBUG_RETURN(send_check_errmsg(thd, table, "restore",
				    "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
      // to finish the restore in the handler later on
      if (!(table->table = reopen_name_locked_table(thd, table)))
      {
	pthread_mutex_lock(&LOCK_open);
        unlock_table_name(thd, table);
	pthread_mutex_unlock(&LOCK_open);
      }
    }

    if (!table->table)
    {
      const char *err_msg;
@@ -1031,8 +1040,12 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
    if (fatal_error)
      table->table->version=0;			// Force close of table
    else if (open_for_modify)
    {
      pthread_mutex_lock(&LOCK_open);
      remove_table_from_cache(thd, table->table->table_cache_key,
			      table->table->real_name);
      pthread_mutex_unlock(&LOCK_open);
    }
    close_thread_tables(thd);
    if (my_net_write(&thd->net, (char*) packet->ptr(),
		     packet->length()))
@@ -1648,8 +1661,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
    error=1;
  if (error)
  {
    VOID(pthread_cond_broadcast(&COND_refresh));
    VOID(pthread_mutex_unlock(&LOCK_open));
    VOID(pthread_cond_broadcast(&COND_refresh));
    goto err;
  }
#ifdef HAVE_BERKELEY_DB