【发布时间】:2021-02-24 03:57:52
【问题描述】:
背景
我们运行托管供应商产品的 MySQL Aurora (5.7.mysql_aurora.2.07.2)。供应商为其版本升级提供迁移 SQL 脚本。
我们遇到了一个问题,即迁移无法在 MySQL Aurora 上成功运行,但可以在其他 MySQL 5.7 数据库上运行,我们真的很想知道为什么只会在 Aurora 中发生这种情况。
详情
-- 1
DROP DATABASE IF EXISTS drop_index_test;
-- 2
CREATE DATABASE IF NOT EXISTS drop_index_test DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci;
-- 3
use drop_index_test;
-- 4
CREATE TABLE msg
(
id BIGINT AUTO_INCREMENT NOT NULL,
uuid VARCHAR(36) NOT NULL,
user_id VARCHAR(36),
title LONGTEXT,
CONSTRAINT pk_msg PRIMARY KEY (id),
CONSTRAINT uq_msg_uuid UNIQUE (uuid)
);
-- 5
CREATE TABLE ack
(
id BIGINT AUTO_INCREMENT NOT NULL,
msg_id BIGINT NOT NULL,
user_id VARCHAR(36) NOT NULL,
CONSTRAINT pk_ack PRIMARY KEY (id),
CONSTRAINT fk_ack2msg_01 FOREIGN KEY (msg_id) REFERENCES msg (id)
);
-- 6
CREATE UNIQUE INDEX ix_ack_mid_uid
ON ack (msg_id, user_id);
-- 7
ALTER TABLE msg
ADD user_id_upper VARCHAR(36) AS (UPPER(user_id));
-- 8
CREATE INDEX ix_msg_upper_user_id ON msg(user_id_upper);
-- 9
ALTER TABLE ack
ADD user_id_upper VARCHAR(36) AS (UPPER(user_id));
-- 10
CREATE UNIQUE INDEX ix_ack_mid_upper_uid
ON ack (msg_id, user_id_upper);
-- 11
DROP INDEX ix_ack_mid_uid ON ack;
以上是语句的精简版本,仍然仅在 Aurora 上复制此问题,并且仍然在“香草”MySQL 5.7 中工作(测试了 brew install、RDS 实例和来自 Docker Hub 的 mysql/mysql-server:5.7)。语句 1-6 是初始设置语句,7-11 是导致以下错误的迁移语句。
错误
ERROR 1553 (HY000): Cannot drop index 'ix_ack_mid_uid': needed in a foreign key constraint
迄今为止的探索发现
-
如果我们在普通 MySQL 5.7 上运行语句 1-11,我们永远不会看到任何错误。
-
如果我们在 MySQL Aurora (5.7.mysql_aurora.2.07.2) 上运行语句 1-11,我们总是会看到这个错误。
-
如果我们在普通 MySQL 5.7 上运行语句 1-6,然后运行语句 11,我们会看到与上述 #2 相同的错误。
-
语句 7-10 是确定此错误与否的关键区别。没有 7-10 vanilla MySQL 5.7 会抛出与 Aurora 相同的
Cannot drop index错误。无论第 7-10 行是否存在,Aurora 都会引发此错误。
问题陈述
此问题的根本原因可能是什么?这是 Aurora 中的错误还是已知的版本差异或我们端潜在的 Aurora 配置错误?
语句 7-10 如何影响索引 ix_ack_nid_uid 可以在 MySQL 5.7 中删除,当它们似乎没有触及该索引时?为什么同样不会影响 Aurora?
【问题讨论】:
-
只是为了澄清,我不是在寻求帮助删除索引。我正在寻找关于为什么这个错误可能发生在 Aurora 而不是其他 vanilla MySQL 实例上的说明。
-
(与问题无关)UUID 也可以是
CHARACTER SET ascii COLLATE ascii_general_ci;这消除了 utf8 的开销并处理大小写折叠,从而消除(我猜)对UPPER()的需求。最好将它们转换为BINARY(16);如有必要,我可以详细说明。 -
在多对多表上使用
id会适得其反。更多详情:mysql.rjweb.org/doc.php/… -
@RickJames,干杯,确实与问题无关。此外,ID 在全表定义中也不会适得其反。这实际上不是多对多表,我刚刚删除了不影响手头问题的列数组。
标签: mysql database-administration amazon-aurora