Through a case, the author explains in detail the relevant parameters and usage of the MySQL 8.0 field information statistics mechanism.
Author: Yang Qilong
Net name "North in the South", senior DBA, mainly responsible for database architecture design and operation and maintenance platform development, good at database performance tuning and fault diagnosis.
Source of this article: original contribution
Produced by the Aikesheng open source community, the original content is not allowed to be used without authorization, please contact the editor and indicate the source for reprinting.
background
A few days ago, a colleague was asking a question: a certain business INFORMATION_SCHEMA
inserts data into the table based on the information (such as the maximum value) of the statistical table.
May I ask INFORMATION_SCHEMA.TABLES
if AUTO_INCREMENT
the will be updated in time?
Let me talk about the conclusion first: yes!
This involves the information statistics mechanism or the frequency problem, which is mainly
information_schema_stats_expiry
controlled by parameters.
Basic logic of table information update
By default, MySQL will efficiently retrieve the cached values of these columns from the system tables mysql.index_stats
and mysql.table_stats
instead of obtaining statistics directly from the storage engine. If cached statistics are not available or have expired, MySQL retrieves the latest statistics from the storage engine and updates and caches their statistics in the mysql.index_stats
and mysql.table_stats
dictionary tables. Subsequent queries will retrieve cached statistics until the cached statistics expire.
It is worth noting that: MySQL restart or opening for the first time mysql.index_stats
and mysql.table_stats
table will not automatically update the cached statistics.
Core parameters
Core parameters information_schema_stats_expiry
The default is 86400 seconds. That is to say, the relevant statistical information is automatically collected every other day to information_schema
the following table fields in :
STATISTICS.CARDINALITY
TABLES.AUTO_INCREMENT
TABLES.AVG_ROW_LENGTH
TABLES.CHECKSUM
TABLES.CHECK_TIME
TABLES.CREATE_TIME
TABLES.DATA_FREE
TABLES.DATA_LENGTH
TABLES.INDEX_LENGTH
TABLES.MAX_DATA_LENGTH
TABLES.TABLE_ROWS
TABLES.UPDATE_TIME
The value of the parameter information_schema_stats_expiry
determines the time interval for collecting table statistics again, and the default is 86400 seconds. If it is set to 0, it means that the statistics information will be updated in real time , which will definitely affect some performance.
Querying statistics columns does not store or update statistics in mysql.index_stats
and dictionary tables in the following cases:mysql.table_stats
- When cached statistics have not yet expired.
- When
information_schema_stas_expiry
set to 0. - When the MySQL server is in read-only, super read-only, transactional read-only or
innodb_read_only
mode. - When querying also fetches
Performance Schema
data from .
information_schema_stas_experity
Both global and session levels are supported, and each session can define its own expiration value. Statistics retrieved from the storage engine and cached by one session are available to other sessions.
test
This article takes MySQL 8.0.30 as an example for analysis.
2.1 Test preparation
CREATE TABLE `sbtest1` (
`id` int NOT NULL AUTO_INCREMENT,
`k` int NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB ;
2.2 Testing
View the current information information_schema.tables
in , the maximum value is 1200006, and the maximum value of self-increment in the table structure definition is also 1200006.sbtest1
master [localhost:22031] {msandbox} (test) > show variables like 'information_schema_stats_expiry' ;
+-----------------------------------------+---------+
| Variable_name | Value |
+-----------------------------------------+---------+
| information_schema_stats_expiry | 86400 |
+-----------------------------------------+---------+
1 row in set (0.02 sec)
master [localhost:22031] {msandbox} (test) > select table_name, AUTO_INCREMENT from information_schema.tables where table_name='sbtest1';
+---------------+--------------------+
| TABLE_NAME | AUTO_INCREMENT |
+---------------+--------------------+
| sbtest1 | 1200006 |
+---------------+--------------------+
1 row in set (0.01 sec)
master [localhost:22031] {msandbox} (test) > show create table sbtest1 \G
*************************** 1. row ***************************
Table: sbtest1
Create Table: CREATE TABLE `sbtest1` (
`id` int NOT NULL AUTO_INCREMENT,
`k` int NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1200006 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
Insert new data, increment by 1.
master [localhost:22031] {msandbox} (test) > insert into sbtest1(k,c,pad) values(1,'c','cc');
Query OK, 1 row affected (0.00 sec)
master [localhost:22031] {msandbox} (test) > show create table sbtest1 \G
*************************** 1. row ***************************
Table: sbtest1
Create Table: CREATE TABLE `sbtest1` (
`id` int NOT NULL AUTO_INCREMENT,
`k` int NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1200007 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
But information_schema.tables
the value in did not change.
master [localhost:22031] {msandbox} (test) > select table_name, AUTO_INCREMENT from information_schema.tables where table_name='sbtest1';
+------------+----------------+
| TABLE_NAME | AUTO_INCREMENT |
+------------+----------------+
| sbtest1 | 1200006 |
+------------+----------------+
1 row in set (0.00 sec)
Set to update in real time
Modify information_schema_stats_expiry
to 0.
master [localhost:22031] {msandbox} (test) > set information_schema_stats_expiry=0;
Query OK, 0 rows affected (0.00 sec)
master [localhost:22031] {msandbox} (test) > show variables like 'information_schema_stats_expiry' ;
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| information_schema_stats_expiry | 0 |
+---------------------------------+-------+
1 row in set (0.00 sec)
master [localhost:22031] {msandbox} (test) > select table_name, AUTO_INCREMENT from information_schema.tables where table_name='sbtest1';
+------------+----------------+
| TABLE_NAME | AUTO_INCREMENT |
+------------+----------------+
| sbtest1 | 1200007 |
+------------+----------------+
1 row in set (0.00 sec)
master [localhost:22031] {msandbox} (test) > show create table sbtest1 \G
*************************** 1. row ***************************
Table: sbtest1
Create Table: CREATE TABLE `sbtest1` (
`id` int NOT NULL AUTO_INCREMENT,
`k` int NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1200007 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
The inserted data is automatically incremented by 1, and the statistics of the auto-increment columninformation_schema.tables
in the query are also updated in real time.
master [localhost:22031] {msandbox} (test) > insert into sbtest1(k,c,pad) values(1,'c','cc');
Query OK, 1 row affected (0.00 sec)
master [localhost:22031] {msandbox} (test) > select table_name, AUTO_INCREMENT from information_schema.tables where table_name='sbtest1';
+------------+----------------+
| TABLE_NAME | AUTO_INCREMENT |
+------------+----------------+
| sbtest1 | 1200008 |
+------------+----------------+
1 row in set (0.00 sec)
master [localhost:22031] {msandbox} (test) > show create table sbtest1 \G
*************************** 1. row ***************************
Table: sbtest1
Create Table: CREATE TABLE `sbtest1` (
`id` int NOT NULL AUTO_INCREMENT,
`k` int NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1200008 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
Manually modifying the auto-increment column can also be updated in real time.
master [localhost:22031] {msandbox} (test) > alter table sbtest1 AUTO_INCREMENT=1200010;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
master [localhost:22031] {msandbox} (test) > select table_name, AUTO_INCREMENT from information_schema.tables where table_name='sbtest1';
+------------+----------------+
| TABLE_NAME | AUTO_INCREMENT |
+------------+----------------+
| sbtest1 | 1200010 |
+------------+----------------+
1 row in set (0.00 sec)
summary
MySQL 8.0 provides more technical features to support the statistical information of table fields. The duration of statistical validity and the histogram of the field itself are more and more convenient to use.
Looking back at this requirement, in fact, if it is business monitoring or database monitoring information, such as whether the maximum value of the primary key of the monitoring table overflows, the more practical suggestion is to query the maximum value of the specific table. It is more practical and the query frequency is controllable id
.
For more technical articles, please visit: https://opensource.actionsky.com/
About SQLE
The SQLE of the Akson open source community is a SQL auditing tool for database users and managers, which supports multi-scenario auditing, supports standardized online processes, natively supports MySQL auditing, and has scalable database types.
SQLE get
type | address |
---|---|
Repository | https://github.com/actiontech/sqle |
document | https://actiontech.github.io/sqle-docs/ |
release news | https://github.com/actiontech/sqle/releases |
Data audit plug-in development documentation | https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse |