Since MariaDB first claimed to be a “drop-in replacement for MySQL”, I knew that claim wouldn’t age well. It hasn’t – the list of incompatibilities between various MySQL and MariaDB verions grows larger and larger over time, now requiring a dedicated page to compare two specific recent releases. Despite that, I largely operated under the assumption that basic, general use cases would see no difference.
I was wrong.
This past week, I was “helping” with a Support issue where installation of Cloudera Manager failed on MariaDB 10.2. Like many products, the schema for Cloudera Manager has evolved over releases, and new installs apply both the original schema and version-specific updates to bring the schema to a current version. When it failed, I reviewed the scripts and found nothing that should cause problems. A fantastic Support colleague (thanks Michalis!) dug in deeper, and – contradicting my assumptions – found that the root problem was an incompatible change made in MariaDB 10.2.8. This causes ALTER TABLE … DROP COLUMN commands to fail in MariaDB 10.2.8, which do not fail in any MySQL version, nor in any previous MariaDB version – including 10.2.7.
When dropping a column that’s part of a composite unique constraint, MariaDB throws error 1072. Here’s an example:
MariaDB [test]> SHOW CREATE TABLE uc_test\G
*************************** 1. row ***************************
Create Table: CREATE TABLE `uc_test` (
`a` int(11) NOT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
PRIMARY KEY (`a`),
UNIQUE KEY `b` (`b`,`c`),
UNIQUE KEY `d` (`d`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
MariaDB [test]> ALTER TABLE uc_test DROP COLUMN c;
ERROR 1072 (42000): Key column ‘c’ doesn’t exist in table
MariaDB [test]> ALTER TABLE uc_test DROP COLUMN b;
ERROR 1072 (42000): Key column ‘b’ doesn’t exist in table
This differs from previous version behavior, as well as MySQL, which does one of two things:
- Narrows the UNIQUE constraint to the remaining columns (surely not ideal, Bug#17098).
- Rejects the change if the resulting narrowed UNIQUE constraint is violated.
While narrowing the existing UNIQUE constraint seems inappropriate, at least MySQL provides a useful and appropriate error message as a result:
mysql> INSERT INto uc_test values (1,1,1,1),(2,1,2,2);
Query OK, 2 rows affected (0.17 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> alter table uc_test DROP COLUMN c;
ERROR 1062 (23000): Duplicate entry ‘1’ for key ‘b’
I agree with the suggestion in the MySQL bug report that a more appropriate action would be to drop the entire UNIQUE constraint in which the dropped column appeared.
MariaDB elected to go a different route. This behavior change was triggered by the work done in MDEV-11114, which explicitly identified a defect in MariaDB’s CHECK CONSTRAINT feature. As the CHECK CONSTRAINT feature is not found upstream, neither was this defect, which failed to drop constraints declared independent of the column definition when the related column was dropped. Rather than restrict the fix to the problematic CHECK CONSTRAINT code, MariaDB developers elected to impose new restrictions on all CONSTRAINTS – despite a very clearly-articulated comment from Mike Bayer documenting the incompatibilities this would trigger. MariaDB also elected to make this change in a maintenance release instead of a minor version upgrade. As a result, SQL scripts – like that used by Cloudera Manager – fail using MariaDB 10.2.8, while they did not in 10.2.7.
Note that I have not tested this behavior in a replication stream – I presume it breaks replication from any MySQL or MariaDB version to 10.2.8+. That’s an even bigger issue for many deployments.
MariaDB has an opportunity – and I’d argue an obligation – to avoid introducing such incompatibilities in maintenance releases. As somebody supporting enterprise products built to use relational databases such as MariaDB, we need to have confidence that maintenance release upgrades won’t break products relying on those services. Ignoring the promise of being a “drop in replacement”, the consequences of this change were known in advance, yet MariaDB chose to pursue it in a maintenance release. There are two real, underlying bugs – the CHECK CONSTRAINT defect introduced by MariaDB, which should have been fixed without impact to other functionality, and the long-standing MySQL defect that triggers constraint narrowing. SQL standards compliance is a viable reason for behavior changes, but such should be done at minor releases only.
I also object to MariaDB’s decision to repurpose an existing MySQL error code for this purpose. I agree with Elena’s comment that more meaningful error messages are required. This is new error-generating behavior, and should have a unique, new error code and message to accompany it for troubleshooting purposes. This is particularly important when the behavior deviates from established historical behavior.
I’m all for MariaDB developing their own value-add features for MySQL Server. Defects found in such features should be fixed without impacting common behavior, though.