Bug #102079 Handler_* counters are not incremented for parallel COUNT(*)
Description:
The handler_ status counters are used for monitoring, for example, to detect full table scans, but these counters are not incremented when a COUNT(*) without a WHERE clause is used on an InnoDB table in MySQL 8.
I imagine this problem is related to the optimized COUNT(*) implementation that is used for InnoDB (parallel implementation) on MySQL 8. When MyISAM uses fast count(*) it does not read from the table, so it shouldn't increment status counters for COUNT(*) w/out a WHERE clause. InnoDB, however, still does read from the table, but the counters are not updated.
How to repeat:
mysql> drop database if exists test;
Query OK, 1 row affected (0.56 sec)
mysql> create database test;
Query OK, 1 row affected (0.00 sec)
mysql> use test;
Database changed
mysql> create table handler_test(c1 int primary key) engine=innodb;
Query OK, 0 rows affected (0.15 sec)
mysql> insert into handler_test values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
Query OK, 10 rows affected (0.01 sec)
Records: 10 Duplicates: 0 Warnings: 0
mysql> flush status;
Query OK, 0 rows affected (0.00 sec)
-- should increment status variables (faster count(*) does read rows!)
mysql> select count(*) from handler_test;
+----------+
| count(*) |
+----------+
| 10 |
+----------+
1 row in set (0.00 sec)
-- status variables are not changed
mysql> show session status like '%handler%read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 0 |
| Handler_read_last | 0 |
| Handler_read_next | 0 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
7 rows in set (0.02 sec)
-- should increment status variables
mysql> select count(*) from handler_test where c1 > 0;
+----------+
| count(*) |
+----------+
| 10 |
+----------+
1 row in set (0.00 sec)
-- status variables ARE incremented
mysql> show session status like '%handler%read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 1 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 10 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
7 rows in set (0.02 sec)
mysql> alter table handler_test engine=myisam;
Query OK, 10 rows affected (0.05 sec)
Records: 10 Duplicates: 0 Warnings: 0
mysql> flush status;
Query OK, 0 rows affected (0.00 sec)
-- status variables SHOULD NOT incremented (fast count(*) reads no rows)
mysql> select count(*) from handler_test;
+----------+
| count(*) |
+----------+
| 10 |
+----------+
1 row in set (0.00 sec)
-- results are correct
mysql> show session status like '%handler%read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 0 |
| Handler_read_last | 0 |
| Handler_read_next | 0 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
7 rows in set (0.02 sec)
-- should increment status variables
mysql> select count(*) from handler_test where c1 > 0;
+----------+
| count(*) |
+----------+
| 10 |
+----------+
1 row in set (0.00 sec)
-- status variables ARE incremented
mysql> show session status like '%handler%read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 1 |
| Handler_read_key | 0 |
| Handler_read_last | 0 |
| Handler_read_next | 10 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
7 rows in set (0.02 sec)
Suggested fix:
Increment the status counters in InnoDB parallel count(*) implementation, since rows are actually read.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.040 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.