diff --git a/mysql-test/main/mysqldump-system.result b/mysql-test/main/mysqldump-system.result index f7d12ad421f04..bc102e4268448 100644 --- a/mysql-test/main/mysqldump-system.result +++ b/mysql-test/main/mysqldump-system.result @@ -121,6 +121,8 @@ REPLACE INTO `innodb_index_stats` VALUES ('test','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx01',5,1,'Time_zone_id'), ('test','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx02',394,1,'Time_zone_id,Transition_time'), ('test','tz','PRIMARY','2019-12-31 21:00:00','n_leaf_pages',1,NULL,'Number of leaf pages in the index'), +('test','tz','PRIMARY','2019-12-31 21:00:00','n_nonnull_pfx01',0,1,'Time_zone_id'), +('test','tz','PRIMARY','2019-12-31 21:00:00','n_nonnull_pfx02',0,1,'Time_zone_id,Transition_time'), ('test','tz','PRIMARY','2019-12-31 21:00:00','size',1,NULL,'Number of pages in the index'); /*!40000 ALTER TABLE `innodb_index_stats` ENABLE KEYS */; UNLOCK TABLES; @@ -741,6 +743,8 @@ REPLACE INTO `innodb_index_stats` VALUES ('test','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx01',5,1,'Time_zone_id'), ('test','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx02',394,1,'Time_zone_id,Transition_time'), ('test','tz','PRIMARY','2019-12-31 21:00:00','n_leaf_pages',1,NULL,'Number of leaf pages in the index'), +('test','tz','PRIMARY','2019-12-31 21:00:00','n_nonnull_pfx01',0,1,'Time_zone_id'), +('test','tz','PRIMARY','2019-12-31 21:00:00','n_nonnull_pfx02',0,1,'Time_zone_id,Transition_time'), ('test','tz','PRIMARY','2019-12-31 21:00:00','size',1,NULL,'Number of pages in the index'); /*!40000 ALTER TABLE `innodb_index_stats` ENABLE KEYS */; UNLOCK TABLES; @@ -1338,6 +1342,8 @@ INSERT IGNORE INTO `innodb_index_stats` VALUES ('test','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx01',5,1,'Time_zone_id'), ('test','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx02',394,1,'Time_zone_id,Transition_time'), ('test','tz','PRIMARY','2019-12-31 21:00:00','n_leaf_pages',1,NULL,'Number of leaf pages in the index'), +('test','tz','PRIMARY','2019-12-31 21:00:00','n_nonnull_pfx01',0,1,'Time_zone_id'), +('test','tz','PRIMARY','2019-12-31 21:00:00','n_nonnull_pfx02',0,1,'Time_zone_id,Transition_time'), ('test','tz','PRIMARY','2019-12-31 21:00:00','size',1,NULL,'Number of pages in the index'); /*!40000 ALTER TABLE `innodb_index_stats` ENABLE KEYS */; UNLOCK TABLES; diff --git a/mysql-test/suite/gcol/r/innodb_virtual_stats.result b/mysql-test/suite/gcol/r/innodb_virtual_stats.result index c0f595263df72..820db9ccf996a 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_stats.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_stats.result @@ -13,15 +13,21 @@ WHERE database_name = 'test' AND table_name = 't'; index_name stat_name stat_description GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index +GEN_CLUST_INDEX n_nonnull_pfx01 DB_ROW_ID GEN_CLUST_INDEX size Number of pages in the index idxa n_diff_pfx01 a idxa n_diff_pfx02 a,DB_ROW_ID idxa n_leaf_pages Number of leaf pages in the index +idxa n_nonnull_pfx01 a +idxa n_nonnull_pfx02 a,DB_ROW_ID idxa size Number of pages in the index vidxcd n_diff_pfx01 c vidxcd n_diff_pfx02 c,d vidxcd n_diff_pfx03 c,d,DB_ROW_ID vidxcd n_leaf_pages Number of leaf pages in the index +vidxcd n_nonnull_pfx01 c +vidxcd n_nonnull_pfx02 c,d +vidxcd n_nonnull_pfx03 c,d,DB_ROW_ID vidxcd size Number of pages in the index ALTER TABLE t ADD COLUMN e INT GENERATED ALWAYS AS(a+a+b), ADD INDEX idxb (b), ALGORITHM=INPLACE; select count(*) from t; @@ -33,19 +39,27 @@ WHERE database_name = 'test' AND table_name = 't'; index_name stat_name stat_description GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index +GEN_CLUST_INDEX n_nonnull_pfx01 DB_ROW_ID GEN_CLUST_INDEX size Number of pages in the index idxa n_diff_pfx01 a idxa n_diff_pfx02 a,DB_ROW_ID idxa n_leaf_pages Number of leaf pages in the index +idxa n_nonnull_pfx01 a +idxa n_nonnull_pfx02 a,DB_ROW_ID idxa size Number of pages in the index idxb n_diff_pfx01 b idxb n_diff_pfx02 b,DB_ROW_ID idxb n_leaf_pages Number of leaf pages in the index +idxb n_nonnull_pfx01 b +idxb n_nonnull_pfx02 b,DB_ROW_ID idxb size Number of pages in the index vidxcd n_diff_pfx01 c vidxcd n_diff_pfx02 c,d vidxcd n_diff_pfx03 c,d,DB_ROW_ID vidxcd n_leaf_pages Number of leaf pages in the index +vidxcd n_nonnull_pfx01 c +vidxcd n_nonnull_pfx02 c,d +vidxcd n_nonnull_pfx03 c,d,DB_ROW_ID vidxcd size Number of pages in the index ALTER TABLE t DROP COLUMN c, DROP INDEX idxa, ALGORITHM=INPLACE; select count(*) from t; @@ -57,14 +71,19 @@ WHERE database_name = 'test' AND table_name = 't'; index_name stat_name stat_description GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index +GEN_CLUST_INDEX n_nonnull_pfx01 DB_ROW_ID GEN_CLUST_INDEX size Number of pages in the index idxb n_diff_pfx01 b idxb n_diff_pfx02 b,DB_ROW_ID idxb n_leaf_pages Number of leaf pages in the index +idxb n_nonnull_pfx01 b +idxb n_nonnull_pfx02 b,DB_ROW_ID idxb size Number of pages in the index vidxcd n_diff_pfx01 d vidxcd n_diff_pfx02 d,DB_ROW_ID vidxcd n_leaf_pages Number of leaf pages in the index +vidxcd n_nonnull_pfx01 d +vidxcd n_nonnull_pfx02 d,DB_ROW_ID vidxcd size Number of pages in the index ALTER TABLE t ADD INDEX vidxe (e), ALGORITHM=INPLACE; select count(*) from t; @@ -76,18 +95,25 @@ WHERE database_name = 'test' AND table_name = 't'; index_name stat_name stat_description GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index +GEN_CLUST_INDEX n_nonnull_pfx01 DB_ROW_ID GEN_CLUST_INDEX size Number of pages in the index idxb n_diff_pfx01 b idxb n_diff_pfx02 b,DB_ROW_ID idxb n_leaf_pages Number of leaf pages in the index +idxb n_nonnull_pfx01 b +idxb n_nonnull_pfx02 b,DB_ROW_ID idxb size Number of pages in the index vidxcd n_diff_pfx01 d vidxcd n_diff_pfx02 d,DB_ROW_ID vidxcd n_leaf_pages Number of leaf pages in the index +vidxcd n_nonnull_pfx01 d +vidxcd n_nonnull_pfx02 d,DB_ROW_ID vidxcd size Number of pages in the index vidxe n_diff_pfx01 e vidxe n_diff_pfx02 e,DB_ROW_ID vidxe n_leaf_pages Number of leaf pages in the index +vidxe n_nonnull_pfx01 e +vidxe n_nonnull_pfx02 e,DB_ROW_ID vidxe size Number of pages in the index ALTER TABLE t ADD COLUMN f INT GENERATED ALWAYS AS(a + a), ADD INDEX vidxf (f), ALGORITHM=INPLACE; select count(*) from t; @@ -99,22 +125,31 @@ WHERE database_name = 'test' AND table_name = 't'; index_name stat_name stat_description GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index +GEN_CLUST_INDEX n_nonnull_pfx01 DB_ROW_ID GEN_CLUST_INDEX size Number of pages in the index idxb n_diff_pfx01 b idxb n_diff_pfx02 b,DB_ROW_ID idxb n_leaf_pages Number of leaf pages in the index +idxb n_nonnull_pfx01 b +idxb n_nonnull_pfx02 b,DB_ROW_ID idxb size Number of pages in the index vidxcd n_diff_pfx01 d vidxcd n_diff_pfx02 d,DB_ROW_ID vidxcd n_leaf_pages Number of leaf pages in the index +vidxcd n_nonnull_pfx01 d +vidxcd n_nonnull_pfx02 d,DB_ROW_ID vidxcd size Number of pages in the index vidxe n_diff_pfx01 e vidxe n_diff_pfx02 e,DB_ROW_ID vidxe n_leaf_pages Number of leaf pages in the index +vidxe n_nonnull_pfx01 e +vidxe n_nonnull_pfx02 e,DB_ROW_ID vidxe size Number of pages in the index vidxf n_diff_pfx01 f vidxf n_diff_pfx02 f,DB_ROW_ID vidxf n_leaf_pages Number of leaf pages in the index +vidxf n_nonnull_pfx01 f +vidxf n_nonnull_pfx02 f,DB_ROW_ID vidxf size Number of pages in the index ALTER TABLE t DROP INDEX vidxcd; SELECT index_name, stat_name, stat_description @@ -123,17 +158,24 @@ WHERE database_name = 'test' AND table_name = 't'; index_name stat_name stat_description GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index +GEN_CLUST_INDEX n_nonnull_pfx01 DB_ROW_ID GEN_CLUST_INDEX size Number of pages in the index idxb n_diff_pfx01 b idxb n_diff_pfx02 b,DB_ROW_ID idxb n_leaf_pages Number of leaf pages in the index +idxb n_nonnull_pfx01 b +idxb n_nonnull_pfx02 b,DB_ROW_ID idxb size Number of pages in the index vidxe n_diff_pfx01 e vidxe n_diff_pfx02 e,DB_ROW_ID vidxe n_leaf_pages Number of leaf pages in the index +vidxe n_nonnull_pfx01 e +vidxe n_nonnull_pfx02 e,DB_ROW_ID vidxe size Number of pages in the index vidxf n_diff_pfx01 f vidxf n_diff_pfx02 f,DB_ROW_ID vidxf n_leaf_pages Number of leaf pages in the index +vidxf n_nonnull_pfx01 f +vidxf n_nonnull_pfx02 f,DB_ROW_ID vidxf size Number of pages in the index DROP TABLE t; diff --git a/mysql-test/suite/innodb/r/innodb-index-online.result b/mysql-test/suite/innodb/r/innodb-index-online.result index 7ebd3cc0fcf10..d00523b5cd6fe 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online.result +++ b/mysql-test/suite/innodb/r/innodb-index-online.result @@ -132,9 +132,11 @@ SELECT * FROM mysql.innodb_index_stats WHERE table_name IN ('t1'); database_name table_name index_name last_update stat_name stat_value sample_size stat_description test t1 PRIMARY LAST_UPDATE n_diff_pfx01 5 1 c1 test t1 PRIMARY LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index +test t1 PRIMARY LAST_UPDATE n_nonnull_pfx01 0 1 c1 test t1 PRIMARY LAST_UPDATE size 1 NULL Number of pages in the index test t1 c2 LAST_UPDATE n_diff_pfx01 5 1 c2 test t1 c2 LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index +test t1 c2 LAST_UPDATE n_nonnull_pfx01 0 1 c2 test t1 c2 LAST_UPDATE size 1 NULL Number of pages in the index CREATE TABLE t1_c2_stats SELECT * FROM mysql.innodb_index_stats WHERE database_name = 'test' AND table_name = 't1' and index_name = 'c2'; @@ -148,9 +150,11 @@ SELECT * FROM mysql.innodb_index_stats WHERE table_name IN ('t1', 't1_c2_stats') database_name table_name index_name last_update stat_name stat_value sample_size stat_description test t1 PRIMARY LAST_UPDATE n_diff_pfx01 5 1 c1 test t1 PRIMARY LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index +test t1 PRIMARY LAST_UPDATE n_nonnull_pfx01 0 1 c1 test t1 PRIMARY LAST_UPDATE size 1 NULL Number of pages in the index -test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE n_diff_pfx01 3 1 DB_ROW_ID +test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE n_diff_pfx01 4 1 DB_ROW_ID test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index +test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE n_nonnull_pfx01 0 1 DB_ROW_ID test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE size 1 NULL Number of pages in the index connection con1; KILL QUERY @id; diff --git a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc.result b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc.result index 40eae0a938547..bc51a0535dadf 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc.result +++ b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc.result @@ -10,6 +10,9 @@ index_name PRIMARY stat_name n_leaf_pages stat_value 1 index_name PRIMARY +stat_name n_nonnull_pfx01 +stat_value 0 +index_name PRIMARY stat_name size stat_value 1 INSERT INTO autorecalc VALUES (1); @@ -25,6 +28,9 @@ index_name PRIMARY stat_name n_leaf_pages stat_value 1 index_name PRIMARY +stat_name n_nonnull_pfx01 +stat_value 0 +index_name PRIMARY stat_name size stat_value 1 DELETE FROM autorecalc; @@ -39,6 +45,9 @@ index_name PRIMARY stat_name n_leaf_pages stat_value 1 index_name PRIMARY +stat_name n_nonnull_pfx01 +stat_value 0 +index_name PRIMARY stat_name size stat_value 1 DROP TABLE autorecalc; diff --git a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_ddl.result b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_ddl.result index 8c68fe745042e..c0314528c000b 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_ddl.result +++ b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_ddl.result @@ -12,6 +12,9 @@ index_name PRIMARY stat_name n_leaf_pages stat_value 1 index_name PRIMARY +stat_name n_nonnull_pfx01 +stat_value 0 +index_name PRIMARY stat_name size stat_value 1 DROP TABLE arddl; @@ -29,6 +32,9 @@ index_name PRIMARY stat_name n_leaf_pages stat_value 1 index_name PRIMARY +stat_name n_nonnull_pfx01 +stat_value 0 +index_name PRIMARY stat_name size stat_value 1 DROP TABLE arddl; diff --git a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_on_nonexistent.result b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_on_nonexistent.result index 9a216374125f6..aec77b1277433 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_on_nonexistent.result +++ b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_on_nonexistent.result @@ -3,7 +3,7 @@ CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB; SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; COUNT(*) 1 SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; -COUNT(*) 3 +COUNT(*) 4 SELECT * FROM t; DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; @@ -16,14 +16,14 @@ SELECT * FROM t; SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; COUNT(*) 1 SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; -COUNT(*) 3 +COUNT(*) 4 DROP TABLE t; Test with explicit enable CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=1; SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; COUNT(*) 1 SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; -COUNT(*) 3 +COUNT(*) 4 SELECT * FROM t; DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; @@ -36,14 +36,14 @@ SELECT * FROM t; SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; COUNT(*) 1 SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; -COUNT(*) 3 +COUNT(*) 4 DROP TABLE t; Test with explicit disable CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=0; SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; COUNT(*) 1 SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; -COUNT(*) 3 +COUNT(*) 4 SELECT * FROM t; DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; diff --git a/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result b/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result index 385733e2c433d..553bbef7d180d 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result +++ b/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result @@ -25,6 +25,9 @@ innodb_stats_drop_locked innodb_stats_drop_locked innodb_stats_drop_locked innodb_stats_drop_locked +innodb_stats_drop_locked +innodb_stats_drop_locked +innodb_stats_drop_locked connect con1,localhost,root,,; SET innodb_lock_wait_timeout=1; ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key; @@ -58,6 +61,9 @@ innodb_stats_drop_locked innodb_stats_drop_locked innodb_stats_drop_locked innodb_stats_drop_locked +innodb_stats_drop_locked +innodb_stats_drop_locked +innodb_stats_drop_locked ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key; SELECT table_name FROM mysql.innodb_index_stats WHERE table_name='innodb_stats_drop_locked'; @@ -65,6 +71,7 @@ table_name innodb_stats_drop_locked innodb_stats_drop_locked innodb_stats_drop_locked +innodb_stats_drop_locked DROP TABLE innodb_stats_drop_locked; SELECT table_name FROM mysql.innodb_table_stats WHERE table_name='innodb_stats_drop_locked'; diff --git a/mysql-test/suite/innodb/r/innodb_stats_fetch.result b/mysql-test/suite/innodb/r/innodb_stats_fetch.result index a1194eb95cac9..d656890d10173 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_fetch.result +++ b/mysql-test/suite/innodb/r/innodb_stats_fetch.result @@ -36,6 +36,16 @@ stat_value 1 sample_size NULL stat_description Number of leaf pages in the index index_name PRIMARY +stat_name n_nonnull_pfx01 +stat_value 0 +sample_size 1 +stat_description a +index_name PRIMARY +stat_name n_nonnull_pfx02 +stat_value 0 +sample_size 1 +stat_description a,b +index_name PRIMARY stat_name size stat_value 1 sample_size NULL @@ -66,6 +76,26 @@ stat_value 1 sample_size NULL stat_description Number of leaf pages in the index index_name idx +stat_name n_nonnull_pfx01 +stat_value 0 +sample_size 1 +stat_description c +index_name idx +stat_name n_nonnull_pfx02 +stat_value 0 +sample_size 1 +stat_description c,d +index_name idx +stat_name n_nonnull_pfx03 +stat_value 0 +sample_size 1 +stat_description c,d,a +index_name idx +stat_name n_nonnull_pfx04 +stat_value 0 +sample_size 1 +stat_description c,d,a,b +index_name idx stat_name size stat_value 1 sample_size NULL diff --git a/mysql-test/suite/innodb/r/innodb_stats_rename_table.result b/mysql-test/suite/innodb/r/innodb_stats_rename_table.result index 20d82dff9ba0d..f8d5daa7fae04 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_rename_table.result +++ b/mysql-test/suite/innodb/r/innodb_stats_rename_table.result @@ -24,6 +24,10 @@ stat_name n_leaf_pages stat_value 1 table_name stats_rename_old index_name PRIMARY +stat_name n_nonnull_pfx01 +stat_value 0 +table_name stats_rename_old +index_name PRIMARY stat_name size stat_value 1 RENAME TABLE stats_rename_old TO stats_rename_new; @@ -45,6 +49,10 @@ stat_name n_leaf_pages stat_value 1 table_name stats_rename_new index_name PRIMARY +stat_name n_nonnull_pfx01 +stat_value 0 +table_name stats_rename_new +index_name PRIMARY stat_name size stat_value 1 DROP TABLE stats_rename_new; diff --git a/mysql-test/suite/innodb/r/innodb_stats_rename_table_if_exists.result b/mysql-test/suite/innodb/r/innodb_stats_rename_table_if_exists.result index a966f629d7ee2..96d3240c49c79 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_rename_table_if_exists.result +++ b/mysql-test/suite/innodb/r/innodb_stats_rename_table_if_exists.result @@ -44,6 +44,10 @@ stat_name n_leaf_pages stat_value 1 table_name stats_rename1 index_name PRIMARY +stat_name n_nonnull_pfx01 +stat_value 0 +table_name stats_rename1 +index_name PRIMARY stat_name size stat_value 1 table_name stats_rename1 @@ -56,6 +60,10 @@ stat_name n_leaf_pages stat_value 1 table_name stats_rename1 index_name b +stat_name n_nonnull_pfx01 +stat_value 0 +table_name stats_rename1 +index_name b stat_name size stat_value 1 table_name stats_rename2 @@ -68,6 +76,10 @@ stat_name n_leaf_pages stat_value 567 table_name stats_rename2 index_name PRIMARY +stat_name n_nonnull_pfx01 +stat_value 567 +table_name stats_rename2 +index_name PRIMARY stat_name size stat_value 567 table_name stats_rename2 @@ -80,6 +92,10 @@ stat_name n_leaf_pages stat_value 567 table_name stats_rename2 index_name b +stat_name n_nonnull_pfx01 +stat_value 567 +table_name stats_rename2 +index_name b stat_name size stat_value 567 RENAME TABLE stats_rename1 TO stats_rename2; @@ -114,6 +130,10 @@ stat_name n_leaf_pages stat_value 1 table_name stats_rename2 index_name PRIMARY +stat_name n_nonnull_pfx01 +stat_value 0 +table_name stats_rename2 +index_name PRIMARY stat_name size stat_value 1 table_name stats_rename2 @@ -126,6 +146,10 @@ stat_name n_leaf_pages stat_value 1 table_name stats_rename2 index_name c +stat_name n_nonnull_pfx01 +stat_value 0 +table_name stats_rename2 +index_name c stat_name size stat_value 1 DROP TABLE stats_rename2; diff --git a/mysql-test/suite/innodb/r/instant_alter_index_rename.result b/mysql-test/suite/innodb/r/instant_alter_index_rename.result index b1384df06368f..8ebbbbf03f5b9 100644 --- a/mysql-test/suite/innodb/r/instant_alter_index_rename.result +++ b/mysql-test/suite/innodb/r/instant_alter_index_rename.result @@ -208,14 +208,19 @@ SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats; table_name index_name stat_name t1 GEN_CLUST_INDEX n_diff_pfx01 t1 GEN_CLUST_INDEX n_leaf_pages +t1 GEN_CLUST_INDEX n_nonnull_pfx01 t1 GEN_CLUST_INDEX size t1 ind1 n_diff_pfx01 t1 ind1 n_diff_pfx02 t1 ind1 n_leaf_pages +t1 ind1 n_nonnull_pfx01 +t1 ind1 n_nonnull_pfx02 t1 ind1 size t1 ind2 n_diff_pfx01 t1 ind2 n_diff_pfx02 t1 ind2 n_leaf_pages +t1 ind2 n_nonnull_pfx01 +t1 ind2 n_nonnull_pfx02 t1 ind2 size ALTER TABLE t1 DROP INDEX ind2, ADD INDEX ind3(b), DROP INDEX ind1, ADD INDEX ind2(c); @@ -223,24 +228,32 @@ SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats; table_name index_name stat_name t1 GEN_CLUST_INDEX n_diff_pfx01 t1 GEN_CLUST_INDEX n_leaf_pages +t1 GEN_CLUST_INDEX n_nonnull_pfx01 t1 GEN_CLUST_INDEX size t1 ind2 n_diff_pfx01 t1 ind2 n_diff_pfx02 t1 ind2 n_leaf_pages +t1 ind2 n_nonnull_pfx01 +t1 ind2 n_nonnull_pfx02 t1 ind2 size t1 ind3 n_diff_pfx01 t1 ind3 n_diff_pfx02 t1 ind3 n_leaf_pages +t1 ind3 n_nonnull_pfx01 +t1 ind3 n_nonnull_pfx02 t1 ind3 size ALTER TABLE t1 DROP b, FORCE; SELECT table_name, index_name, stat_name FROM mysql.innodb_index_stats; table_name index_name stat_name t1 GEN_CLUST_INDEX n_diff_pfx01 t1 GEN_CLUST_INDEX n_leaf_pages +t1 GEN_CLUST_INDEX n_nonnull_pfx01 t1 GEN_CLUST_INDEX size t1 ind2 n_diff_pfx01 t1 ind2 n_diff_pfx02 t1 ind2 n_leaf_pages +t1 ind2 n_nonnull_pfx01 +t1 ind2 n_nonnull_pfx02 t1 ind2 size UPDATE t1 SET a = 1 WHERE c = 'foo'; DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/stats_method,NULLS_EQUAL.rdiff b/mysql-test/suite/innodb/r/stats_method,NULLS_EQUAL.rdiff new file mode 100644 index 0000000000000..a00888db873c4 --- /dev/null +++ b/mysql-test/suite/innodb/r/stats_method,NULLS_EQUAL.rdiff @@ -0,0 +1,11 @@ +--- stats_method.result 2025-03-10 15:30:38.087625820 +0530 ++++ stats_method.reject 2025-03-10 15:34:26.697129924 +0530 +@@ -19,7 +19,7 @@ + n_nonnull_pfx02 0 f1,f3 + n_nonnull_pfx03 0 f1,f3,DB_ROW_ID + size 19 Number of pages in the index +-n_diff_pfx01 16384 f3 ++n_diff_pfx01 1 f3 + n_diff_pfx02 16384 f3,DB_ROW_ID + n_leaf_pages 1 Number of leaf pages in the index + n_nonnull_pfx01 0 f3 diff --git a/mysql-test/suite/innodb/r/stats_method,NULLS_IGNORED.rdiff b/mysql-test/suite/innodb/r/stats_method,NULLS_IGNORED.rdiff new file mode 100644 index 0000000000000..aad09b2723b17 --- /dev/null +++ b/mysql-test/suite/innodb/r/stats_method,NULLS_IGNORED.rdiff @@ -0,0 +1,18 @@ +--- stats_method.result 2025-03-10 15:30:38.087625820 +0530 ++++ stats_method.reject 2025-03-10 15:35:21.741953192 +0530 +@@ -9,13 +9,13 @@ + stat_name stat_value stat_description + n_diff_pfx01 16341 DB_ROW_ID + n_leaf_pages 37 Number of leaf pages in the index +-n_nonnull_pfx01 0 DB_ROW_ID ++n_nonnull_pfx01 16378 DB_ROW_ID + size 97 Number of pages in the index + n_diff_pfx01 16384 f1 + n_diff_pfx02 16384 f1,f3 + n_diff_pfx03 16384 f1,f3,DB_ROW_ID + n_leaf_pages 1 Number of leaf pages in the index +-n_nonnull_pfx01 0 f1 ++n_nonnull_pfx01 16384 f1 + n_nonnull_pfx02 0 f1,f3 + n_nonnull_pfx03 0 f1,f3,DB_ROW_ID + size 19 Number of pages in the index diff --git a/mysql-test/suite/innodb/r/stats_method.result b/mysql-test/suite/innodb/r/stats_method.result new file mode 100644 index 0000000000000..e32b001abc953 --- /dev/null +++ b/mysql-test/suite/innodb/r/stats_method.result @@ -0,0 +1,28 @@ +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, +f3 INT, KEY(f1, f3), key(f3)) STATS_PERSISTENT=1,ENGINE=INNODB; +INSERT INTO t1 SELECT seq, seq, NULL from seq_1_to_16384; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +SELECT stat_name, stat_value, stat_description FROM mysql.innodb_index_stats where table_name="t1"; +stat_name stat_value stat_description +n_diff_pfx01 16341 DB_ROW_ID +n_leaf_pages 37 Number of leaf pages in the index +n_nonnull_pfx01 0 DB_ROW_ID +size 97 Number of pages in the index +n_diff_pfx01 16384 f1 +n_diff_pfx02 16384 f1,f3 +n_diff_pfx03 16384 f1,f3,DB_ROW_ID +n_leaf_pages 1 Number of leaf pages in the index +n_nonnull_pfx01 0 f1 +n_nonnull_pfx02 0 f1,f3 +n_nonnull_pfx03 0 f1,f3,DB_ROW_ID +size 19 Number of pages in the index +n_diff_pfx01 16384 f3 +n_diff_pfx02 16384 f3,DB_ROW_ID +n_leaf_pages 1 Number of leaf pages in the index +n_nonnull_pfx01 0 f3 +n_nonnull_pfx02 0 f3,DB_ROW_ID +size 15 Number of pages in the index +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/stats_method.combinations b/mysql-test/suite/innodb/t/stats_method.combinations new file mode 100644 index 0000000000000..fd4aa92fee9ef --- /dev/null +++ b/mysql-test/suite/innodb/t/stats_method.combinations @@ -0,0 +1,8 @@ +[NULLS_EQUAL] +--innodb_stats_method=nulls_equal + +[NULLS_UNEQUAL] +--innodb_stats_method=nulls_unequal + +[NULLS_IGNORED] +--innodb_stats_method=nulls_ignored diff --git a/mysql-test/suite/innodb/t/stats_method.test b/mysql-test/suite/innodb/t/stats_method.test new file mode 100644 index 0000000000000..9ecdc50b1a050 --- /dev/null +++ b/mysql-test/suite/innodb/t/stats_method.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc + +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, + f3 INT, KEY(f1, f3), key(f3)) STATS_PERSISTENT=1,ENGINE=INNODB; +INSERT INTO t1 SELECT seq, seq, NULL from seq_1_to_16384; +ANALYZE TABLE t1; +SELECT stat_name, stat_value, stat_description FROM mysql.innodb_index_stats where table_name="t1"; +DROP TABLE t1; diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index a1d354ca3b6c9..70e50baad46f7 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -960,10 +960,8 @@ btr_estimate_number_of_different_key_vals(dict_index_t* index, n_core, ULINT_UNDEFINED, &heap); - if (n_not_null != NULL) { - btr_record_not_null_field_in_rec( - n_cols, offsets_rec, n_not_null); - } + btr_record_not_null_field_in_rec( + n_cols, offsets_rec, n_not_null); } while (rec != page_get_supremum_rec(page)) { @@ -995,10 +993,8 @@ btr_estimate_number_of_different_key_vals(dict_index_t* index, n_diff[j]++; } - if (n_not_null != NULL) { - btr_record_not_null_field_in_rec( - n_cols, offsets_next_rec, n_not_null); - } + btr_record_not_null_field_in_rec( + n_cols, offsets_next_rec, n_not_null); total_external_size += btr_rec_get_externally_stored_len( @@ -1369,6 +1365,8 @@ dict_stats_analyze_index_level( ulint level, /*!< in: level */ ib_uint64_t* n_diff, /*!< out: array for number of distinct keys for all prefixes */ + ib_uint64_t* n_not_null, /*!< out: array for number of + non null keys for all prefixes */ ib_uint64_t* total_recs, /*!< out: total number of records */ ib_uint64_t* total_pages, /*!< out: total number of pages */ boundaries_t* n_diff_boundaries,/*!< out: boundaries of the groups @@ -1516,6 +1514,9 @@ dict_stats_analyze_index_level( (*total_recs)++; + btr_record_not_null_field_in_rec(n_uniq, rec_offsets, + n_not_null); + if (prev_rec != NULL) { ulint matched_fields; @@ -1526,7 +1527,9 @@ dict_stats_analyze_index_level( cmp_rec_rec(prev_rec, rec, prev_rec_offsets, rec_offsets, index, - false, &matched_fields); + (srv_innodb_stats_method + > SRV_STATS_NULLS_EQUAL), + &matched_fields); for (i = matched_fields; i < n_uniq; i++) { @@ -1694,6 +1697,8 @@ be big enough) @param[out] n_diff number of distinct records encountered @param[out] n_external_pages if this is non-NULL then it will be set to the number of externally stored pages which were encountered +@param[out] n_not_null number of non null value for + the given n_prefix key @return offsets1 or offsets2 (the offsets of *out_rec), or NULL if the page is empty and does not contain user records. */ UNIV_INLINE @@ -1707,7 +1712,8 @@ dict_stats_scan_page( ulint n_prefix, ulint n_core, ib_uint64_t* n_diff, - ib_uint64_t* n_external_pages) + ib_uint64_t* n_external_pages, + ib_uint64_t* n_not_null) { rec_offs* offsets_rec = offsets1; rec_offs* offsets_next_rec = offsets2; @@ -1753,6 +1759,8 @@ dict_stats_scan_page( *n_diff = 1; + if (n_not_null) *n_not_null = 1; + while (next_rec && next_rec != page_get_supremum_rec(page)) { ulint matched_fields; @@ -1765,7 +1773,9 @@ dict_stats_scan_page( /* check whether rec != next_rec when looking at the first n_prefix fields */ cmp_rec_rec(rec, next_rec, offsets_rec, offsets_next_rec, - index, false, &matched_fields); + index, + (srv_innodb_stats_method > SRV_STATS_NULLS_EQUAL), + &matched_fields); if (matched_fields < n_prefix) { /* rec != next_rec, => rec is non-boring */ @@ -1794,6 +1804,11 @@ dict_stats_scan_page( rec, offsets_rec); } + if (n_not_null && + !rec_offs_nth_sql_null(offsets_rec, n_prefix -1)) { + (*n_not_null)++; + } + next_rec = get_next(page, next_rec); } @@ -1812,6 +1827,7 @@ on the leaf page. when comparing records @param[out] n_diff number of distinct records @param[out] n_external_pages number of external pages +@param[out] n_not_null number of non null key values @return number of distinct records on the leaf page */ static void @@ -1819,7 +1835,8 @@ dict_stats_analyze_index_below_cur( const btr_cur_t* cur, ulint n_prefix, ib_uint64_t* n_diff, - ib_uint64_t* n_external_pages) + ib_uint64_t* n_external_pages, + ib_uint64_t* n_not_null) { dict_index_t* index; buf_block_t* block; @@ -1896,7 +1913,7 @@ dict_stats_analyze_index_below_cur( /* search for the first non-boring record on the page */ offsets_rec = dict_stats_scan_page( &rec, offsets1, offsets2, index, page, n_prefix, - 0, n_diff, NULL); + 0, n_diff, NULL, nullptr); /* pages on level > 0 are not allowed to be empty */ ut_a(offsets_rec != NULL); @@ -1942,7 +1959,7 @@ dict_stats_analyze_index_below_cur( offsets_rec = dict_stats_scan_page( &rec, offsets1, offsets2, index, page, n_prefix, index->n_core_fields, n_diff, - n_external_pages); + n_external_pages, n_not_null); #if 0 DEBUG_PRINTF(" %s(): n_diff below page_no=%lu: " UINT64PF "\n", @@ -1977,6 +1994,9 @@ struct n_diff_data_t { /** Number of different key values that were found on the mid level. */ ib_uint64_t n_diff_on_level; + /** Number of non null key values that were found on the mid level */ + ib_uint64_t n_not_null_on_level; + /** Number of leaf pages that are analyzed. This is also the same as the number of records that we pick from the mid level and dive below them. */ @@ -1989,6 +2009,9 @@ struct n_diff_data_t { /** Cumulative sum of the number of external pages (stored outside of the btree but in the same file segment). */ ib_uint64_t n_external_pages_sum; + + /** Number of non-null key values found on leaf pages */ + ib_uint64_t n_not_null_on_leaf; }; /** Estimate the number of different key values in an index when looking at @@ -2036,6 +2059,7 @@ dict_stats_analyze_index_for_n_prefix( n_diff_data->n_diff_all_analyzed_pages = 0; n_diff_data->n_external_pages_sum = 0; + n_diff_data->n_not_null_on_leaf= 0; if (btr_pcur_open_level(&pcur, n_diff_data->level, mtr, index) != DB_SUCCESS @@ -2143,11 +2167,17 @@ dict_stats_analyze_index_for_n_prefix( ib_uint64_t n_diff_on_leaf_page; ib_uint64_t n_external_pages; + ib_uint64_t n_not_null_on_leaf_page = 0; + bool calc_non_null = + (srv_innodb_stats_method == SRV_STATS_NULLS_IGNORED); dict_stats_analyze_index_below_cur(btr_pcur_get_btr_cur(&pcur), n_prefix, &n_diff_on_leaf_page, - &n_external_pages); + &n_external_pages, + (calc_non_null + ? &n_not_null_on_leaf_page + : nullptr)); /* We adjust n_diff_on_leaf_page here to avoid counting one value twice - once as the last on some page and once @@ -2170,6 +2200,9 @@ dict_stats_analyze_index_for_n_prefix( n_diff_data->n_diff_all_analyzed_pages += n_diff_on_leaf_page; n_diff_data->n_external_pages_sum += n_external_pages; + + if (calc_non_null) + n_diff_data->n_not_null_on_leaf += n_not_null_on_leaf_page; } } @@ -2257,6 +2290,15 @@ dict_stats_index_set_n_diff( * data->n_diff_all_analyzed_pages / data->n_leaf_pages_to_analyze; + index_stats.stats[n_prefix - 1].n_non_null_key_vals + = n_ordinary_leaf_pages + + * data->n_not_null_on_level + / data->n_recs_on_level + + * data->n_not_null_on_leaf + / data->n_leaf_pages_to_analyze; + index_stats.stats[n_prefix - 1].n_sample_sizes = data->n_leaf_pages_to_analyze; @@ -2333,6 +2375,8 @@ static index_stats_t dict_stats_analyze_index(dict_index_t* index) mtr.commit(); + bool calc_non_null = (srv_innodb_stats_method + == SRV_STATS_NULLS_IGNORED); mtr.start(); mtr_sx_lock_index(index, &mtr); @@ -2364,6 +2408,9 @@ static index_stats_t dict_stats_analyze_index(dict_index_t* index) dict_stats_analyze_index_level(index, 0 /* leaf level */, index->stat_n_diff_key_vals, + calc_non_null + ? index->stat_n_non_null_key_vals + : nullptr, &total_recs, &total_pages, NULL /* boundaries not needed */, @@ -2388,6 +2435,16 @@ static index_stats_t dict_stats_analyze_index(dict_index_t* index) ib_uint64_t* n_diff_on_level = UT_NEW_ARRAY( ib_uint64_t, n_uniq, mem_key_dict_stats_n_diff_on_level); + ib_uint64_t* n_not_null_on_level = nullptr; + + if (calc_non_null) { + n_not_null_on_level = + UT_NEW_ARRAY(ib_uint64_t, n_uniq, + mem_key_dict_stats_n_nonnull_on_level); + for (ulint i=0; i < n_uniq; i++) + n_not_null_on_level[i] = 0; + } + /* For each level that is being scanned in the btree, this contains the index of the last record from each group of equal records (when comparing only the first n columns, n=1..n_uniq). */ @@ -2508,6 +2565,7 @@ static index_stats_t dict_stats_analyze_index(dict_index_t* index) dict_stats_analyze_index_level(index, level, n_diff_on_level, + n_not_null_on_level, &total_recs, &total_pages, n_diff_boundaries, @@ -2558,6 +2616,11 @@ static index_stats_t dict_stats_analyze_index(dict_index_t* index) data->n_diff_on_level = n_diff_on_level[n_prefix - 1]; + data->n_not_null_on_level = + (n_not_null_on_level + ? n_not_null_on_level[n_prefix -1] + : 0); + data->n_leaf_pages_to_analyze = std::min( N_SAMPLE_PAGES(index), n_diff_on_level[n_prefix - 1]); @@ -3040,6 +3103,34 @@ dberr_t dict_stats_save(dict_table_t* table, index_id_t index_id) if (ret != DB_SUCCESS) { goto rollback_and_exit; } + + /* Update n_nonnull_pfx */ + snprintf(stat_name, sizeof(stat_name), + "n_nonnull_pfx%02u", i + 1); + + snprintf(stat_description, + sizeof(stat_description), + "%s", index->fields[0].name()); + + for (unsigned j = 1; j <= i; j++) { + size_t len; + + len = strlen(stat_description); + + snprintf(stat_description + len, + sizeof(stat_description) - len, + ",%s", index->fields[j].name()); + } + + ret = dict_stats_save_index_stat( + index, now, stat_name, + index->stat_n_non_null_key_vals[i], + &index->stat_n_sample_sizes[i], + stat_description, trx); + + if (ret != DB_SUCCESS) { + goto rollback_and_exit; + } } ret = dict_stats_save_index_stat(index, now, "n_leaf_pages", @@ -3168,6 +3259,35 @@ struct index_fetch_t { least one index stats were modified */ }; +/* Print the error while fetching the stats from innodb_index_stats +@param index stats to be fetched for index +@param stat_name statistics field name +@param stat_name_len length of the stats field +@param out_of_bound Out of bound error */ +static void dict_stats_fetch_print_error(dict_index_t *index, + const char* stat_name, + ulint stat_name_len, + bool out_of_bound=false) +{ + dict_table_t *table= index->table; + char db_utf8[MAX_DB_UTF8_LEN]; + char table_utf8[MAX_TABLE_UTF8_LEN]; + dict_fs2utf8(table->name.m_name, db_utf8, sizeof(db_utf8), + table_utf8, sizeof(table_utf8)); + ib::info out; + out << "Ignoring strange row from "<< INDEX_STATS_NAME_PRINT + << " WHERE database_name = '" << db_utf8 + << "' AND table_name = '" << table_utf8 + << "' AND index_name = '" << index->name() + << "' AND stat_name = '"; + out.write(stat_name, stat_name_len); + if (out_of_bound) + out << "'; because stat_name is out of range, the index has " + << index->n_uniq << " unique columns"; + else + out << "'; because stat_name is malformed"; +} + /*********************************************************************//** Called for the rows that are selected by SELECT ... FROM mysql.innodb_index_stats WHERE table='...' @@ -3319,6 +3439,8 @@ dict_stats_fetch_index_stats_step( #define PFX "n_diff_pfx" #define PFX_LEN 10 + const char *non_null_pfx = "n_not_null_pfx"; + size_t non_null_len = strlen(non_null_pfx); if (stat_name_len == 4 /* strlen("size") */ && strncasecmp("size", stat_name, stat_name_len) == 0) { @@ -3344,23 +3466,9 @@ dict_stats_fetch_index_stats_step( || num_ptr[0] < '0' || num_ptr[0] > '9' || num_ptr[1] < '0' || num_ptr[1] > '9') { - char db_utf8[MAX_DB_UTF8_LEN]; - char table_utf8[MAX_TABLE_UTF8_LEN]; - - dict_fs2utf8(table->name.m_name, - db_utf8, sizeof(db_utf8), - table_utf8, sizeof(table_utf8)); - - ib::info out; - out << "Ignoring strange row from " - << INDEX_STATS_NAME_PRINT << " WHERE" - " database_name = '" << db_utf8 - << "' AND table_name = '" << table_utf8 - << "' AND index_name = '" << index->name() - << "' AND stat_name = '"; - out.write(stat_name, stat_name_len); - out << "'; because stat_name is malformed"; - return(TRUE); + dict_stats_fetch_print_error(index, stat_name, + stat_name_len); + return true; } /* else */ @@ -3372,25 +3480,10 @@ dict_stats_fetch_index_stats_step( if (n_pfx == 0 || n_pfx > n_uniq) { - char db_utf8[MAX_DB_UTF8_LEN]; - char table_utf8[MAX_TABLE_UTF8_LEN]; - - dict_fs2utf8(table->name.m_name, - db_utf8, sizeof(db_utf8), - table_utf8, sizeof(table_utf8)); - - ib::info out; - out << "Ignoring strange row from " - << INDEX_STATS_NAME_PRINT << " WHERE" - " database_name = '" << db_utf8 - << "' AND table_name = '" << table_utf8 - << "' AND index_name = '" << index->name() - << "' AND stat_name = '"; - out.write(stat_name, stat_name_len); - out << "'; because stat_name is out of range, the index" - " has " << n_uniq << " unique columns"; - - return(TRUE); + dict_stats_fetch_print_error(index, stat_name, + stat_name_len, + true); + return true; } /* else */ @@ -3405,9 +3498,30 @@ dict_stats_fetch_index_stats_step( index->stat_n_sample_sizes[n_pfx - 1] = 0; } - index->stat_n_non_null_key_vals[n_pfx - 1] = 0; + arg->stats_were_modified = true; + } else if (stat_name_len > non_null_len + && strncasecmp(non_null_pfx, stat_name, + non_null_len) == 0) { + const char *num_ptr = stat_name + non_null_len; + if (stat_name_len != non_null_len + 2 + || num_ptr[0] < '0' || num_ptr[0] > '9' + || num_ptr[1] < '0' || num_ptr[1] > '9') { + dict_stats_fetch_print_error(index, stat_name, + stat_name_len); + return true; + } + + ulong n_pfx = ulong(num_ptr[0] - '0') * 10 + + ulong(num_ptr[1] - '0'); + if (n_pfx == 0 || n_pfx > index->n_uniq) { + dict_stats_fetch_print_error(index, stat_name, + stat_name_len, + true); + return true; + } arg->stats_were_modified = true; + index->stat_n_non_null_key_vals[n_pfx - 1] = stat_value; } else { /* silently ignore rows with unknown stat_name, the user may have developed her own stats */ diff --git a/storage/innobase/include/ut0new.h b/storage/innobase/include/ut0new.h index 3ff5f8853e0fe..8763cbe29b8dd 100644 --- a/storage/innobase/include/ut0new.h +++ b/storage/innobase/include/ut0new.h @@ -169,6 +169,7 @@ extern PSI_memory_key mem_key_buf_buf_pool; extern PSI_memory_key mem_key_dict_stats_bg_recalc_pool_t; extern PSI_memory_key mem_key_dict_stats_index_map_t; extern PSI_memory_key mem_key_dict_stats_n_diff_on_level; +extern PSI_memory_key mem_key_dict_stats_n_nonnull_on_level; extern PSI_memory_key mem_key_other; extern PSI_memory_key mem_key_row_log_buf; extern PSI_memory_key mem_key_row_merge_sort; diff --git a/storage/innobase/ut/ut0new.cc b/storage/innobase/ut/ut0new.cc index a3ce1bdf3c767..bcf2cd94d63fd 100644 --- a/storage/innobase/ut/ut0new.cc +++ b/storage/innobase/ut/ut0new.cc @@ -42,6 +42,7 @@ PSI_memory_key mem_key_buf_buf_pool; PSI_memory_key mem_key_dict_stats_bg_recalc_pool_t; PSI_memory_key mem_key_dict_stats_index_map_t; PSI_memory_key mem_key_dict_stats_n_diff_on_level; +PSI_memory_key mem_key_dict_stats_n_nonnull_on_level; PSI_memory_key mem_key_other; PSI_memory_key mem_key_row_log_buf; PSI_memory_key mem_key_row_merge_sort; @@ -69,6 +70,7 @@ static PSI_memory_info pfs_info[] = { {&mem_key_dict_stats_bg_recalc_pool_t, "dict_stats_bg_recalc_pool_t", 0}, {&mem_key_dict_stats_index_map_t, "dict_stats_index_map_t", 0}, {&mem_key_dict_stats_n_diff_on_level, "dict_stats_n_diff_on_level", 0}, + {&mem_key_dict_stats_n_nonnull_on_level, "dict_stats_n_nonnull_on_level", 0}, {&mem_key_other, "other", 0}, {&mem_key_row_log_buf, "row_log_buf", 0}, {&mem_key_row_merge_sort, "row_merge_sort", 0},