[MDEV-26400] ALTER TABLE does not remove KEY_BLOCK_SIZE for non-Compressed InnoDB tables Created: 2021-08-18 Updated: 2021-11-01 |
|
| Status: | Stalled |
| Project: | MariaDB Server |
| Component/s: | Data Definition - Alter Table, Storage Engine - InnoDB |
| Affects Version/s: | 10.6.4 |
| Fix Version/s: | 10.6 |
| Type: | Bug | Priority: | Major |
| Reporter: | Geoff Montee (Inactive) | Assignee: | Sergei Golubchik |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||||||||||||||||||
| Description |
|
For InnoDB tables, the KEY_BLOCK_SIZE table option is only used for the Compressed row format. The Compressed row format is read-only in 10.6, so many users will probably want to convert to other row formats. When the KEY_BLOCK_SIZE table option is set for an InnoDB table, it seems a bit difficult to get rid of. Let's say that we start with this table:
You cannot set KEY_BLOCK_SIZE=DEFAULT at the same time you try to change the row format:
You can almost set KEY_BLOCK_SIZE=0 at the same time you try to change the row format:
But for some weird reason, that seems to move the original KEY_BLOCK_SIZE option to the PK:
Shouldn't there be a more reliable method to remove the KEY_BLOCK_SIZE option from an InnoDB table? |
| Comments |
| Comment by Geoff Montee (Inactive) [ 2021-08-18 ] | ||
|
It looks like this might be a duplicate of MDEV-12152. | ||
| Comment by Marko Mäkelä [ 2021-08-19 ] | ||
|
This is an interesting bug, and I do not know if there is a satisfactory way to fix it. When I developed the original form of InnoDB compression, which was initially released in a product that was distributed independently from MySQL ("InnoDB Plugin for MySQL 5.1"), back when Oracle owned Innobase Oy but not MySQL, we were unable to change any syntax. We had to repurpose an existing attribute. Nowadays, MariaDB Server would provide a HA_xOPTION interface that would allow a storage engine to define attributes on columns, indexes, or tables. But that did not exist in MySQL back then (and still does not). I noticed that the attribute KEY_BLOCK_SIZE had been recently introduced for some other purpose. The syntax ROW_FORMAT=COMPRESSED already existed; if I remember correctly, MyISAM supported compressed read-only tables from an early point on. We needed something that would allow the compressed page size to be specified independently of the InnoDB page size (which before the introduction of the global parameter innodb_page_size was fixed at 16384 bytes). Unlike the much later page_compressed format which resembles Stacker or DoubleSpace by compressing fixed-size input blocks to variable-size output blocks, the InnoDB ROW_FORMAT=COMPRESSED format requires one to specify the target compressed page size upfront and essentially treats the input as variable-size blocks. If the compressed page fills up, a page split on the uncompressed page will be forced. The default value of the compressed page size is half the uncompressed page size. Someone thought that because the SQL parser does not support suffixes like KEY_BLOCK_SIZE=4K or KEY_BLOCK_SIZE=4KiB (MDEV-25652), it would be awkward to require the user to type larger powers of two, like KEY_BLOCK_SIZE=4096. So, the unit was chosen to be 1024 bytes instead of bytes. Because a storage engine cannot rewrite the table definition that is stored in the .frm file, we ended up with this awkward situation. Specifying KEY_BLOCK_SIZE alone without any ROW_FORMAT will imply ROW_FORMAT=COMPRESSED, but SHOW CREATE TABLE will not indicate that. Specifying KEY_BLOCK_SIZE with any other ROW_FORMAT than COMPRESSED or DEFAULT (which I believe is the same as specifying no ROW_FORMAT) will result in an error. Based on the description, I assume that KEY_BLOCK_SIZE was originally conceived as an index attribute, and that the table-wide attribute would specify the default for all indexes, similar to how columns may default to character set or collation attributes specified at the table level. But, InnoDB always treated it as a table attribute. I do not know if any other storage engine would interpret KEY_BLOCK_SIZE, or allow different indexes to use a different page size. ENGINE=Aria or ENGINE=MyISAM would be my best guesses for that. The only easy improvements that I might foresee are outside InnoDB:
With these suggestions, I think that the following should remove all traces of ROW_FORMAT=COMPRESSED or KEY_BLOCK_SIZE:
|