[MDEV-32690] After CREATE INDEX, InnoDB reports the index length as 0 if STATS_PERSISTENT=0 Created: 2023-11-06  Updated: 2023-12-11

Status: Confirmed
Project: MariaDB Server
Component/s: Server, Storage Engine - InnoDB
Affects Version/s: 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9, 10.10, 10.11, 11.0, 11.1, 11.2
Fix Version/s: 10.4

Type: Bug Priority: Major
Reporter: Marko Mäkelä Assignee: Sergei Golubchik
Resolution: Unresolved Votes: 0
Labels: upstream

Issue Links:
Relates
relates to MDEV-13626 Merge InnoDB test cases from MySQL 5.7 Closed
relates to MDEV-32785 background innodb stats recalculation... Open

 Description   

While working on MDEV-13626, I found the following (based on the MySQL test innodb.index_length):

--source include/have_innodb.inc
--source include/have_innodb_16k.inc
--source include/have_sequence.inc
CREATE TABLE t1(a INT PRIMARY KEY, b varchar(1024))
ENGINE=InnoDB STATS_PERSISTENT=1;
INSERT INTO t1 SELECT seq,repeat('b',1024) FROM seq_1_to_16384;
 
SELECT INDEX_LENGTH from information_schema.TABLES WHERE
TABLE_SCHEMA = 'test' AND TABLE_NAME = 't1';
ALTER TABLE t1 add INDEX b (b(800));
SELECT INDEX_LENGTH from information_schema.TABLES WHERE
TABLE_SCHEMA = 'test' AND TABLE_NAME = 't1';
ALTER TABLE t1 add INDEX ba (b(800),a);
SELECT INDEX_LENGTH from information_schema.TABLES WHERE
TABLE_SCHEMA = 'test' AND TABLE_NAME = 't1';
DROP TABLE t1;

The test is expected to report the INFORMATION_SCHEMA.TABLES.INDEX_LENGTH as 0, 17809408, and 35618816. Because the table is created with STATS_PERSISTENT=0 (in MariaDB 10.0 to 10.5 by default due to MDEV-4750), we will be always reporting INDEX_LENGTH as 0. This is fixed by removing a condition:

diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 6fe40c75555..90b344ee3ac 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -331,14 +331,12 @@ dict_table_close(
 
 	const bool last_handle = table->release();
 
-	/* Force persistent stats re-read upon next open of the table
+	/* Force statistics re-read upon next open of the table
 	so that FLUSH TABLE can be used to forcibly fetch stats from disk
 	if they have been manually modified. We reset table->stat_initialized
 	only if table reference count is 0 because we do not want too frequent
 	stats re-reads (e.g. in other cases than FLUSH TABLE). */
-	if (last_handle && strchr(table->name.m_name, '/') != NULL
-	    && dict_stats_is_persistent_enabled(table)) {
-
+	if (last_handle && strchr(table->name.m_name, '/')) {
 		dict_stats_deinit(table);
 	}
 



 Comments   
Comment by Marko Mäkelä [ 2023-11-06 ]

Unfortunately, applying the patch would break many other tests. It would be more robust to implement that FLUSH TABLES logic somewhere at a higher level.

Comment by Marko Mäkelä [ 2023-12-11 ]

To fix this bug, we would seem to need a storage engine handlerton interface that would be invoked by FLUSH TABLES (or some other statement that would cause the persistent statistics of all InnoDB tables to be reloaded). I was only able to find handlerton::flush_logs, which is invoked by FLUSH ENGINE LOGS.

Generated at Thu Feb 08 10:33:15 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.