Skip to content

Commit d9e3f82

Browse files
author
Olav Sandstaa
committed
Bug#19537790 INNODB_STATS_FETCH FAILS WITH WRONG CARDINALITY
ESTIMATE ON 32 BIT PLATFORMS The innodb_stats_fetch test failed when running on 32 bit platforms due to an "off by one" cardinality number in the result from a query that read from the statitics table in information schema. This test failure is caused by WL#7339. The cardinality numbers that are retrieved from information schema is roughly calculated this way when the table is stored in InnoDB: 1. InnoDB has the number of rows and the cardinality for the index stored in the persistent statistics. In the failing case, InnoDB had 1000 as the number of rows and 3 as the cardinality. 2. InnoDB calculates the records per key value and stores this in the KEY object. This is calculated as 1000/3 and is thus 333.333333.... when using the code from WL#7339 (before this worklog, the rec_per_key value was 166). 3. When filling data into information schema, we re-calculate the cardinality number by using the records per key information (in sql_show.cc): double records= (show_table->file->stats.records / key->records_per_key(j)); table->field[9]->store((longlong) records, TRUE); in this case we first compute the cardinality to be records= 1000 / 333.3333... = 3.0000... or 2.9999999 and then use the cast to get an integer value. On 64-bit platforms, the result of this was 3.00000 which was casted to 3. On 32 bit platforms, the result was 2.999999 which was casted to 2 before inserting it into the information schema table. (in the pre-wl7339 version, the calculated cardinality number was 6 for this case). This issue is caused by having converted to using a float numbers for the records per key estimate. So when re-calculating the cardinatily number in step 3 above, we can easily get a result that is just below the actual correct cardinality number and due to the use of cast, the number is always truncated. The suggested fix for this problem is to round the calculated cardinality number to the nearest integer value before inserting it into the statistics table. This will both avoid the issue with different results on different platforms but it will also produce a more correct cardinality estimate. This change has caused a few other test result files to be re-recorded. The updated cardinality numbers are more correct than the previous.
1 parent 14fb2a9 commit d9e3f82

File tree

3 files changed

+5
-5
lines changed

3 files changed

+5
-5
lines changed

mysql-test/r/myisam.result

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ test.t1 optimize status OK
4141
show index from t1;
4242
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
4343
t1 0 PRIMARY 1 a A 5 NULL NULL BTREE
44-
t1 1 b 1 b A 1 NULL NULL BTREE
44+
t1 1 b 1 b A 2 NULL NULL BTREE
4545
optimize table t1;
4646
Table Op Msg_type Msg_text
4747
test.t1 optimize status Table is already up to date
4848
show index from t1;
4949
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
5050
t1 0 PRIMARY 1 a A 5 NULL NULL BTREE
51-
t1 1 b 1 b A 1 NULL NULL BTREE
51+
t1 1 b 1 b A 2 NULL NULL BTREE
5252
drop table t1;
5353
create table t1 (a int not null, b int not null, c int not null, primary key (a),key(b)) engine=myisam;
5454
insert into t1 values (3,3,3),(1,1,1),(2,2,2),(4,4,4);
@@ -356,7 +356,7 @@ show index from t1;
356356
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
357357
t1 1 b 1 b A 5 NULL NULL YES BTREE
358358
t1 1 c 1 c A 5 NULL NULL YES BTREE
359-
t1 1 a 1 a A 1 NULL NULL BTREE
359+
t1 1 a 1 a A 2 NULL NULL BTREE
360360
t1 1 a 2 b A 5 NULL NULL YES BTREE
361361
t1 1 c_2 1 c A 5 NULL NULL YES BTREE
362362
t1 1 c_2 2 a A 5 NULL NULL BTREE

mysql-test/r/show_check.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def information_schema STATISTICS STATISTICS COMMENT Comment 253 16 0 Y 0 0 8
7676
def information_schema STATISTICS STATISTICS INDEX_COMMENT Index_comment 253 1024 0 N 1 0 8
7777
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
7878
t1 0 PRIMARY 1 a A 5 NULL NULL BTREE
79-
t1 1 b 1 b A 1 NULL NULL BTREE
79+
t1 1 b 1 b A 2 NULL NULL BTREE
8080
t1 1 b 2 c A 5 NULL NULL BTREE
8181
insert into t1 values (5,5,5);
8282
ERROR 23000: Duplicate entry '5' for key 'PRIMARY'

sql/sql_show.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5667,7 +5667,7 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables,
56675667
{
56685668
double records= (show_table->file->stats.records /
56695669
key->records_per_key(j));
5670-
table->field[9]->store((longlong) records, TRUE);
5670+
table->field[9]->store(static_cast<longlong>(round(records)), TRUE);
56715671
table->field[9]->set_notnull();
56725672
}
56735673
str= show_table->file->index_type(i);

0 commit comments

Comments
 (0)