MySQL "Show table status", auto increment is not correct - mysql

I create a new table in Mysql, add some rows, yet the Auto_increment field of show tables still returns NULL.
The mysql manual says: this field should return: "The next Auto_increment value"
https://dev.mysql.com/doc/refman/8.0/en/show-table-status.html
What am I doing wrong?
How can I find the next auto_increment value correctly?
Steps to reproduce:
create table `test` (
`id` int(5) not null auto_increment,
`name` varchar(256),
PRIMARY KEY(`id`)
);
Then I run :
show table status where name like 'test';
Result:
Name, Engine, Version, ..., Auto_increment, ...
'test', 'InnoDB', '10', ..., NULL, ...
Then I run:
insert into test values(null,'name1');
insert into test values(null,'name2');
insert into test values(null,'name3');
Edit: -other insert syntax-
insert into test (name) values('name4');
insert into test (name) values('name5');
insert into test (name) values('name6');
Fetch the status of the table
show table status where name like 'test';
Result
Name, Engine, Version, ..., Auto_increment, ...
'test', 'InnoDB', '10', ..., NULL, ...
Data in the table
select * from test;
Result:
1 name1
2 name2
3 name3
For your information:
SHOW VARIABLES LIKE "%version%";
Result:
'innodb_version', '8.0.12'
'protocol_version', '10'
'slave_type_conversions', ''
'tls_version', 'TLSv1,TLSv1.1,TLSv1.2'
'version', '8.0.12'
'version_comment', 'MySQL Community Server - GPL'
'version_compile_machine', 'x86_64'
'version_compile_os', 'Win64'
'version_compile_zlib', '1.2.11'
edit:
autocommit:
SHOW VARIABLES LIKE "autocommit";
result:
'autocommit', 'ON'
Edit:
After a while it automagically starts working. No clear reason how to make it start working.

It's a feature.. not a bug.
The table statistics are cached. To disable the cache and always have the latest version you should change the server variable that indicates the duration of the cache-clear to 0:
SET PERSIST information_schema_stats_expiry = 0
The default value of this property has changed to 86400 (24 hours) in Mysql 8.x
Example:
SET PERSIST information_schema_stats_expiry = 86400
-- 86400 is the default value of mysql 8.x if you have never changed this you don't need to set this
show variables like 'information_schema_stats_expiry';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| information_schema_stats_expiry | 86400 |
+---------------------------------+-------+
create schema mytest;
create table `test` (
`id` int(5) not null auto_increment,
`name` varchar(256),
PRIMARY KEY(`id`)
);
insert into test values(null,'name1')
insert into test values(null,'name2')
insert into test values(null,'name3')
show table status where name like 'test';
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| test | InnoDB | 10 | Dynamic | 3 | 5461 | 16384 | 0 | 0 | 0 | 4 | 2018-10-09 15:32:15 | 2018-10-09 15:32:16 | NULL | utf8mb4_0900_ai_ci | NULL | | |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
-- The Auto_increment field is correctly set to 4.. but is now cached.
insert into test values(null,'name3');
show table status where name like 'test';
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| test | InnoDB | 10 | Dynamic | 3 | 5461 | 16384 | 0 | 0 | 0 | 4 | 2018-10-09 15:32:15 | 2018-10-09 15:32:16 | NULL | utf8mb4_0900_ai_ci | NULL | | |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
-- The Auto_increment is still 4 (it was cached).
drop schema mytest
Now we change the configuration:
SET PERSIST information_schema_stats_expiry = 0
and we run the same test:
show variables like 'information_schema_stats_expiry'
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| information_schema_stats_expiry | 0 |
+---------------------------------+-------+
create schema mytest;
create table `test` (
`id` int(5) not null auto_increment,
`name` varchar(256),
PRIMARY KEY(`id`)
);
insert into test values(null,'name1');
insert into test values(null,'name2');
insert into test values(null,'name3');
show table status where name like 'test';
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| test | InnoDB | 10 | Dynamic | 3 | 5461 | 16384 | 0 | 0 | 0 | 4 | 2018-10-09 15:32:49 | 2018-10-09 15:32:49 | NULL | utf8mb4_0900_ai_ci | NULL | | |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
-- Auto_increment is 4, but the result is not cached!
insert into test values(null,'name3');
show table status where name like 'test';
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| test | InnoDB | 10 | Dynamic | 4 | 4096 | 16384 | 0 | 0 | 0 | 5 | 2018-10-09 15:32:49 | 2018-10-09 15:32:49 | NULL | utf8mb4_0900_ai_ci | NULL | | |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
-- The Auto_increment field is now 5 (a correct, not cached value)
drop schema mytest;

Related

MySQL - i dont see data, but mysql says, that there are rows

I have table ip_per_nat_vlan, innodb format. When I give truncate table, table is empty.
Then I have php script, which fill data into this table.
When is this script finished without errors (simple insert statemets) situation is following:
select * from ip_per_nat_vlan;
Empty set (0.00 sec)
.
select count(*) from ip_per_nat_vlan;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
.
show table status;
+----------------------------------+--------+---------+------------+----------+----------------+-------------+-----------------+--------------+------------+----------------+---------------------+---------------------+------------+-----------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+----------------------------------+--------+---------+------------+----------+----------------+-------------+-----------------+--------------+------------+----------------+---------------------+---------------------+------------+-----------------+----------+----------------+---------+
| ip_per_nat_vlan | InnoDB | 10 | Dynamic | 141291 | 100 | 14172160 | 0 | 6832128 | 25165824 | 143563 | 2017-12-24 16:26:40 | 2018-06-13 09:01:33 | NULL | utf8_unicode_ci | NULL |
MySQL says, that there should be 14172160 rows, but I dont see any. Where could be a problem? Transactions? But I dont see any running thread and no any fault.
Thank you. D
Structure of table is:
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| ipAddress | varchar(255) | NO | UNI | NULL | |
| nat | int(11) | NO | | NULL | |
| vlan | int(11) | NO | | NULL | |
| district | varchar(255) | YES | | NULL | |
| idOblasti | int(11) | YES | | NULL | |
| type | varchar(255) | NO | | NULL | |
| macAddress | varchar(255) | NO | | NULL | |
+------------+--------------+------+-----+---------+----------------+
There are various ways to "count" rows in a table.
The normal way. Just count them.
select count(*) as table_rows from table_name ;
Accuracy: 100% accurate count at the time of the query is run.
using the information_schema tables
select table_rows
from information_schema.tables
where table_schema = 'database_name'
and table_name = 'table_name' ;
Accuracy: Only an approximation. If the table is the target of frequent inserts and deletes, the result can be way off the actual count. This can be improved by running ANALYZE TABLE more often.
Efficiency: Very good, it doesn't touch the table at all.
As count option is 100% accurate, your table doesn't contain any data.
Check your code and default commit option of MySQL.
Looks like you are inserting rows, but not committing them, check your index length.
Check more details here
https://dba.stackexchange.com/questions/151769/mysql-difference-between-using-count-and-information-schema-tables-for-coun
First thing, I am not sure how mysql run this line and produce the result
select count() from ip_per_nat_vlan
count() will return [Err] 1064.
count(*) or else a field name should be mentioned inside.

How can we verify an internal index is created for a relation?

From https://stackoverflow.com/a/51181742/3284469
If the table has no PRIMARY KEY or suitable UNIQUE index, InnoDB
internally generates a hidden clustered index named GEN_CLUST_INDEX on
a synthetic column containing row ID values. The rows are ordered by
the ID that InnoDB assigns to the rows in such a table. The row ID is
a 6-byte field that increases monotonically as new rows are inserted.
Thus, the rows ordered by the row ID are physically in insertion
order.
My mysql version is:
$ mysql --version
mysql Ver 8.0.11 for Linux on x86_64 (MySQL Community Server - GPL)
I followed the commands there to verify the internal index is created, but the last command doesn't show any index has been created. Why is that? Thanks.
Note that I changed the last command a little bit, because the original command gives me Unknown table 'INNODB_INDEX_STATS' in information_schema error.
# Create the table
create table test.check_table (id int, description varchar(10)) ENGINE = INNODB;
# Verify that there is no primary or unique column
desc test.check_table;
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| description | varchar(10) | YES | | NULL | |
+-------------+-------------+------+-----+---------+-------+
# Insert some values
insert into test.check_table values(1, 'value-1');
insert into test.check_table values(2, 'value-2');
insert into test.check_table values(null, 'value-3');
insert into test.check_table values(4, null);
insert into test.check_table values(1, 'value-1');
# Verify table
select * from test.check_table;
+------+-------------+
| id | description |
+------+-------------+
| 1 | value-1 |
| 2 | value-2 |
| NULL | value-3 |
| 4 | NULL |
| 1 | value-1 |
+------+-------------+
# Verify that the GEN_CLUST_INDEX index is auto-created.
select * from INFORMATION_SCHEMA.INNODB_INDEX_STATS where TABLE_SCHEMA='test' and TABLE_NAME = 'check_table';
ERROR 1109 (42S02): Unknown table 'INNODB_INDEX_STATS' in information_schema
SELECT DISTINCT TABLE_NAME, COLUMN_NAME , INDEX_NAME FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME='check_table';
Empty set (0.00 sec)
In all versions of MySQL that I've been able to find, the INNODB_INDEX_STATS table is located in the mysql database, not INFORMATION_SCHEMA. This appears to be an error in the post you're referencing.
mysql> select * from mysql.innodb_index_stats where table_name = 'check_table';
+---------------+-------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
| database_name | table_name | index_name | last_update | stat_name | stat_value | sample_size | stat_description |
+---------------+-------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
| test | check_table | GEN_CLUST_INDEX | 2018-07-10 11:34:01 | n_diff_pfx01 | 5 | 1 | DB_ROW_ID |
| test | check_table | GEN_CLUST_INDEX | 2018-07-10 11:34:01 | n_leaf_pages | 1 | NULL | Number of leaf pages in the index |
| test | check_table | GEN_CLUST_INDEX | 2018-07-10 11:34:01 | size | 1 | NULL | Number of pages in the index |
+---------------+-------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
This index isn't a "real" index from the perspective of SQL (it doesn't appear in the output of DESCRIBE, and can't be modified or dropped), so it isn't shown in INFORMATION_SCHEMA.STATISTICS.
For version 8.0.11, the table innodb_index_stats is located in mysql schema in lieu of INFORMATION_SCHEMA. Following the commands, the last query gives result as below:
mysql> select VERSION();
+-----------+
| VERSION() |
+-----------+
| 8.0.11 |
+-----------+
mysql> select * from mysql.innodb_index_stats where database_name='test' and table_name = 'check_table';
+---------------+-------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
| database_name | table_name | index_name | last_update | stat_name | stat_value | sample_size | stat_description |
+---------------+-------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
| test | check_table | GEN_CLUST_INDEX | 2018-07-10 18:57:45 | n_diff_pfx01 | 5 | 1 | DB_ROW_ID |
| test | check_table | GEN_CLUST_INDEX | 2018-07-10 18:57:45 | n_leaf_pages | 1 | NULL | Number of leaf pages in the index |
| test | check_table | GEN_CLUST_INDEX | 2018-07-10 18:57:45 | size | 1 | NULL | Number of pages in the index |
+---------------+-------------+-----------------+---------------------+--------------+------------+-------------+-----------------------------------+
Also, the post referenced in the question creates a second table with a primary key specified. The index verification for that query gives:
mysql> create table test.check_table_2 (id int, description varchar(10), PRIMARY KEY(id)) ENGINE = INNODB;
mysql> desc check_table_2;
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| description | varchar(10) | YES | | NULL | |
+-------------+-------------+------+-----+---------+-------+
mysql> select * from mysql.innodb_index_stats where database_name='test' and table_name = 'check_table_2';
+---------------+---------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
| database_name | table_name | index_name | last_update | stat_name | stat_value | sample_size | stat_description |
+---------------+---------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
| test | check_table_2 | PRIMARY | 2018-07-10 19:00:39 | n_diff_pfx01 | 0 | 1 | id |
| test | check_table_2 | PRIMARY | 2018-07-10 19:00:39 | n_leaf_pages | 1 | NULL | Number of leaf pages in the index |
| test | check_table_2 | PRIMARY | 2018-07-10 19:00:39 | size | 1 | NULL | Number of pages in the index |
+---------------+---------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+

Django "UPDATE `django_session`" killing performances

My Django client was very slow during MySQL queries. Doing a tcpdump on the MySQL server, I saw that the following SQL query
"UPDATE `django_session` SET `session_data` = " [data]
is very long. What is the simplest way to solve this problem ?
Thank you.
------------------------- EDIT 1
the size of [data] is very big and it is taking a very long time to transfer.
------------------------- EDIT 2
mysql> SHOW INDEX FROM django_session;
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------------+------------+-------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| django_session | 0 | PRIMARY | 1 | session_key | A | 9496 | NULL | NULL | | BTREE | | |
| django_session | 1 | django_session_expire_date_a5c62663 | 1 | expire_date | A | 9496 | NULL | NULL | | BTREE | | |
2 rows in set (0,02 sec)
mysql> SHOW CREATE TABLE django_session;
| Table | Create Table |
+----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| django_session | CREATE TABLE django_session (
session_key varchar(40) NOT NULL,
session_data longtext NOT NULL,
expire_date datetime NOT NULL,
PRIMARY KEY (session_key),
KEY django_session_expire_date_a5c62663 (expire_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
1 row in set (0,01 sec)

mysql Undo log record is too big

I have a strange problem with a particular database:
mysql> update person set last_name=null where first_name='john';
ERROR 1713 (HY000): Undo log record is too big.
What can be the problem?
(I've already googled quite a log)
mysql 5.7.20 installed with brew on Mac OSX 10.12.6.
show table status where name = 'person'
-> ;
+--------------------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+--------------------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| person | InnoDB | 10 | Dynamic | 650918 | 4322 | 2813853696 | 0 | 1369833472 | 6291456 | NULL | 2017-09-12 14:31:20 | 2017-10-24 12:37:03 | NULL | utf8mb4_unicode_ci | NULL | | |
+--------------------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
1 row in set (0.00 sec)

MySQL InnoDB whats the difference between Data_Length and Max_Data_Length

So here is the table status of my test table:
+------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+------+--------+---------+------------+--------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| TEST | InnoDB | 10 | Compact | 172713 | 1175 | 203096064 | 202309632 | 0 | 5242880 | 181935 | 2015-07-21 23:52:24 | NULL | NULL | utf8_general_ci | NULL | | |
Table is created with:
CREATE TABLE TEST ( id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, att VARCHAR(1000) NOT NULL);
I heard from some one that Max_data_length used to be a fixed value and it is usually 4gb. But in later version of mysql they change the definition of Max_data_length. So now Max_data_length will grow as you insert more data (just like data_length).
I am wondering whats the new definition of Max_data_length and how is it different from Data_length?
Thanks!
Erben