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:
@ -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 */
|
||||
|
||||
|
Reference in New Issue
Block a user