| Bug #59763 | when does innodb compact blocks on delete | ||
|---|---|---|---|
| Submitted: | 27 Jan 2011 0:16 | Modified: | 4 May 2011 19:12 |
| Reporter: | Mark Callaghan | Email Updates: | |
| Status: | Not a Bug | Impact on me: | |
| Category: | MySQL Server: InnoDB Plugin storage engine | Severity: | S3 (Non-critical) |
| Version: | 5.1,5.5 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | compact, delete, innodb | ||
[27 Jan 2011 0:16]
Mark Callaghan
[8 Feb 2011 22:49]
Mark Callaghan
Maybe Domas can supply a better reproduction case. I cannot reproduce the problem. I used the test listed below and measured both the size of the ibd file after inserting 1M rows, after deleting the largest ~90% of them, and then after inserting ~500,000 rows. The ibd file did not grow after the delete so the inserts that followed appeared to use space made available after the deletes. The i.ibd file was ~32M after the initial insert and ~32M at test end.
I also ran enhanced innochecksum on the ibd file after the initial insert, delete and then re-insert. After the initial insert, innochecksum reported block allocation in i.ibd as:
1555 FIL_PAGE_INDEX
490 FIL_PAGE_TYPE_ALLOCATED
After the delete:
1555 FIL_PAGE_INDEX
490 FIL_PAGE_TYPE_ALLOCATED
And after the re-insert:
1555 FIL_PAGE_INDEX
490 FIL_PAGE_TYPE_ALLOCATED
I created f-master.opt with:
--innodb-file-per-table
and used f.test with:
-- source include/have_innodb_plugin.inc
create table i(ic int primary key auto_increment) engine=innodb;
create table i2(ic int primary key auto_increment) engine=innodb;
insert into i2 values (1), (2), (3), (4);
let $x=12;
while ($x)
{
eval insert into i2 select null from i2;
dec $x;
}
let $x=64;
while ($x)
{
eval insert into i select null from i2;
dec $x;
}
select count(*) from i;
show table status;
echo Sleep before;
sleep 10;
delete from i where ic > 900000;
delete from i where ic > 800000;
delete from i where ic > 700000;
delete from i where ic > 600000;
delete from i where ic > 500000;
delete from i where ic > 400000;
delete from i where ic > 300000;
delete from i where ic > 200000;
delete from i where ic > 100000;
select count(*) from i;
echo Sleep after;
sleep 60;
show table status;
echo Insert more;
let $x=32;
while ($x)
{
eval insert into i select null from i2;
dec $x;
}
select count(*) from i;
echo Sleep after insert;
sleep 60;
show table status;
[8 Feb 2011 23:33]
Mark Callaghan
I repeated the test without using file-per-table and it appears that the pages that should be free after the big delete remain allocated for table i. But they are eventually moved to other uses when needed. I changed to test to avoid allocating so much undo. ibdata1 did not grow after the initial insert so I think InnoDB did the right thing here. After the initial insert of 1M rows: 1713 FIL_PAGE_INDEX 947 FIL_PAGE_TYPE_ALLOCATED and pages by ID: 1676 15 26 16 1 17 After deleting 90% of the rows: 1446 FIL_PAGE_INDEX 363 FIL_PAGE_UNDO_LOG 869 FIL_PAGE_TYPE_ALLOCATED and pages by ID show that most are still counted for the table with the inserts: 1409 15 26 16 1 17 After inserting ~1M into another table: 1815 FIL_PAGE_INDEX 82 FIL_PAGE_UNDO_LOG 784 FIL_PAGE_TYPE_ALLOCATED and pages by ID finally shows pages taken away from the first table: 404 15 26 16 1375 17
[4 May 2011 18:01]
Sveta Smirnova
Thank you for the report. > ibdata1 did not grow after the initial insert so I think InnoDB did the right thing here. Does this mean bug can be closed as "Not a Bug"/"Can't repeat"?
[4 May 2011 18:53]
Mark Callaghan
yes, please close as "not a bug"
[4 May 2011 19:12]
Sveta Smirnova
Closed, thanks!
