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!