diff --git a/mysql-test/suite/innodb/r/innodb_stats_fetch.result b/mysql-test/suite/innodb/r/innodb_stats_fetch.result index df6bc4b0cf7..76d6b022f03 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_fetch.result +++ b/mysql-test/suite/innodb/r/innodb_stats_fetch.result @@ -174,3 +174,13 @@ SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_VIRTUAL LIMIT ROWS EXAMINED 5; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN LIMIT ROWS EXAMINED 5; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS LIMIT ROWS EXAMINED 5; DROP TABLE t1; +# +# MDEV-34474 InnoDB: Failing assertion: stat_n_leaf_pages > 0 +# in ha_innobase::estimate_rows_upper_bound +# +CREATE TABLE t (c1 INT,c2 INT, +INDEX(c1))STATS_PERSISTENT=1 ENGINE=INNODB; +UPDATE mysql.innodb_index_stats SET stat_value=0 WHERE database_name like "test" and table_name like 't'; +UPDATE mysql.innodb_table_stats SET clustered_index_size= 0, sum_of_other_index_sizes=0 WHERE database_name like "test" and table_name like 't'; +UPDATE t SET c1=+1 ORDER BY c2; +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/innodb_stats_fetch.test b/mysql-test/suite/innodb/t/innodb_stats_fetch.test index 99fc115af1d..8968b48e0b2 100644 --- a/mysql-test/suite/innodb/t/innodb_stats_fetch.test +++ b/mysql-test/suite/innodb/t/innodb_stats_fetch.test @@ -96,3 +96,15 @@ SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_VIRTUAL LIMIT ROWS EXAMINED 5; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN LIMIT ROWS EXAMINED 5; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS LIMIT ROWS EXAMINED 5; DROP TABLE t1; + +--echo # +--echo # MDEV-34474 InnoDB: Failing assertion: stat_n_leaf_pages > 0 +--echo # in ha_innobase::estimate_rows_upper_bound +--echo # + +CREATE TABLE t (c1 INT,c2 INT, + INDEX(c1))STATS_PERSISTENT=1 ENGINE=INNODB; +UPDATE mysql.innodb_index_stats SET stat_value=0 WHERE database_name like "test" and table_name like 't'; +UPDATE mysql.innodb_table_stats SET clustered_index_size= 0, sum_of_other_index_sizes=0 WHERE database_name like "test" and table_name like 't'; +UPDATE t SET c1=+1 ORDER BY c2; +DROP TABLE t; diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 9b6abab162a..8ab8cec47e3 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -2665,25 +2665,34 @@ dict_stats_fetch_table_stats_step( break; case 1: /* mysql.innodb_table_stats.clustered_index_size */ - + { ut_a(dtype_get_mtype(type) == DATA_INT); ut_a(len == 8); table->stat_clustered_index_size - = (ulint) mach_read_from_8(data); - + = std::max(mach_read_from_8(data), 1); break; + } case 2: /* mysql.innodb_table_stats.sum_of_other_index_sizes */ - + { ut_a(dtype_get_mtype(type) == DATA_INT); ut_a(len == 8); - table->stat_sum_of_other_index_sizes + ulint stat_other_idx_size = (ulint) mach_read_from_8(data); + if (!stat_other_idx_size + && UT_LIST_GET_LEN(table->indexes) > 1) { + stat_other_idx_size + = UT_LIST_GET_LEN(table->indexes) - 1; + } + table->stat_sum_of_other_index_sizes + = std::max( + mach_read_from_8(data), + UT_LIST_GET_LEN(table->indexes) - 1); break; - + } default: /* someone changed SELECT @@ -2866,12 +2875,14 @@ dict_stats_fetch_index_stats_step( if (stat_name_len == 4 /* strlen("size") */ && strncasecmp("size", stat_name, stat_name_len) == 0) { - index->stat_index_size = (ulint) stat_value; + index->stat_index_size + = std::max(stat_value, 1); arg->stats_were_modified = true; } else if (stat_name_len == 12 /* strlen("n_leaf_pages") */ && strncasecmp("n_leaf_pages", stat_name, stat_name_len) == 0) { - index->stat_n_leaf_pages = (ulint) stat_value; + index->stat_n_leaf_pages + = std::max(stat_value, 1); arg->stats_were_modified = true; } else if (stat_name_len == 12 /* strlen("n_page_split") */ && strncasecmp("n_page_split", stat_name, stat_name_len) @@ -2951,7 +2962,8 @@ dict_stats_fetch_index_stats_step( index->stat_n_diff_key_vals[n_pfx - 1] = stat_value; if (sample_size != UINT64_UNDEFINED) { - index->stat_n_sample_sizes[n_pfx - 1] = sample_size; + index->stat_n_sample_sizes[n_pfx - 1] = + std::max(sample_size, 1); } else { /* hmm, strange... the user must have UPDATEd the table manually and SET sample_size = NULL */