1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-8633: information_schema.index_statistics doesn't delete

item when drop table indexes or drop table;

Problem was that table and index statistics is removed from
persistent tables but not from memory cache. Added functions
to remove table and index statistics from memory cache.
This commit is contained in:
Jan Lindström
2016-06-20 09:58:31 +03:00
parent e24a183370
commit 70ad689b11
6 changed files with 219 additions and 5 deletions

View File

@ -3460,6 +3460,100 @@ int fill_schema_table_stats(THD *thd, TABLE_LIST *tables, COND *cond)
DBUG_RETURN(0);
}
/* Remove all indexes for a given table from global index statistics */
static
int del_global_index_stats_for_table(THD *thd, uchar* cache_key, uint cache_key_length)
{
int res = 0;
DBUG_ENTER("del_global_index_stats_for_table");
mysql_mutex_lock(&LOCK_global_index_stats);
for (uint i= 0; i < global_index_stats.records;)
{
INDEX_STATS *index_stats =
(INDEX_STATS*) my_hash_element(&global_index_stats, i);
/* We search correct db\0table_name\0 string */
if (index_stats &&
index_stats->index_name_length >= cache_key_length &&
!memcmp(index_stats->index, cache_key, cache_key_length))
{
res= my_hash_delete(&global_index_stats, (uchar*)index_stats);
/*
In our HASH implementation on deletion one elements
is moved into a place where a deleted element was,
and the last element is moved into the empty space.
Thus we need to re-examine the current element, but
we don't have to restart the search from the beginning.
*/
}
else
i++;
}
mysql_mutex_unlock(&LOCK_global_index_stats);
DBUG_RETURN(res);
}
/* Remove a table from global table statistics */
int del_global_table_stat(THD *thd, LEX_STRING *db, LEX_STRING *table)
{
TABLE_STATS *table_stats;
int res = 0;
uchar *cache_key;
uint cache_key_length;
DBUG_ENTER("del_global_table_stat");
cache_key_length= db->length + 1 + table->length + 1;
if(!(cache_key= (uchar *)my_malloc(cache_key_length,
MYF(MY_WME | MY_ZEROFILL))))
{
/* Out of memory error already given */
res = 1;
goto end;
}
memcpy(cache_key, db->str, db->length);
memcpy(cache_key + db->length + 1, table->str, table->length);
res= del_global_index_stats_for_table(thd, cache_key, cache_key_length);
mysql_mutex_lock(&LOCK_global_table_stats);
if((table_stats= (TABLE_STATS*) my_hash_search(&global_table_stats,
cache_key,
cache_key_length)))
res= my_hash_delete(&global_table_stats, (uchar*)table_stats);
my_free(cache_key);
mysql_mutex_unlock(&LOCK_global_table_stats);
end:
DBUG_RETURN(res);
}
/* Remove a index from global index statistics */
int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info)
{
INDEX_STATS *index_stats;
uint key_length= table->s->table_cache_key.length + key_info->name_length + 1;
int res = 0;
DBUG_ENTER("del_global_index_stat");
mysql_mutex_lock(&LOCK_global_index_stats);
if((index_stats= (INDEX_STATS*) my_hash_search(&global_index_stats,
key_info->cache_name,
key_length)))
res= my_hash_delete(&global_index_stats, (uchar*)index_stats);
mysql_mutex_unlock(&LOCK_global_index_stats);
DBUG_RETURN(res);
}
/* Fill information schema table with index statistics */