@@ -1589,25 +1589,26 @@ bool close_thread_table(THD *thd, TABLE **table_ptr)
15891589 *table_ptr=table->next ;
15901590 mysql_mutex_unlock (&thd->LOCK_thd_data );
15911591
1592+ if (! table->needs_reopen ())
1593+ {
1594+ /* Avoid having MERGE tables with attached children in unused_tables. */
1595+ table->file ->extra (HA_EXTRA_DETACH_CHILDREN);
1596+ /* Free memory and reset for next loop. */
1597+ free_field_buffers_larger_than (table, MAX_TDC_BLOB_SIZE);
1598+ table->file ->ha_reset ();
1599+ }
1600+
15921601 mysql_mutex_lock (&LOCK_open);
15931602
1594- if (table->s ->needs_reopen () ||
1595- thd->version != refresh_version || table->needs_reopen () ||
1603+ if (table->s ->needs_reopen () || table->needs_reopen () ||
15961604 table_def_shutdown_in_progress)
15971605 {
15981606 free_cache_entry (table);
15991607 found_old_table= 1 ;
16001608 }
16011609 else
16021610 {
1603- /* Avoid to have MERGE tables with attached children in unused_tables. */
16041611 DBUG_ASSERT (table->file );
1605- table->file ->extra (HA_EXTRA_DETACH_CHILDREN);
1606-
1607- /* Free memory and reset for next loop */
1608- free_field_buffers_larger_than (table,MAX_TDC_BLOB_SIZE);
1609-
1610- table->file ->ha_reset ();
16111612 table_def_unuse_table (table);
16121613 /*
16131614 We free the least used table, not the subject table,
@@ -2305,36 +2306,38 @@ void wait_for_condition(THD *thd, mysql_mutex_t *mutex, mysql_cond_t *cond)
23052306 @param[out] exists Out parameter which is set to TRUE if table
23062307 exists and to FALSE otherwise.
23072308
2308- @note This function assumes that caller owns LOCK_open mutex .
2309+ @note This function acquires LOCK_open internally .
23092310 It also assumes that the fact that there are no exclusive
23102311 metadata locks on the table was checked beforehand.
23112312
23122313 @note If there is no .FRM file for the table but it exists in one
23132314 of engines (e.g. it was created on another node of NDB cluster)
23142315 this function will fetch and create proper .FRM file for it.
23152316
2316- @retval TRUE Some error occured
2317+ @retval TRUE Some error occurred
23172318 @retval FALSE No error. 'exists' out parameter set accordingly.
23182319*/
23192320
23202321bool check_if_table_exists (THD *thd, TABLE_LIST *table, bool *exists)
23212322{
23222323 char path[FN_REFLEN + 1 ];
2323- int rc;
2324+ int rc= 0 ;
23242325 DBUG_ENTER (" check_if_table_exists" );
23252326
2326- mysql_mutex_assert_owner (&LOCK_open);
2327+ mysql_mutex_assert_not_owner (&LOCK_open);
23272328
23282329 *exists= TRUE ;
23292330
2331+ mysql_mutex_lock (&LOCK_open);
2332+
23302333 if (get_cached_table_share (table->db , table->table_name ))
2331- DBUG_RETURN ( FALSE ) ;
2334+ goto end ;
23322335
23332336 build_table_filename (path, sizeof (path) - 1 , table->db , table->table_name ,
23342337 reg_ext, 0 );
23352338
23362339 if (!access (path, F_OK))
2337- DBUG_RETURN ( FALSE ) ;
2340+ goto end ;
23382341
23392342 /* .FRM file doesn't exist. Check if some engine can provide it. */
23402343
@@ -2344,19 +2347,17 @@ bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists)
23442347 {
23452348 /* Table does not exists in engines as well. */
23462349 *exists= FALSE ;
2347- DBUG_RETURN (FALSE );
2348- }
2349- else if (!rc)
2350- {
2351- /* Table exists in some engine and .FRM for it was created. */
2352- DBUG_RETURN (FALSE );
2350+ rc= 0 ;
23532351 }
2354- else /* (rc > 0) */
2352+ else if (rc)
23552353 {
23562354 my_printf_error (ER_UNKNOWN_ERROR, " Failed to open '%-.64s', error while "
23572355 " unpacking from engine" , MYF (0 ), table->table_name );
2358- DBUG_RETURN (TRUE );
23592356 }
2357+
2358+ end:
2359+ mysql_mutex_unlock (&LOCK_open);
2360+ DBUG_RETURN (test (rc));
23602361}
23612362
23622363
@@ -2651,7 +2652,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
26512652 if (thd->global_read_lock .wait_if_global_read_lock (thd, 1 , 1 ))
26522653 DBUG_RETURN (TRUE );
26532654
2654- if (thd->version != refresh_version)
2655+ if (thd->open_tables && thd-> open_tables -> s -> version != refresh_version)
26552656 {
26562657 (void ) ot_ctx->request_backoff_action (Open_table_context::OT_WAIT_TDC,
26572658 NULL );
@@ -2848,48 +2849,24 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
28482849 }
28492850
28502851 hash_value= my_calc_hash (&table_def_cache, (uchar*) key, key_length);
2851- mysql_mutex_lock (&LOCK_open);
28522852
2853- /*
2854- If it's the first table from a list of tables used in a query,
2855- remember refresh_version (the version of open_cache state).
2856- If the version changes while we're opening the remaining tables,
2857- we will have to back off, close all the tables opened-so-far,
2858- and try to reopen them.
2859- Note: refresh_version is currently changed only during FLUSH TABLES.
2860- */
2861- if (!thd->open_tables )
2862- thd->version =refresh_version;
2863- else if ((thd->version != refresh_version) &&
2864- ! (flags & MYSQL_OPEN_IGNORE_FLUSH))
2865- {
2866- /* Someone did a refresh while thread was opening tables */
2867- mysql_mutex_unlock (&LOCK_open);
2868- (void ) ot_ctx->request_backoff_action (Open_table_context::OT_WAIT_TDC,
2869- NULL );
2870- DBUG_RETURN (TRUE );
2871- }
28722853
28732854 if (table_list->open_strategy == TABLE_LIST::OPEN_IF_EXISTS)
28742855 {
28752856 bool exists;
28762857
28772858 if (check_if_table_exists (thd, table_list, &exists))
2878- goto err_unlock2 ;
2859+ DBUG_RETURN ( TRUE ) ;
28792860
28802861 if (!exists)
2881- {
2882- mysql_mutex_unlock (&LOCK_open);
28832862 DBUG_RETURN (FALSE );
2884- }
2863+
28852864 /* Table exists. Let us try to open it. */
28862865 }
28872866 else if (table_list->open_strategy == TABLE_LIST::OPEN_STUB)
2888- {
2889- mysql_mutex_unlock (&LOCK_open);
28902867 DBUG_RETURN (FALSE );
2891- }
28922868
2869+ mysql_mutex_lock (&LOCK_open);
28932870#ifdef DISABLED_UNTIL_GRL_IS_MADE_PART_OF_MDL
28942871 if (!(share= (TABLE_SHARE *) mdl_ticket->get_cached_object ()))
28952872#endif
@@ -2911,7 +2888,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
29112888 my_error (ER_WRONG_MRG_TABLE, MYF (0 ));
29122889 goto err_unlock;
29132890 }
2914-
2891+
29152892 /*
29162893 This table is a view. Validate its metadata version: in particular,
29172894 that it was a view when the statement was prepared.
@@ -2980,7 +2957,15 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
29802957 }
29812958#endif
29822959
2983- if (share->needs_reopen ())
2960+
2961+ /*
2962+ If the version changes while we're opening the tables,
2963+ we have to back off, close all the tables opened-so-far,
2964+ and try to reopen them. Note: refresh_version is currently
2965+ changed only during FLUSH TABLES.
2966+ */
2967+ if (share->needs_reopen () ||
2968+ (thd->open_tables && thd->open_tables ->s ->version != share->version ))
29842969 {
29852970 if (!(flags & MYSQL_OPEN_IGNORE_FLUSH))
29862971 {
@@ -3000,8 +2985,6 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
30002985 NULL );
30012986 DBUG_RETURN (TRUE );
30022987 }
3003- /* Force close at once after usage */
3004- thd->version = share->version ;
30052988 }
30062989
30072990 if (!share->free_tables .is_empty ())
@@ -3017,9 +3000,11 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
30173000 while (table_cache_count > table_cache_size && unused_tables)
30183001 free_cache_entry (unused_tables);
30193002
3003+ mysql_mutex_unlock (&LOCK_open);
3004+
30203005 /* make a new table */
30213006 if (!(table=(TABLE*) my_malloc (sizeof (*table),MYF (MY_WME))))
3022- goto err_unlock ;
3007+ goto err_lock ;
30233008
30243009 error= open_table_from_share (thd, share, alias,
30253010 (uint) (HA_OPEN_KEYFILE |
@@ -3041,16 +3026,17 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
30413026 (void ) ot_ctx->request_backoff_action (Open_table_context::OT_REPAIR,
30423027 table_list);
30433028
3044- goto err_unlock ;
3029+ goto err_lock ;
30453030 }
30463031
30473032 if (open_table_entry_fini (thd, share, table))
30483033 {
30493034 closefrm (table, 0 );
30503035 my_free ((uchar*)table, MYF (0 ));
3051- goto err_unlock ;
3036+ goto err_lock ;
30523037 }
30533038
3039+ mysql_mutex_lock (&LOCK_open);
30543040 /* Add table to the share's used tables list. */
30553041 table_def_add_used_table (thd, table);
30563042 }
@@ -3112,6 +3098,8 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
31123098 table->file ->extra (HA_EXTRA_DETACH_CHILDREN);
31133099 DBUG_RETURN (FALSE );
31143100
3101+ err_lock:
3102+ mysql_mutex_lock (&LOCK_open);
31153103err_unlock:
31163104 release_table_share (share);
31173105err_unlock2:
0 commit comments