Fixed bug mdev-4019.
The bug could cause a crash when several connections needed persistent statistics for the same table. Also added a missing call of set_statistics_for_table() in the code of the function mysql_update.
This commit is contained in:
parent
7d9df8075e
commit
7d5c56cb41
@ -219,4 +219,24 @@ set debug_sync='RESET';
|
||||
set global use_stat_tables=@save_global_use_stat_tables;
|
||||
DROP DATABASE dbt3_s001;
|
||||
use test;
|
||||
set @save_global_use_stat_tables=@@global.use_stat_tables;
|
||||
set global use_stat_tables='preferably';
|
||||
set debug_sync='RESET';
|
||||
create table t1 (a int, b int, key(a));
|
||||
insert t1 values (1,1),(2,2);
|
||||
analyze table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status OK
|
||||
SET debug_sync='after_open_table_ignore_flush WAIT_FOR go';
|
||||
select * from information_schema.statistics where table_schema='test';
|
||||
select * from t1;
|
||||
a b
|
||||
1 1
|
||||
2 2
|
||||
SET DEBUG_SYNC= "now SIGNAL go";
|
||||
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT INDEX_COMMENT
|
||||
def test t1 1 test a 1 a A 2 NULL NULL YES BTREE
|
||||
set debug_sync='RESET';
|
||||
drop table t1;
|
||||
set global use_stat_tables=@save_global_use_stat_tables;
|
||||
set use_stat_tables=@save_use_stat_tables;
|
||||
|
@ -228,6 +228,26 @@ set debug_sync='RESET';
|
||||
set global use_stat_tables=@save_global_use_stat_tables;
|
||||
DROP DATABASE dbt3_s001;
|
||||
use test;
|
||||
set @save_global_use_stat_tables=@@global.use_stat_tables;
|
||||
set global use_stat_tables='preferably';
|
||||
set debug_sync='RESET';
|
||||
create table t1 (a int, b int, key(a));
|
||||
insert t1 values (1,1),(2,2);
|
||||
analyze table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status OK
|
||||
SET debug_sync='after_open_table_ignore_flush WAIT_FOR go';
|
||||
select * from information_schema.statistics where table_schema='test';
|
||||
select * from t1;
|
||||
a b
|
||||
1 1
|
||||
2 2
|
||||
SET DEBUG_SYNC= "now SIGNAL go";
|
||||
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT INDEX_COMMENT
|
||||
def test t1 1 test a 1 a A 2 NULL NULL YES BTREE
|
||||
set debug_sync='RESET';
|
||||
drop table t1;
|
||||
set global use_stat_tables=@save_global_use_stat_tables;
|
||||
set use_stat_tables=@save_use_stat_tables;
|
||||
set optimizer_switch=@save_optimizer_switch_for_stat_tables_test;
|
||||
SET SESSION STORAGE_ENGINE=DEFAULT;
|
||||
|
@ -242,4 +242,37 @@ DROP DATABASE dbt3_s001;
|
||||
|
||||
use test;
|
||||
|
||||
#
|
||||
# Bug mdev-4019: crash when executing in parallel ANALYZE and
|
||||
# SELECT * FROM information_schema.statistics
|
||||
#
|
||||
|
||||
set @save_global_use_stat_tables=@@global.use_stat_tables;
|
||||
set global use_stat_tables='preferably';
|
||||
set debug_sync='RESET';
|
||||
|
||||
create table t1 (a int, b int, key(a));
|
||||
insert t1 values (1,1),(2,2);
|
||||
|
||||
analyze table t1;
|
||||
|
||||
SET debug_sync='after_open_table_ignore_flush WAIT_FOR go';
|
||||
send select * from information_schema.statistics where table_schema='test';
|
||||
|
||||
connect(con1, localhost, root);
|
||||
connection con1;
|
||||
select * from t1;
|
||||
SET DEBUG_SYNC= "now SIGNAL go";
|
||||
|
||||
connection default;
|
||||
reap;
|
||||
|
||||
connection default;
|
||||
disconnect con1;
|
||||
set debug_sync='RESET';
|
||||
|
||||
drop table t1;
|
||||
set global use_stat_tables=@save_global_use_stat_tables;
|
||||
|
||||
|
||||
set use_stat_tables=@save_use_stat_tables;
|
||||
|
@ -4654,6 +4654,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
|
||||
Field **table_field_ptr= tables->table->field;
|
||||
for ( ; *field_ptr; field_ptr++, table_field_ptr++)
|
||||
(*table_field_ptr)->read_stats= (*field_ptr)->read_stats;
|
||||
tables->table->stats_is_read= table_share->stats_cb.stats_is_read;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2501,6 +2501,8 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
|
||||
}
|
||||
}
|
||||
|
||||
table->stats_is_read= TRUE;
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
@ -2559,6 +2561,8 @@ bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables)
|
||||
table_share->stats_cb.stats_can_be_read &&
|
||||
!table_share->stats_cb.stats_is_read)
|
||||
return TRUE;
|
||||
if (table_share->stats_cb.stats_is_read)
|
||||
tl->table->stats_is_read= TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2618,6 +2622,8 @@ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables)
|
||||
(void) read_statistics_for_table(thd, tl->table, stat_tables);
|
||||
table_share->stats_cb.stats_is_read= TRUE;
|
||||
}
|
||||
if (table_share->stats_cb.stats_is_read)
|
||||
tl->table->stats_is_read= TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3045,7 +3051,7 @@ void set_statistics_for_table(THD *thd, TABLE *table)
|
||||
Use_stat_tables_mode use_stat_table_mode= get_use_stat_tables_mode(thd);
|
||||
table->used_stat_records=
|
||||
(use_stat_table_mode <= COMPLEMENTARY ||
|
||||
!stats_cb->stats_is_read || read_stats->cardinality_is_null) ?
|
||||
!table->stats_is_read || read_stats->cardinality_is_null) ?
|
||||
table->file->stats.records : read_stats->cardinality;
|
||||
KEY *key_info, *key_info_end;
|
||||
for (key_info= table->key_info, key_info_end= key_info+table->s->keys;
|
||||
@ -3053,7 +3059,7 @@ void set_statistics_for_table(THD *thd, TABLE *table)
|
||||
{
|
||||
key_info->is_statistics_from_stat_tables=
|
||||
(use_stat_table_mode > COMPLEMENTARY &&
|
||||
stats_cb->stats_is_read &&
|
||||
table->stats_is_read &&
|
||||
key_info->read_stats->avg_frequency_is_inited() &&
|
||||
key_info->read_stats->get_avg_frequency(0) > 0.5);
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "sql_view.h" // check_key_in_view
|
||||
#include "sp_head.h"
|
||||
#include "sql_trigger.h"
|
||||
#include "sql_statistics.h"
|
||||
#include "probes_mysql.h"
|
||||
#include "debug_sync.h"
|
||||
#include "key.h" // is_key_used
|
||||
@ -404,6 +405,7 @@ int mysql_update(THD *thd,
|
||||
#endif
|
||||
/* Update the table->file->stats.records number */
|
||||
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
|
||||
set_statistics_for_table(thd, table);
|
||||
|
||||
select= make_select(table, 0, 0, conds, 0, &error);
|
||||
if (error || !limit || thd->is_error() ||
|
||||
|
@ -1189,6 +1189,7 @@ public:
|
||||
bool no_partitions_used; /* If true, all partitions have been pruned away */
|
||||
#endif
|
||||
uint max_keys; /* Size of allocated key_info array. */
|
||||
bool stats_is_read; /* Persistent statistics is read for the table */
|
||||
MDL_ticket *mdl_ticket;
|
||||
|
||||
void init(THD *thd, TABLE_LIST *tl);
|
||||
|
Loading…
x
Reference in New Issue
Block a user