[MDEV-23245] Still getting assertion failure in file data0type.cc line 67 Created: 2020-07-21  Updated: 2020-12-16  Resolved: 2020-07-29

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB
Affects Version/s: 10.4.13
Fix Version/s: 10.4.14, 10.5.5

Type: Bug Priority: Critical
Reporter: Simeon Maxein Assignee: Eugene Kosov (Inactive)
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by MDEV-22898 SQL query always crashes on INSERT I... Closed
is duplicated by MDEV-24419 Galera crash after ALTER TABLE conver... Closed
Relates
relates to MDEV-20726 InnoDB: Assertion failure in file dat... Closed
relates to MDEV-23964 MariaDB 10.5.4 and 10.5.6 replica ke... Closed

 Description   

This error is essentially the same as MDEV-20726, except that is still happens for me. I'm running mariadb server version 10.4.13-MariaDB-1:10.4.13+maria~bionic.

Here is a very short example which reproduces the error (Careful - crashes the server and prevents it from restarting!)

CREATE TABLE `Foo`
(
    `Bar` char(2) CHARACTER SET utf8,
    KEY `Bar` (`Bar`(1))
) ENGINE = InnoDB;
 
ALTER TABLE `Foo` MODIFY `Bar` char(2) CHARACTER SET utf8mb4;
 
INSERT INTO Foo VALUES ('a');

At this point the server crashes and cannot restart, always crashing again with the error message "InnoDB: Failing assertion: !(prefix_len % mbmaxlen)".

Observations: The error only occurs if the index is a prefix index. It also doesn't occur if the collation is changed in the ALTER TABLE - going from utf8_bin to utf8mb4_bin triggers the bug, as does going from utf8_general_ci to utf8mb4_general_ci, but when going from utf8_general_ci to utf8mb4_bin it does not occur.



 Comments   
Comment by Marko Mäkelä [ 2020-07-21 ]

I can repeat a debug assertion failure, even after recently fixing MDEV-22771.

10.4 b1538f4d60bf30de00417a7c3f948d2de654fcb3

mysqld: /mariadb/10.4/storage/innobase/data/data0type.cc:64: ulint dtype_get_at_most_n_mbchars(ulint, ulint, ulint, ulint, ulint, const char *): Assertion `!mbmaxlen || !(prefix_len % mbmaxlen)' failed.

Comment by Marko Mäkelä [ 2020-07-21 ]

I see nothing wrong in ha_innobase::can_convert_string(), but I do see a problem that ha_innobase::check_if_supported_inplace_alter() is only invoked with ha_alter_info->handler_flags = HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE | ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE.
Any column prefix indexes on the CHAR column must be rebuilt.
I tried a few variations of the test:

--source include/have_innodb.inc
CREATE TABLE Foo
(
  Bar char(2) CHARACTER SET utf8,
  KEY Bar (Bar
#(1)
  )
) ENGINE = InnoDB;
ALTER TABLE Foo MODIFY Bar char(2) CHARACTER SET utf8mb4;
#--source include/restart_mysqld.inc
#ALTER TABLE Foo ADD lb INT GENERATED ALWAYS AS (length(Bar));
INSERT INTO Foo SET Bar='a';
DROP TABLE Foo;

With the (1) commented out, the test completes successfully. Similarly, if I declare the column as varchar(2) instead of char(2), everything seems to be fine. Also ROW_FORMAT=REDUNDANT seems to be fine.

The commented-out statements are causing the table to be evicted and re-loaded into InnoDB dict_sys. That does not affect the reproducibility.

Comment by Simeon Maxein [ 2020-07-21 ]

For me this also happens if both the initial column definition and the ALTER TABLE specify varchar (though not if one of them specifies varchar and the other char)

Generated at Thu Feb 08 09:20:58 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.