Defragmenting InnoDB Tablespaces
Overview
When rows are deleted from an InnoDB table, the rows are simply marked as deleted and not physically deleted. The free space is not returned to the operating system for re-use.
The purge thread will physically delete index keys and rows, but the free space introduced is still not returned to operating system. This can lead to gaps in the pages. If you have variable length rows, new rows may be larger than old rows and cannot make use of the available space.
You can run OPTIMIZE TABLE or ALTER TABLE
ENGINE=InnoDB to reconstruct the table. Unfortunately running OPTIMIZE TABLE against an InnoDB table stored in the shared table-space file ibdata1 does two things:
Makes the table’s data and indexes contiguous inside
ibdata1.Increases the size of
ibdata1because the contiguous data and index pages are appended toibdata1.
InnoDB Defragmentation
The feature described below has been deprecated in MariaDB 11.0 and was removed in MariaDB 11.1.0. See MDEV-30544 and MDEV-30545.
MariaDB 10.1 merged Facebook's defragmentation code prepared for MariaDB by Matt, Seong Uck Lee from Kakao. The only major difference to Facebook's code and Matt’s patch is that MariaDB does not introduce new literals to SQL and makes no changes to the server code. Instead, OPTIMIZE TABLE is used and all code changes are inside the InnoDB/XtraDB storage engines.
The behaviour of OPTIMIZE TABLE is unchanged by default, and to enable this new feature, you need to set the innodb_defragment system variable to 1.
[mysqld]
...
innodb-defragment=1No new tables are created and there is no need to copy data from old tables to new tables. Instead, this feature loads n pages (determined by innodb-defragment-n-pages) and tries to move records so that pages would be full of records and then frees pages that are fully empty after the operation.
Note that tablespace files (including ibdata1) will not shrink as the result of defragmentation, but one will get better memory utilization in the InnoDB buffer pool as there are fewer data pages in use.
A number of new system and status variables for controlling and monitoring the feature are introduced.
System Variables
innodb_defragment: Enable InnoDB defragmentation.
innodb_defragment_n_pages: Number of pages considered at once when merging multiple pages to defragment.
innodb_defragment_stats_accuracy: Number of defragment stats changes there are before the stats are written to persistent storage.
innodb_defragment_fill_factor_n_recs: Number of records of space that defragmentation should leave on the page.
innodb_defragment_fill_factor: Indicates how full defragmentation should fill a page.
innodb_defragment_frequency: Maximum times per second for defragmenting a single index.
Status Variables
Innodb_defragment_compression_failures: Number of defragment re-compression failures
Innodb_defragment_failures: Number of defragment failures.
Innodb_defragment_count: Number of defragment operations.
Example
After these CREATE and INSERT operations, the following information can be seen from the INFORMATION SCHEMA:
Deleting three-quarters of the records, leaving gaps, and then optimizing:
Now some pages have been freed, and some merged:
See Defragmenting unused space on InnoDB tablespace on the Mariadb.org blog for more details.
This page is licensed: CC BY-SA / Gnu FDL
Last updated
Was this helpful?

