| Bug #36312 | InnoDB DATA_FREE BUG? | ||
|---|---|---|---|
| Submitted: | 24 Apr 2008 9:42 | Modified: | 20 Jan 22:15 |
| Reporter: | talen xu | ||
| Status: | Closed | ||
| Category: | Server: Partition | Severity: | S3 (Non-critical) |
| Version: | 5.1.24 | OS: | Linux |
| Assigned to: | Mattias Jonsson | Target Version: | 5.1+ |
| Tags: | DATA_FREE InnoDB | ||
| Triage: | Triaged: D4 (Minor) | ||
[24 Apr 2008 9:42]
talen xu
[24 Apr 2008 11:30]
Domas Mituzas
Seems to be a duplicate of Bug#36278
[24 Apr 2008 11:55]
talen xu
I do not think that is bug 36278.I am also aware that the free_data there is in kilobytes.Even so,it is not correct mysql> select 2008104960/1024/1024; +----------------------+ | 2008104960/1024/1024 | +----------------------+ | 1915.07812500 | +----------------------+ 1 row in set (0.00 sec) Because I allocate the total size is 200G why?
[27 Apr 2008 13:40]
Sveta Smirnova
Thank you for the report. Verified as described. Seems only partitioned tables are affected. Test case: --source include/have_innodb.inc create table t1(id int) engine=innodb; insert into t1 values(1),(2),(3),(4); create table t2(id int) engine=innodb PARTITION BY HASH(id*2) partitions 4; create table t3(id int) engine=innodb PARTITION BY HASH(id*2) partitions 2; select TABLE_NAME, data_free from information_schema.TABLES where TABLE_NAME like 't%'; show table status like 't%';
[27 Apr 2008 15:19]
talen xu
mysql> select TABLE_NAME, data_free/1024/1024 from information_schema.TABLES where TABLE_NAME like 't_'; +------------+---------------------+ | TABLE_NAME | data_free/1024/1024 | +------------+---------------------+ | t1 | 150.71191406 | | t2 | 602.84765625 | | t3 | 301.42382813 | +------------+---------------------+ 3 rows in set (0.00 sec)
[27 Apr 2008 16:02]
talen xu
ls -lrth ibdata* -rw-rw---- 1 mysql mysql 2.0G Apr 24 14:27 ibdata25 -rw-rw---- 1 mysql mysql 2.0G Apr 24 14:27 ibdata26 -rw-rw---- 1 mysql mysql 2.0G Apr 24 14:27 ibdata27 Table t1 shows that it is correct
[23 Jun 2008 19:49]
Heikki Tuuri
Vasil, you recently fixed something associated with data free. Please look at this. --Heikki
[24 Jun 2008 9:03]
Vasil Dimov
Data_free is multiplied by the number of partitions.
Here is a test case and a gdb output:
create table t1(id int) engine=innodb;
create table t2(id int) engine=innodb PARTITION BY HASH(id*2) partitions 2;
select TABLE_NAME, data_free from information_schema.TABLES where TABLE_NAME like 't%';
gdb during the above select:
Breakpoint 4, ha_innobase::info (this=0x2529c10, flag=86) at handler/ha_innodb.cc:6656
6656 ib_table->space) * 1024;
(gdb) ins ib_table->name
$56 = 0x1814220 "test/t1"
(gdb) c
Continuing.
Breakpoint 4, ha_innobase::info (this=0x252b010, flag=16) at handler/ha_innodb.cc:6656
6656 ib_table->space) * 1024;
(gdb) ins ib_table->name
$57 = 0x1816620 "test/t2#P#p0"
(gdb) c
Continuing.
Breakpoint 3, ha_partition::info (this=0x252ac10, flag=86) at ha_partition.cc:4495
4495 stats.delete_length+= file->stats.delete_length;
(gdb) ins file->table_share->table_name
$58 = {str = 0x252a315 "t2", length = 2}
(gdb) c
Continuing.
Breakpoint 4, ha_innobase::info (this=0x252b1f8, flag=16) at handler/ha_innodb.cc:6656
6656 ib_table->space) * 1024;
(gdb) ins ib_table->name
$59 = 0x1817a20 "test/t2#P#p1"
(gdb) c
Continuing.
Breakpoint 3, ha_partition::info (this=0x252ac10, flag=86) at ha_partition.cc:4495
4495 stats.delete_length+= file->stats.delete_length;
(gdb) ins file->table_share->table_name
$60 = {str = 0x252a315 "t2", length = 2}
(gdb) c
Continuing.
This loop inside sql/ha_partition.cc is adding the free space multiple times (line
4495):
4485 do
4486 {
4487 if (bitmap_is_set(&(m_part_info->used_partitions), (file_array - m_file)))
4488 {
4489 file= *file_array;
4490 file->info(HA_STATUS_VARIABLE);
4491 stats.records+= file->stats.records;
4492 stats.deleted+= file->stats.deleted;
4493 stats.data_file_length+= file->stats.data_file_length;
4494 stats.index_file_length+= file->stats.index_file_length;
4495 stats.delete_length+= file->stats.delete_length;
4496 if (file->stats.check_time > stats.check_time)
4497 stats.check_time= file->stats.check_time;
4498 }
4499 } while (*(++file_array));
We have the following dilemma: there is a pool of 10MB free space (for example). There
are 2 tables in it - t2-partition0 and t2-partition1. For InnoDB these are two
independent tables, and when asked how much is the free space in t2-partition0 the answer
is 10MB, same for t2-partition1. Then the partitioning code assumes that t2 has free space
of 20MB because each of its two pars has 10MB.
I think this should be handled at partitioning level. It may not be as simple as counting
the free space only once (i.e. dividing the result to the number of partitions) because if
innodb_file_per_table is ON, then the free space is indeed 20MB, in the above example,
because 2 files are created - t2#P#p0.ibd and t2#P#p1.ibd, each one being 10MB.
Setting this to "Server: Partitioning" and de-assigning from myself. Feel free to set
back to InnoDB bug if changes to InnoDB code are needed.
[27 Aug 2008 10:16]
Mattias Jonsson
marked bug#38964 as a duplicate of this
[2 Dec 2008 10:14]
Mattias Jonsson
Assigning to myself, if all partitions have the same stat variables, then I assume it uses the same tablespace (or innodb-file). This might be wrong result on an empty table, or if the tablespace/innodb-file is used concurrently by another thread.
[16 Dec 2008 16:22]
Mattias Jonsson
For tables using TABLESPACES, one can query I_S.PARTITIONS for this like: select table_schema,table_name, sum(table_rows), sum(data_length)/sum(table_rows) as 'avg_row_length', sum(data_length), sum(max_data_length), sum(index_length), sum(data_free) from (select table_schema, table_name, tablespace_name, sum(table_rows) as table_rows, data_length, max_data_length, index_length, data_free from information_schema.partitions where table_schema = 'test' and table_name = 't2' group by table_schema, table_name, tablespace_name) a group by table_schema, table_name; This is also possible to do on InnoDB tables, although they do not use TABLESPACE, but one self must check if the InnoDB table was created with innodb_file_per_table or not, since that cannot be checked within the storage engine api. I will propose a patch which will default to innodb_file_per_table, but if it is obvious not using innodb_file_per_table, it will not sum the values for DATA_FREE etc. I assume it is NOT created with innodb_file_per_table if all these statements are true: Table is using ENGINE = InnoDB. All partitions have the same data_file_length, index_file_length, delete_length, check_time. NOT all partitions have the same number of records, deleted records, mean_rec_length. (Might be innodb_file_per_table and evently distributed records, defaulting to guess on innodb_file_per_table, to not break current default). I will not make any other changes on how ha_partition::info() reports the DATA_FREE etc. on table level (i.e. do grouping on tablespaces) since it is possible to get that information on a partition level through I_S.PARTITIONS.
[19 Dec 2008 9:23]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/62055 2739 Mattias Jonsson 2008-12-19 Bug#36312: InnoDB DATA_FREE BUG? Problem is that DATA_FREE in SHOW TABLE STATUS is not correct when not using innodb_file_per_table. The solution is to use I_S.PARTITIONS instead. This is only a small fix for correcting mean record length and always return 0 if the table is empty.
[19 Dec 2008 9:30]
Mattias Jonsson
Here is a print out from a ha_partition::info(HA_STATUS_VARIABLE) showing the results from each partitions ::info call. (r - records, d - deleted records, f - data file length, i - index file length, dl - deleted length, c - create time, m - mean record length) part: r 1 d 0 f 16384 i 0 dl 0 c 0 m 16384 part: r 1 d 0 f 16384 i 0 dl 0 c 0 m 16384 part: r 2 d 0 f 16384 i 0 dl 0 c 0 m 8192 part: r 1 d 0 f 16384 i 0 dl 0 c 0 m 16384 part: r 1 d 0 f 16384 i 0 dl 0 c 0 m 16384 The above result is the same for both tables created with and without innodb_file_per_table. It would be too many restrictions and special treatment for this to be user friendly and/or correct for all variants. So my proposal would be the following: Always return the sum of all partitions for the statistics (accept for mean record length, which we recalculate). And document this behavior. (The correct value can be accumulated from I_S.PARTITIONS, if one have the knowledge of how the storage engine stores the data, i.e. if innodb_file_per_table was set when created all partitions. This is also true for engines using tablespaces).
[8 Jan 11:36]
Mattias Jonsson
Patch queued to mysql-5.1-bugteam and mysql-6.0-bugteam (the patch was only a small fix for correcting mean record length and always return 0 if the table is empty. I.e. not changing the behavior for DATA_FREE!).
[14 Jan 10:32]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/63197 2748 He Zhenxing 2009-01-14 [merge] Auto merge
[15 Jan 7:38]
Bugs System
Pushed into 5.1.31 (revid:joro@sun.com-20090115053147-tx1oapthnzgvs1ro) (version source revid:davi.arnaut@sun.com-20090113150631-y84w12o2zmh7j3qd) (merge vers: 5.1.31) (pib:6)
[15 Jan 18:01]
Jon Stephens
Documented bugfix in the 5.1.31 changelog as follows:
SHOW TABLE STATUS could show a nonzero value for the Mean record
length of a partitioned InnoDB table, even if the table
contained no rows.
Also updated info in SHOW TABLE STATUS section of 5.1/6.0 Manual per developer comments.
Set back to PQ status pending merge to 6.0 tree.
[15 Jan 19:29]
Jon Stephens
Status should have been set to NDI.
[19 Jan 12:28]
Bugs System
Pushed into 5.1.31-ndb-6.2.17 (revid:tomas.ulin@sun.com-20090119095303-uwwvxiibtr38djii) (version source revid:tomas.ulin@sun.com-20090115073240-1wanl85vlvw2she1) (merge vers: 5.1.31-ndb-6.2.17) (pib:6)
[19 Jan 14:06]
Bugs System
Pushed into 5.1.31-ndb-6.3.21 (revid:tomas.ulin@sun.com-20090119104956-guxz190n2kh31fxl) (version source revid:tomas.ulin@sun.com-20090119104956-guxz190n2kh31fxl) (merge vers: 5.1.31-ndb-6.3.21) (pib:6)
[19 Jan 14:58]
Jon Stephens
Set status back to NDI pending merge to 6.0.
[19 Jan 17:12]
Bugs System
Pushed into 5.1.31-ndb-6.4.1 (revid:tomas.ulin@sun.com-20090119144033-4aylstx5czzz88i5) (version source revid:tomas.ulin@sun.com-20090119144033-4aylstx5czzz88i5) (merge vers: 5.1.31-ndb-6.4.1) (pib:6)
[19 Jan 18:04]
Jon Stephens
Set back to NDI pending merge to 6.0.
[20 Jan 19:58]
Bugs System
Pushed into 6.0.10-alpha (revid:joro@sun.com-20090119171328-2hemf2ndc1dxl0et) (version source revid:mattias.jonsson@sun.com-20090108102010-3caae52fb95b5v4x) (merge vers: 6.0.10-alpha) (pib:6)
[20 Jan 22:15]
Jon Stephens
Fix also noted in 6.0.10 changelog; closed.
