MDEV-37886 PAGE_COMPRESSED ALTER TABLE operations inconsistent with innodb_file_per_table setting#4646
Merged
MDEV-37886 PAGE_COMPRESSED ALTER TABLE operations inconsistent with innodb_file_per_table setting#4646
Conversation
|
|
c20173a to
1b225b6
Compare
dr-m
approved these changes
Feb 17, 2026
sql/handler.h
Outdated
Comment on lines
2636
to
2648
| /** true for ALTER IGNORE TABLE ... */ | ||
| const bool ignore; | ||
|
|
||
| /** true for online operation (LOCK=NONE) */ | ||
| bool online= false; | ||
| /** Online operation and storage engine specific flags */ | ||
| struct | ||
| { | ||
| /** TRUE for online operation (LOCK=NONE) */ | ||
| unsigned online : 1; | ||
| /** TRUE when innodb_file_per_table is set */ | ||
| unsigned file_per_table : 1; | ||
| /** Reserved for future storage engine flags */ | ||
| unsigned reserved : 6; | ||
| } engine_flags= {0, 0, 0}; |
Contributor
There was a problem hiding this comment.
There should be no need for the reserved field nor for the struct encapsulation.
Could the ignore flag be part of the same bit-field? Could we move this bit-field next to uint index_altered_ignorability_count in order to reduce the alignment loss? Check the output of ptype/o Alter_inplace_info in GDB.
Member
Author
There was a problem hiding this comment.
{code}
Before:
======
(gdb) ptype /o ha_alter_info
type = class Alter_inplace_info {
public:
/* 0 | 8 */ HA_CREATE_INFO *create_info;
/* 8 | 8 */ Alter_info *alter_info;
/* 16 | 8 */ KEY *key_info_buffer;
/* 24 | 4 */ uint key_count;
/* 28 | 4 */ uint index_drop_count;
/* 32 | 8 */ KEY **index_drop_buffer;
/* 40 | 4 */ uint index_add_count;
/* XXX 4-byte hole */
/* 48 | 8 */ uint *index_add_buffer;
/* 56 | 8 */ KEY_PAIR *index_altered_ignorability_buffer;
/* 64 | 4 */ uint index_altered_ignorability_count;
/* XXX 4-byte hole */
/* 72 | 32 */ Rename_keys_vector rename_keys;
/* 104 | 8 */ inplace_alter_handler_ctx *handler_ctx;
/* 112 | 8 */ inplace_alter_handler_ctx **group_commit_ctx;
/* 120 | 8 */ alter_table_operations handler_flags;
/* 128 | 8 */ ulong partition_flags;
/* 136 | 8 */ partition_info * const modified_part_info;
/* 144 | 1 */ const bool ignore;
/* 145 | 1 */ bool online;
/* XXX 6-byte hole */
/* 152 | 8 */ inplace_alter_table_commit_callback *inplace_alter_table_committed;
/* 160 | 8 */ void *inplace_alter_table_committed_argument;
/* 168 | 4 */ enum_alter_inplace_result inplace_supported;
/* XXX 4-byte hole */
/* 176 | 8 */ const char *unsupported_reason;
/* 184 | 1 */ const bool error_if_not_empty;
/* 185 | 1 */ bool mdl_exclusive_after_prepare;
/* XXX 6-byte padding */
/* total size (bytes): 192 */
} *
After:
=====
(gdb) ptype/o ha_alter_info
type = class Alter_inplace_info {
public:
/* 0 | 8 */ HA_CREATE_INFO *create_info;
/* 8 | 8 */ Alter_info *alter_info;
/* 16 | 8 */ KEY *key_info_buffer;
/* 24 | 8 */ KEY **index_drop_buffer;
/* 32 | 8 */ uint *index_add_buffer;
/* 40 | 8 */ KEY_PAIR *index_altered_ignorability_buffer;
/* 48 | 8 */ inplace_alter_handler_ctx *handler_ctx;
/* 56 | 8 */ inplace_alter_handler_ctx **group_commit_ctx;
/* 64 | 8 */ alter_table_operations handler_flags;
/* 72 | 8 */ partition_info * const modified_part_info;
/* 80 | 8 */ inplace_alter_table_commit_callback *inplace_alter_table_committed;
/* 88 | 8 */ void *inplace_alter_table_committed_argument;
/* 96 | 8 */ const char *unsupported_reason;
/* 104 | 8 */ ulong partition_flags;
/* 112 | 32 */ Rename_keys_vector rename_keys;
/* 144 | 4 */ uint key_count;
/* 148 | 4 */ uint index_drop_count;
/* 152 | 4 */ uint index_add_count;
/* 156 | 4 */ uint index_altered_ignorability_count;
/* 160 | 4 */ enum_alter_inplace_result inplace_supported;
/* 164: 0 | 4 */ unsigned int online : 1;
/* 164: 1 | 4 */ unsigned int file_per_table : 1;
/* 164: 2 | 4 */ unsigned int ignore : 1;
/* 164: 3 | 4 */ unsigned int error_if_not_empty : 1;
/* 164: 4 | 4 */ unsigned int mdl_exclusive_after_prepare : 1;
/* XXX 3-bit padding */
/* XXX 3-byte padding */
/* total size (bytes): 168 */
} *
1b225b6 to
424f420
Compare
…nnodb_file_per_table setting Problem: ======= InnoDB DDL does ALTER TABLE PAGE_COMPRESSED=1 because: 1. check_if_supported_inplace_alter() reads srv_file_per_table during precheck and does allow INSTANT operation. 2. User does change innodb_file_per_table later. But prepare phase read srv_file_per_table again during execution. 3. If the global variable changed between these phases, causes server abort for page_compressed tables. Solution: ========= - Add a file_per_table member to Alter_inplace_info to capture the innodb_file_per_table value during the precheck phase and use that consistent value throughout the entire ALTER TABLE operation. - Converted boolean flags (online, ignore, error_if_not_empty, mdl_exclusive_after_prepare) from individual boolean members to bitfields packed in a single byte - Reduced Alter_inplace_info structure size by 24 bytes
424f420 to
8882f8f
Compare
dr-m
approved these changes
Feb 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem:
InnoDB DDL does ALTER TABLE PAGE_COMPRESSED=1 because:
Solution: