diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-04-09 15:34:27 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-04-09 15:34:27 +0200 |
commit | d71b75c90d86f6a654a7e93ac383b4000533ffbc (patch) | |
tree | f91b486bf0cee267bc79a6dd62c9110c4a650400 /sql | |
parent | 163882665eed8c065953bdce05aaa152b6b5df0f (diff) | |
download | mariadb-git-d71b75c90d86f6a654a7e93ac383b4000533ffbc.tar.gz |
moving LOCK_open into get_table_share()
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_admin.cc | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 183 | ||||
-rw-r--r-- | sql/sql_show.cc | 7 | ||||
-rw-r--r-- | sql/sql_view.cc | 5 | ||||
-rw-r--r-- | sql/table.h | 4 |
5 files changed, 105 insertions, 96 deletions
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 849a00a7df7..0410d72bafc 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -128,10 +128,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, has_mdl_lock= TRUE; hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); - mysql_mutex_lock(&LOCK_open); share= get_table_share(thd, table_list, key, key_length, FRM_READ_TABLE_ONLY, ¬_used, hash_value); - mysql_mutex_unlock(&LOCK_open); if (share == NULL) DBUG_RETURN(0); // Can't open frm file diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 03728fcd372..f58e121a511 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -167,6 +167,24 @@ Repair_mrg_table_error_handler::handle_condition(THD *, Protects table_def_hash, used and unused lists in the TABLE_SHARE object, LRU lists of used TABLEs and used TABLE_SHAREs, refresh_version and the table id counter. + In particular: + + end_of_unused_share + last_table_id + oldest_unused_share + refresh_version + table_cache_count + table_def_cache + table_def_shutdown_in_progress + unused_tables + TABLE::next + TABLE::prev + TABLE_SHARE::free_tables + TABLE_SHARE::m_flush_tickets + TABLE_SHARE::next + TABLE_SHARE::prev + TABLE_SHARE::ref_count + TABLE_SHARE::used_tables */ mysql_mutex_t LOCK_open; @@ -584,6 +602,8 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, *error= OPEN_FRM_OK; + mysql_mutex_lock(&LOCK_open); + /* To be able perform any operation on table we should own some kind of metadata lock on it. @@ -594,47 +614,46 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, MDL_SHARED)); /* Read table definition from cache */ - if ((share= (TABLE_SHARE*) my_hash_search_using_hash_value(&table_def_cache, - hash_value, (uchar*) key, key_length))) - goto found; - - if (!(share= alloc_table_share(table_list, key, key_length))) + share= (TABLE_SHARE*) my_hash_search_using_hash_value(&table_def_cache, + hash_value, (uchar*) key, key_length); + if (!share) { - DBUG_RETURN(0); - } + if (!(share= alloc_table_share(table_list, key, key_length))) + goto err; - /* - We assign a new table id under the protection of LOCK_open. - We do this instead of creating a new mutex - and using it for the sole purpose of serializing accesses to a - static variable, we assign the table id here. We assign it to the - share before inserting it into the table_def_cache to be really - sure that it cannot be read from the cache without having a table - id assigned. - - CAVEAT. This means that the table cannot be used for - binlogging/replication purposes, unless get_table_share() has been - called directly or indirectly. - */ - assign_new_table_id(share); - - if (my_hash_insert(&table_def_cache, (uchar*) share)) - { - free_table_share(share); - DBUG_RETURN(0); // return error - } - if (open_table_def(thd, share, op)) - { - *error= share->error; - (void) my_hash_delete(&table_def_cache, (uchar*) share); - DBUG_RETURN(0); + /* + We assign a new table id under the protection of LOCK_open. + We do this instead of creating a new mutex + and using it for the sole purpose of serializing accesses to a + static variable, we assign the table id here. We assign it to the + share before inserting it into the table_def_cache to be really + sure that it cannot be read from the cache without having a table + id assigned. + + CAVEAT. This means that the table cannot be used for + binlogging/replication purposes, unless get_table_share() has been + called directly or indirectly. + */ + assign_new_table_id(share); + + if (my_hash_insert(&table_def_cache, (uchar*) share)) + { + free_table_share(share); + goto err; + } + if (open_table_def(thd, share, op)) + { + *error= share->error; + (void) my_hash_delete(&table_def_cache, (uchar*) share); + goto err; + } + share->ref_count++; // Mark in use + DBUG_PRINT("exit", ("share: 0x%lx ref_count: %u", + (ulong) share, share->ref_count)); + + goto end; } - share->ref_count++; // Mark in use - DBUG_PRINT("exit", ("share: 0x%lx ref_count: %u", - (ulong) share, share->ref_count)); - DBUG_RETURN(share); -found: /* We found an existing table definition. Return it if we didn't get an error when reading the table definition from file. @@ -643,12 +662,13 @@ found: { /* Table definition contained an error */ open_table_error(share, share->error, share->open_errno); - DBUG_RETURN(0); + goto err; } + if (share->is_view && op != FRM_READ_NO_ERROR_FOR_VIEW) { open_table_error(share, OPEN_FRM_NO_VIEWS, ENOENT); - DBUG_RETURN(0); + goto err; } ++share->ref_count; @@ -673,6 +693,12 @@ found: DBUG_PRINT("exit", ("share: 0x%lx ref_count: %u", (ulong) share, share->ref_count)); + goto end; + +err: + share= 0; +end: + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(share); } @@ -3013,13 +3039,10 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, retry_share: - mysql_mutex_lock(&LOCK_open); - if (!(share= get_table_share_with_discover(thd, table_list, key, key_length, FRM_READ_NO_ERROR_FOR_VIEW, &error, hash_value))) { - mysql_mutex_unlock(&LOCK_open); /* If thd->is_error() is not set, we either need discover or the error was silenced by the prelocking handler, in which case we should skip this @@ -3042,7 +3065,7 @@ retry_share: if (table_list->parent_l) { my_error(ER_WRONG_MRG_TABLE, MYF(0)); - goto err_unlock; + goto err_lock; } /* @@ -3050,12 +3073,12 @@ retry_share: that it was a view when the statement was prepared. */ if (check_and_update_table_version(thd, table_list, share)) - goto err_unlock; + goto err_lock; if (table_list->i_s_requested_object & OPEN_TABLE_ONLY) { my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->table_name); - goto err_unlock; + goto err_lock; } /* Open view */ @@ -3065,7 +3088,9 @@ retry_share: READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, thd->open_options, 0, table_list, mem_root)) - goto err_unlock; + goto err_lock; + + mysql_mutex_lock(&LOCK_open); /* TODO: Don't free this */ release_table_share(share); @@ -3087,12 +3112,12 @@ retry_share: { my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->table_name); - goto err_unlock; + goto err_lock; } + mysql_mutex_lock(&LOCK_open); if (!(flags & MYSQL_OPEN_IGNORE_FLUSH) || - (share->protected_against_usage() && - !(flags & MYSQL_OPEN_FOR_REPAIR))) + (share->protected_against_usage() && !(flags & MYSQL_OPEN_FOR_REPAIR))) { if (share->has_old_version()) { @@ -3144,12 +3169,12 @@ retry_share: { table= share->free_tables.front(); table_def_use_table(thd, table); - /* We need to release share as we have EXTRA reference to it in our hands. */ + /* Release the share as we hold an extra reference to it */ release_table_share(share); } else { - /* We have too many TABLE instances around let us try to get rid of them. */ + /* If we have too many TABLE instances around, try to get rid of them */ while (table_cache_count > table_cache_size && unused_tables) free_cache_entry(unused_tables); @@ -3218,7 +3243,6 @@ retry_share: err_lock: mysql_mutex_lock(&LOCK_open); -err_unlock: release_table_share(share); mysql_mutex_unlock(&LOCK_open); @@ -3853,30 +3877,26 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, hash_value= my_calc_hash(&table_def_cache, (uchar*) cache_key, cache_key_length); - mysql_mutex_lock(&LOCK_open); - if (!(share= get_table_share(thd, table_list, cache_key, cache_key_length, FRM_READ_NO_ERROR_FOR_VIEW, &error, hash_value))) - goto err; + return TRUE; - if (share->is_view && - !open_new_frm(thd, share, alias, - (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | - HA_GET_INDEX | HA_TRY_READ_ONLY), - READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD | - flags, thd->open_options, ¬_used, table_list, - mem_root)) - { - release_table_share(share); - mysql_mutex_unlock(&LOCK_open); - return FALSE; - } + bool err= !share->is_view || + open_new_frm(thd, share, alias, + (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | + HA_GET_INDEX | HA_TRY_READ_ONLY), + READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD | flags, + thd->open_options, ¬_used, table_list, mem_root); - my_error(ER_WRONG_OBJECT, MYF(0), share->db.str, share->table_name.str, "VIEW"); + mysql_mutex_lock(&LOCK_open); release_table_share(share); -err: mysql_mutex_unlock(&LOCK_open); - return TRUE; + + if (err) + my_error(ER_WRONG_OBJECT, MYF(0), table_list->db, + table_list->table_name, "VIEW"); + + return err; } @@ -3942,27 +3962,19 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) thd->clear_error(); + if (!(entry= (TABLE*)my_malloc(sizeof(TABLE), MYF(MY_WME)))) + return result; + hash_value= my_calc_hash(&table_def_cache, (uchar*) cache_key, cache_key_length); - mysql_mutex_lock(&LOCK_open); if (!(share= get_table_share(thd, table_list, cache_key, cache_key_length, FRM_READ_NO_ERROR_FOR_VIEW, ¬_used, hash_value))) - goto end_unlock; + goto end_free; if (share->is_view) - { - release_table_share(share); - goto end_unlock; - } - - if (!(entry= (TABLE*)my_malloc(sizeof(TABLE), MYF(MY_WME)))) - { - release_table_share(share); - goto end_unlock; - } - mysql_mutex_unlock(&LOCK_open); + goto end_release; if (open_table_from_share(thd, share, table_list->alias, (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | @@ -3987,16 +3999,17 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) closefrm(entry, 0); result= FALSE; } - my_free(entry); +end_release: mysql_mutex_lock(&LOCK_open); release_table_share(share); /* Remove the repaired share from the table cache. */ tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db, table_list->table_name, TRUE); -end_unlock: mysql_mutex_unlock(&LOCK_open); +end_free: + my_free(entry); return result; } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 7afbd3a7f9c..45c3318987c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4382,13 +4382,12 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, key_length= create_table_def_key(thd, key, &table_list, 0); hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); - mysql_mutex_lock(&LOCK_open); share= get_table_share(thd, &table_list, key, key_length, FRM_READ_NO_ERROR_FOR_VIEW, ¬_used, hash_value); if (!share) { res= 0; - goto end_unlock; + goto end; } if (share->is_view) @@ -4437,10 +4436,10 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, free_root(&tbl.mem_root, MYF(0)); } + end_share: + mysql_mutex_lock(&LOCK_open); release_table_share(share); - -end_unlock: mysql_mutex_unlock(&LOCK_open); end: diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 8ce2c145d01..67004dc538d 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1707,9 +1707,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) some_views_deleted= TRUE; /* - For a view, there is a TABLE_SHARE object, but its - ref_count never goes above 1. Remove it from the table - definition cache, in case the view was cached. + For a view, there is a TABLE_SHARE object. + Remove it from the table definition cache, in case the view was cached. */ tdc_remove_table(thd, TDC_RT_REMOVE_ALL, view->db, view->table_name, FALSE); diff --git a/sql/table.h b/sql/table.h index 737afc38300..520d5a2f2b5 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2188,9 +2188,9 @@ private: #else inline void set_check_merged() {} #endif - /** See comments for set_metadata_id() */ + /** See comments for set_table_ref_id() */ enum enum_table_ref_type m_table_ref_type; - /** See comments for set_metadata_id() */ + /** See comments for set_table_ref_id() */ ulong m_table_ref_version; }; |