mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-16757 Memory leak after adding manually min/max statistical data
for blob column ANALYZE TABLE <table> does not collect statistical data on min/max values for BLOB columns of <table>. However these values can be added into mysql.column_stats manually by executing proper statements. Unfortunately this led to a memory leak because the memory allocated for these values was never freed. This patch provides the server with a function to free memory allocated for min/max statistical values of BLOB types. Temporarily changed the test case until MDEV-16711 is fixed as without this fix the test case for MDEV-16757 did not fail only for 10.0.
This commit is contained in:
@ -517,3 +517,27 @@ drop database db1;
|
|||||||
drop database db2;
|
drop database db2;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
set use_stat_tables=@save_use_stat_tables;
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
|
#
|
||||||
|
# MDEV-16757: manual addition of min/max statistics for BLOB
|
||||||
|
#
|
||||||
|
SET use_stat_tables= PREFERABLY;
|
||||||
|
CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT);
|
||||||
|
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
|
||||||
|
ANALYZE TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status Engine-independent statistics collected
|
||||||
|
test.t1 analyze Warning Engine-independent statistics are not collected for column 't'
|
||||||
|
test.t1 analyze status OK
|
||||||
|
SELECT * FROM mysql.column_stats;
|
||||||
|
db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram
|
||||||
|
test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL
|
||||||
|
DELETE FROM mysql.column_stats
|
||||||
|
WHERE db_name='test' AND table_name='t1' AND column_name='t';
|
||||||
|
INSERT INTO mysql.column_stats VALUES
|
||||||
|
('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL);
|
||||||
|
SELECT * FROM mysql.column_stats;
|
||||||
|
db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram
|
||||||
|
test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL
|
||||||
|
test t1 t bar foo 0.0000 3.0000 1.0000 0 NULL NULL
|
||||||
|
DROP TABLE t1;
|
||||||
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
|
@ -544,5 +544,29 @@ drop database db1;
|
|||||||
drop database db2;
|
drop database db2;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
set use_stat_tables=@save_use_stat_tables;
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
|
#
|
||||||
|
# MDEV-16757: manual addition of min/max statistics for BLOB
|
||||||
|
#
|
||||||
|
SET use_stat_tables= PREFERABLY;
|
||||||
|
CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT);
|
||||||
|
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
|
||||||
|
ANALYZE TABLE t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status Engine-independent statistics collected
|
||||||
|
test.t1 analyze Warning Engine-independent statistics are not collected for column 't'
|
||||||
|
test.t1 analyze status OK
|
||||||
|
SELECT * FROM mysql.column_stats;
|
||||||
|
db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram
|
||||||
|
test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL
|
||||||
|
DELETE FROM mysql.column_stats
|
||||||
|
WHERE db_name='test' AND table_name='t1' AND column_name='t';
|
||||||
|
INSERT INTO mysql.column_stats VALUES
|
||||||
|
('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL);
|
||||||
|
SELECT * FROM mysql.column_stats;
|
||||||
|
db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram
|
||||||
|
test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL
|
||||||
|
test t1 t bar foo 0.0000 3.0000 1.0000 0 NULL NULL
|
||||||
|
DROP TABLE t1;
|
||||||
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
set optimizer_switch=@save_optimizer_switch_for_stat_tables_test;
|
set optimizer_switch=@save_optimizer_switch_for_stat_tables_test;
|
||||||
SET SESSION STORAGE_ENGINE=DEFAULT;
|
SET SESSION STORAGE_ENGINE=DEFAULT;
|
||||||
|
@ -306,3 +306,27 @@ drop database db2;
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
set use_stat_tables=@save_use_stat_tables;
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-16757: manual addition of min/max statistics for BLOB
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET use_stat_tables= PREFERABLY;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT);
|
||||||
|
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
|
||||||
|
ANALYZE TABLE t1;
|
||||||
|
--sorted_result
|
||||||
|
SELECT * FROM mysql.column_stats;
|
||||||
|
DELETE FROM mysql.column_stats
|
||||||
|
WHERE db_name='test' AND table_name='t1' AND column_name='t';
|
||||||
|
INSERT INTO mysql.column_stats VALUES
|
||||||
|
('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL);
|
||||||
|
--sorted_result
|
||||||
|
SELECT * FROM mysql.column_stats;
|
||||||
|
|
||||||
|
# SELECT pk FROM t1;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
|
@ -3055,6 +3055,39 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@breif
|
||||||
|
Cleanup of min/max statistical values for table share
|
||||||
|
*/
|
||||||
|
|
||||||
|
void delete_stat_values_for_table_share(TABLE_SHARE *table_share)
|
||||||
|
{
|
||||||
|
TABLE_STATISTICS_CB *stats_cb= &table_share->stats_cb;
|
||||||
|
Table_statistics *table_stats= stats_cb->table_stats;
|
||||||
|
if (!table_stats)
|
||||||
|
return;
|
||||||
|
Column_statistics *column_stats= table_stats->column_stats;
|
||||||
|
if (!column_stats)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (Field **field_ptr= table_share->field;
|
||||||
|
*field_ptr;
|
||||||
|
field_ptr++, column_stats++)
|
||||||
|
{
|
||||||
|
if (column_stats->min_value)
|
||||||
|
{
|
||||||
|
delete column_stats->min_value;
|
||||||
|
column_stats->min_value= NULL;
|
||||||
|
}
|
||||||
|
if (column_stats->max_value)
|
||||||
|
{
|
||||||
|
delete column_stats->max_value;
|
||||||
|
column_stats->max_value= NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief
|
@brief
|
||||||
Check whether any statistics is to be read for tables from a table list
|
Check whether any statistics is to be read for tables from a table list
|
||||||
|
@ -92,6 +92,7 @@ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables);
|
|||||||
int collect_statistics_for_table(THD *thd, TABLE *table);
|
int collect_statistics_for_table(THD *thd, TABLE *table);
|
||||||
int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *share,
|
int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *share,
|
||||||
bool is_safe);
|
bool is_safe);
|
||||||
|
void delete_stat_values_for_table_share(TABLE_SHARE *table_share);
|
||||||
int alloc_statistics_for_table(THD *thd, TABLE *table);
|
int alloc_statistics_for_table(THD *thd, TABLE *table);
|
||||||
int update_statistics_for_table(THD *thd, TABLE *table);
|
int update_statistics_for_table(THD *thd, TABLE *table);
|
||||||
int delete_statistics_for_table(THD *thd, LEX_STRING *db, LEX_STRING *tab);
|
int delete_statistics_for_table(THD *thd, LEX_STRING *db, LEX_STRING *tab);
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include "lf.h"
|
#include "lf.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "sql_base.h"
|
#include "sql_base.h"
|
||||||
|
#include "sql_statistics.h"
|
||||||
|
|
||||||
|
|
||||||
/** Configuration. */
|
/** Configuration. */
|
||||||
@ -786,6 +787,7 @@ void tdc_release_share(TABLE_SHARE *share)
|
|||||||
}
|
}
|
||||||
if (share->tdc->flushed || tdc_records() > tdc_size)
|
if (share->tdc->flushed || tdc_records() > tdc_size)
|
||||||
{
|
{
|
||||||
|
delete_stat_values_for_table_share(share);
|
||||||
mysql_mutex_unlock(&LOCK_unused_shares);
|
mysql_mutex_unlock(&LOCK_unused_shares);
|
||||||
tdc_delete_share_from_hash(share->tdc);
|
tdc_delete_share_from_hash(share->tdc);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
Reference in New Issue
Block a user