Bug #56536 | CREATE TABLE … doesn't initialize data_length, index_length | ||
---|---|---|---|
Submitted: | 3 Sep 2010 13:10 | Modified: | 5 Oct 2010 16:12 |
Reporter: | Paolo Lunazzi | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S3 (Non-critical) |
Version: | 5.1.43 | OS: | Linux |
Assigned to: | Jimmy Yang | CPU Architecture: | Any |
Tags: | create, data_free, innodb, truncate |
[3 Sep 2010 13:10]
Paolo Lunazzi
[6 Sep 2010 20:40]
Sveta Smirnova
Thank you for the report. I see Data_length = 0 after TRUNCATE and Data_free is 0 everytime. Also version 5.1.43 is old. Please try with version 5.1.50 and if problem still exists provide your configuration file.
[10 Sep 2010 14:06]
Paolo Lunazzi
Tried with 5.1.50: mysql> show table status\G *************************** 1. row *************************** Name: so_hits Engine: InnoDB Version: 10 Row_format: Compact Rows: 1401342 Avg_row_length: 65 Data_length: 91881472 Max_data_length: 0 Index_length: 92536832 Data_free: 4194304 Auto_increment: NULL Create_time: 2010-09-10 13:37:53 Update_time: NULL Check_time: NULL Collation: latin1_swedish_ci Checksum: NULL Create_options: Comment: 1 row in set (0.00 sec) mysql> truncate table so_motime_hits_live; Query OK, 0 rows affected (0.28 sec) mysql> show table status\G *************************** 1. row *************************** Name: so_hits Engine: InnoDB Version: 10 Row_format: Compact Rows: 0 Avg_row_length: 0 Data_length: 16384 Max_data_length: 0 Index_length: 32768 Data_free: 187695104 Auto_increment: NULL Create_time: 2010-09-10 13:37:53 Update_time: NULL Check_time: NULL Collation: latin1_swedish_ci Checksum: NULL Create_options: Comment: 1 row in set (0.00 sec)
[10 Sep 2010 15:46]
Sveta Smirnova
Thank you for the feedback. Most of data were freed really: 91881472 > 16384 Please send us output of SHOW CREATE TABLE so_hits, so we can re-create the problem.
[13 Sep 2010 9:07]
Paolo Lunazzi
But if the truncate table drops the table like it is written on the manual, data_free must be 0. In fact if I do manually a drop/create data_free is 0. Below the create table. mysql> show create table so__hits\G *************************** 1. row *************************** Table: so_motime_hits_live Create Table: CREATE TABLE `so_hits` ( `id` bigint(20) unsigned NOT NULL, `file_id` int(10) unsigned NOT NULL, `offset` int(10) unsigned NOT NULL, `tld` char(2) NOT NULL, `ev_date` date NOT NULL, `ev_hour` tinyint(3) unsigned NOT NULL, `step_id` tinyint(3) unsigned NOT NULL, `spare` char(1) DEFAULT NULL, `cmp` int(11) DEFAULT NULL, `flight` int(11) DEFAULT NULL, `crt` int(11) DEFAULT NULL, `leaf` smallint(5) unsigned NOT NULL, `site` smallint(5) DEFAULT NULL, `state` tinyint(3) unsigned DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `Id_File` (`file_id`,`offset`), KEY `idx` (`cmp`,`flight`,`crt`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
[14 Sep 2010 0:18]
Sveta Smirnova
Thank you for the feedback. Verified as described, although this can be expected, because every storage engine can use own implementation of TRUNCATE and InnoDB does. Test case for MTR: --source include/have_innodb.inc CREATE TABLE `t1` ( `id` bigint(20) unsigned NOT NULL, `file_id` int(10) unsigned NOT NULL, `offset` int(10) unsigned NOT NULL, `tld` char(2) NOT NULL, `ev_date` date NOT NULL, `ev_hour` tinyint(3) unsigned NOT NULL, `step_id` tinyint(3) unsigned NOT NULL, `spare` char(1) DEFAULT NULL, `cmp` int(11) DEFAULT NULL, `flight` int(11) DEFAULT NULL, `crt` int(11) DEFAULT NULL, `leaf` smallint(5) unsigned NOT NULL, `site` smallint(5) DEFAULT NULL, `state` tinyint(3) unsigned DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `Id_File` (`file_id`,`offset`), KEY `idx` (`cmp`,`flight`,`crt`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; --disable_query_log --disable_warnings let $i=1000; while ($i) { --eval insert into t1 values($i,$i,$i,'$i',curdate(),$i,$i,'$i',$i,$i,$i,$i,$i,$i) dec $i; } --enable_warnings --enable_query_log --vertical_results show table status like 't1'; truncate table t1; show table status like 't1'; drop table t1; create table t1(f1 text); show table status like 't1';
[15 Sep 2010 7:50]
Marko Mäkelä
The built-in InnoDB in MySQL 5.1 implements TRUNCATE by dropping and re-creating the index trees within the same tablespace. It will not delete and re-create the *.ibd file, nor shrink the *.ibd file before re-creating the index trees of the table. The InnoDB Plugin in MySQL 5.1 implements TRUNCATE by dropping the tablespace and creating a new one before creating the index trees. There, data_free should be 0, just like after CREATE TABLE. Can you confirm this?
[15 Sep 2010 18:41]
Sveta Smirnova
Same problem with Plugin. Before truncate: Data_length 98304 Max_data_length 0 Index_length 114688 Data_free 4194304 After truncate: Data_length 16384 Max_data_length 0 Index_length 32768 Data_free 4194304 After drop/create: Data_length 0 Max_data_length 281474976710655 Index_length 1024 Data_free 0
[16 Sep 2010 12:42]
Mikhail Izioumtchenko
Sveta, could you do DROP/TRUNCATE with the Plugin and innodb-file-per-table=1? This should work as Marko described.
[16 Sep 2010 17:14]
Sveta Smirnova
Michael, re-tested with both settings. With --innodb_file_per_table results are: before TRUNCATE; Data_length 98304 Max_data_length 0 Index_length 114688 Data_free 0 after TRUNCATE; Data_length 16384 Max_data_length 0 Index_length 32768 Data_free 0 after DROP/CREATE: Data_length 0 Max_data_length 281474976710655 Index_length 1024 Data_free 0 Still interesting why Data_length is not 0 after TRUNCATE
[16 Sep 2010 18:01]
Mikhail Izioumtchenko
let's leave it to Marko to sort it out. To me it's interesting that data_free was 0 before any action, with innodb-file-per-table, is it a test deficiency or an InnoDB being generally ignorant of data_free, as the rest of the bug suggests. Now that MySQL and InnoDB are one it would be nice to handle all those small things properly. As for TRUNCATE action itself, well we do our best and there's a number of bugs/feature requests that say we should do better, Marko is the expert here.
[22 Sep 2010 6:07]
Marko Mäkelä
Sveta, Your test demonstrates that TRUNCATE TABLE in InnoDB Plugin works as advertised. The table comprises three B-tree indexes: * the clustered index (organized by PRIMARY KEY(id)) * two secondary indexes: UNIQUE KEY Id_File and KEY idx The minimum size of the table is 3 B-tree root pages of 16384 bytes each, one per index. Thus, this is correct: after TRUNCATE; Data_length 16384 Max_data_length 0 Index_length 32768 Data_free 0 What is incorrect is that CREATE TABLE is not initializing the fields: after DROP/CREATE: Data_length 0 Max_data_length 281474976710655 Index_length 1024 Data_free 0
[30 Sep 2010 3:08]
Jimmy Yang
Well, after drop and recreate, the table seems to be a MyISAM table, and the incorrect value: mysql> create table t1(f1 text); Query OK, 0 rows affected (0.09 sec) mysql> show table status like 't1'; +------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-------------------+----------+----------------+---------+ | 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 | +------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-------------------+----------+----------------+---------+ | t1 | MyISAM | 10 | Dynamic | 0 | 0 | 0 | 281474976710655 | 1024 | 0 | NULL | 2010-09-29 20:01:06 | 2010-09-29 20:01:06 | NULL | latin1_swedish_ci | NULL | | | +------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-------------------+----------+----------------+---------+ 1 row in set (0.00 sec) If it is an InnoDB table, the fields are correctly initialized. mysql> drop table t1; Query OK, 0 rows affected (0.00 sec) mysql> create table t1(f1 text) engine = innodb; Query OK, 0 rows affected (0.14 sec) mysql> show table status like 't1'; +------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-------------------+----------+----------------+---------+ | 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 | +------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-------------------+----------+----------------+---------+ | t1 | InnoDB | 10 | Compact | 0 | 0 | 16384 | 0 | 0 | 4194304 | NULL | 2010-09-29 20:04:36 | NULL | NULL | latin1_swedish_ci | NULL | | | +------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-------------------+----------+----------------+---------+ 1 row in set (0.00 sec)
[5 Oct 2010 16:12]
Sveta Smirnova
Jimmy, correct, I forgot option engine in my test when created second table. I think in case of MyISAM this should be not a bug as it handles table data differently, so closing it as such.