【问题标题】:Cannot drop index on MySQL Aurora only无法仅在 MySQL Aurora 上删除索引
【发布时间】: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

迄今为止的探索发现

  1. 如果我们在普通 MySQL 5.7 上运行语句 1-11,我们永远不会看到任何错误。

  2. 如果我们在 MySQL Aurora (5.7.mysql_aurora.2.07.2) 上运行语句 1-11,我们总是会看到这个错误。

  3. 如果我们在普通 MySQL 5.7 上运行语句 1-6,然后运行语句 11,我们会看到与上述 #2 相同的错误。

  4. 语句 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


【解决方案1】:

我也遇到了同样的问题。无论如何,我还是通过先删除外键然后删除索引来解决这个问题。

现在,出于原因,我的一位朋友(SQL 架构师)说这看起来像是 MySQL Aurora 中 Bug #17449901 中提到的一个现有问题。

对于foreign_key_checks=0,InnoDB 允许删除外键约束所需的索引,从而将表置于不一致的状态,并导致表加载时发生的外键检查失败。 InnoDB 现在可以防止删除外键约束所需的索引,即使使用foreign_key_checks=0。在删除外键索引之前,必须删除外键约束。

这可能是问题的原因,因为 InnoDB 现在可以防止删除外键约束所需的索引

【讨论】:

  • 我认为你正在做某事。这个错误/相应的修复可能与 Aurora 在这里表现不同的原因有关。我想我不明白为什么语句 7-10 确定它是否在 vanilla MySQL 5.7 中出错。赏金仍然是你的。
  • 另外记录一下,foreign_key_checks=0foreign_key_checks=1 似乎对结果没有影响
  • 我的意思是由于这个修复,InnoDB 现在可以防止删除外键约束所需的索引,这就是导致上述问题仅在 InnoDB 而不是 MySql 上的原因
【解决方案2】:

尝试在 sql 文件的开头禁用密钥检查。

SET FOREIGN_KEY_CHECKS=0;

并在最后启用:

SET FOREIGN_KEY_CHECKS=1;

【讨论】:

  • 这不是关于“如何删除索引”的问题。问题是,为什么它在 Aurora 和 MySQL 上的表现不同。 Sreeram 的回答大概就是指向了答案。
猜你喜欢
  • 2016-11-05
  • 2018-12-13
  • 2019-10-28
  • 2018-05-23
  • 1970-01-01
  • 2013-09-10
  • 2012-01-31
  • 2015-05-30
  • 1970-01-01
相关资源
最近更新 更多