[MDEV-15507] Assertion `!((flags & ((~(~0U << 1)) << 0)) >> 0) || flags2 & 16U' failed in dict_check_sys_tables on upgrade from 5.5 Created: 2018-03-07 Updated: 2018-04-26 Resolved: 2018-04-26 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - InnoDB |
| Affects Version/s: | 10.2.2, 10.3.0 |
| Fix Version/s: | 10.2.15, 10.3.7 |
| Type: | Bug | Priority: | Major |
| Reporter: | Elena Stepanova | Assignee: | Marko Mäkelä |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | upstream | ||
| Attachments: |
|
||||||||
| Issue Links: |
|
||||||||
| Description |
|
The attached datadir was created on MariaDB 5.5.50 by running simple workflow and then shutting down the server normally (general log is also attached). Further attempt to start 10.2 (with all default options) on this datadir causes the assertion failure:
10.1 starts all right. Starting 10.1 and running mysql_upgrade doesn't help, 10.2 still fails after that. Please note that I had to pack ibdata/ib_logfiles separately, to get around 10Mb limitation in JIRA. Put them back to the datadir. |
| Comments |
| Comment by Marko Mäkelä [ 2018-04-26 ] | |||||||||||||||||||||||||||||||||||
|
The problematic SYS_TABLES clustered index record contents is as follows:
This looks valid to me. The fields MIX_ID, MIX_LEN and CLUSTER_NAME were originally unused and in very old InnoDB versions written as garbage, so for ROW_FORMAT=REDUNDANT we must ignore these fields. The fields were originally intended to be used for mixed clustered indexes, where a clustered index could contain records from multiple tables sharing a similar primary key. The MIX_LEN field was repurposed for additional table flags in the InnoDB Plugin for MySQL 5.1: Applying InnoDB snapshot, fixes BUG#41609. Until MySQL 5.6, the only flag was DICT_TF2_TEMPORARY, intended to suppress warnings about non-found files for temporary tables. (Until MySQL 5.7 and MariaDB 10.2, InnoDB treated temporary tables as persistent ones.) 5.6 introduced further persistently stored flags in SYS_TABLES.MIX_LEN mainly for passing transient information during table creation. The failing debug assertion seems bogus:
The flag DICT_TF2_USE_FILE_PER_TABLE was introduced in SYS_TABLES.MIX_LEN, originally called DICT_TF2_USE_TABLESPACE in MySQL 5.6.5. It does not make sense to store this transient information ("was innodb_file_per_table set at the start of CREATE TABLE?") in a persistent data structure, but that is what was done. Finally, MySQL 5.7.6 introduced this bogus assertion in a change that was approved by me. (My bad, I should have remembered that the flag did not exist before 5.6.) I believe that Oracle does not test upgrades with debug binaries. The fix is simple: remove the bogus debug assertion. We must only ensure that if a table that resides in an .ibd file is rebuilt, it will remain in an .ibd file even if innodb_file_per_table=0:
That actually was the case, after I removed one more failing debug assertion in dict_table_is_file_per_table():
After these removals, the remaining references to DICT_TF2_USE_TABLESPACE look reasonable. It would seem reasonable to stop setting the flag in MIX_LEN altogether, but that would cause trouble when downgrading to earlier versions. So, we should basically treat the flag as garbage. | |||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-04-26 ] | |||||||||||||||||||||||||||||||||||
|
This bug only affected debug builds. Release builds may have been affected before |