Commit 557303b8 authored by Igor Babaev's avatar Igor Babaev

Merged the fix for bug mdev-4019.

parents bc75820f 7d5c56cb
...@@ -219,4 +219,24 @@ set debug_sync='RESET'; ...@@ -219,4 +219,24 @@ set debug_sync='RESET';
set global use_stat_tables=@save_global_use_stat_tables; set global use_stat_tables=@save_global_use_stat_tables;
DROP DATABASE dbt3_s001; DROP DATABASE dbt3_s001;
use test; 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 use_stat_tables=@save_use_stat_tables;
...@@ -228,6 +228,26 @@ set debug_sync='RESET'; ...@@ -228,6 +228,26 @@ set debug_sync='RESET';
set global use_stat_tables=@save_global_use_stat_tables; set global use_stat_tables=@save_global_use_stat_tables;
DROP DATABASE dbt3_s001; DROP DATABASE dbt3_s001;
use test; 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 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;
...@@ -242,4 +242,37 @@ DROP DATABASE dbt3_s001; ...@@ -242,4 +242,37 @@ DROP DATABASE dbt3_s001;
use test; 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; set use_stat_tables=@save_use_stat_tables;
...@@ -4659,6 +4659,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, ...@@ -4659,6 +4659,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
Field **table_field_ptr= tables->table->field; Field **table_field_ptr= tables->table->field;
for ( ; *field_ptr; field_ptr++, table_field_ptr++) for ( ; *field_ptr; field_ptr++, table_field_ptr++)
(*table_field_ptr)->read_stats= (*field_ptr)->read_stats; (*table_field_ptr)->read_stats= (*field_ptr)->read_stats;
tables->table->stats_is_read= table_share->stats_cb.stats_is_read;
} }
} }
} }
......
...@@ -2499,6 +2499,8 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables) ...@@ -2499,6 +2499,8 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
} }
} }
table->stats_is_read= TRUE;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -2557,6 +2559,8 @@ bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables) ...@@ -2557,6 +2559,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_can_be_read &&
!table_share->stats_cb.stats_is_read) !table_share->stats_cb.stats_is_read)
return TRUE; return TRUE;
if (table_share->stats_cb.stats_is_read)
tl->table->stats_is_read= TRUE;
} }
} }
...@@ -2616,6 +2620,8 @@ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables) ...@@ -2616,6 +2620,8 @@ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables)
(void) read_statistics_for_table(thd, tl->table, stat_tables); (void) read_statistics_for_table(thd, tl->table, stat_tables);
table_share->stats_cb.stats_is_read= TRUE; table_share->stats_cb.stats_is_read= TRUE;
} }
if (table_share->stats_cb.stats_is_read)
tl->table->stats_is_read= TRUE;
} }
} }
...@@ -3034,7 +3040,7 @@ void set_statistics_for_table(THD *thd, TABLE *table) ...@@ -3034,7 +3040,7 @@ void set_statistics_for_table(THD *thd, TABLE *table)
Use_stat_tables_mode use_stat_table_mode= get_use_stat_tables_mode(thd); Use_stat_tables_mode use_stat_table_mode= get_use_stat_tables_mode(thd);
table->used_stat_records= table->used_stat_records=
(use_stat_table_mode <= COMPLEMENTARY || (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; table->file->stats.records : read_stats->cardinality;
KEY *key_info, *key_info_end; KEY *key_info, *key_info_end;
for (key_info= table->key_info, key_info_end= key_info+table->s->keys; for (key_info= table->key_info, key_info_end= key_info+table->s->keys;
...@@ -3042,7 +3048,7 @@ void set_statistics_for_table(THD *thd, TABLE *table) ...@@ -3042,7 +3048,7 @@ void set_statistics_for_table(THD *thd, TABLE *table)
{ {
key_info->is_statistics_from_stat_tables= key_info->is_statistics_from_stat_tables=
(use_stat_table_mode > COMPLEMENTARY && (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->avg_frequency_is_inited() &&
key_info->read_stats->get_avg_frequency(0) > 0.5); key_info->read_stats->get_avg_frequency(0) > 0.5);
} }
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "sql_view.h" // check_key_in_view #include "sql_view.h" // check_key_in_view
#include "sp_head.h" #include "sp_head.h"
#include "sql_trigger.h" #include "sql_trigger.h"
#include "sql_statistics.h"
#include "probes_mysql.h" #include "probes_mysql.h"
#include "debug_sync.h" #include "debug_sync.h"
#include "key.h" // is_key_used #include "key.h" // is_key_used
...@@ -393,6 +394,7 @@ int mysql_update(THD *thd, ...@@ -393,6 +394,7 @@ int mysql_update(THD *thd,
#endif #endif
/* Update the table->file->stats.records number */ /* Update the table->file->stats.records number */
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); 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); select= make_select(table, 0, 0, conds, 0, &error);
if (error || !limit || thd->is_error() || if (error || !limit || thd->is_error() ||
......
...@@ -1196,6 +1196,7 @@ struct TABLE ...@@ -1196,6 +1196,7 @@ struct TABLE
bool no_partitions_used; /* If true, all partitions have been pruned away */ bool no_partitions_used; /* If true, all partitions have been pruned away */
#endif #endif
uint max_keys; /* Size of allocated key_info array. */ uint max_keys; /* Size of allocated key_info array. */
bool stats_is_read; /* Persistent statistics is read for the table */
MDL_ticket *mdl_ticket; MDL_ticket *mdl_ticket;
void init(THD *thd, TABLE_LIST *tl); void init(THD *thd, TABLE_LIST *tl);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment