MySQL 5.7升级到8遇到问题:由于bug,表上FTS索引的辅助表创建在系统表空间中

问题描述 投票:0回答:1

我和我的团队正在尝试将我们的多租户 AWS RDS/MySQL 实例从 MySQL 5.7 升级到 8。尝试升级后,我们收到一份报告,显示客户和 lineitems 表存在大量错误。

错误示例

{
    "level": "Error",
    "dbObject": "@[email protected]",
    "description": " The auxiliary tables of FTS indexes on the table '@[email protected]' are created in system table-space due to https://bugs.mysql.com/bug.php?id=72132. In MySQL8.0, DDL queries executed on this table shall cause database unavailability. To avoid that, drop and recreate all the FTS indexes on the table or rebuild the table using ALTER TABLE query before the upgrade."
},

{
    "level": "Error",
    "dbObject": "@[email protected]",
    "description": " The auxiliary tables of FTS indexes on the table '@[email protected]' are created in system table-space due to https://bugs.mysql.com/bug.php?id=72132. In MySQL8.0, DDL queries executed on this table shall cause database unavailability. To avoid that, drop and recreate all the FTS indexes on the table or rebuild the table using ALTER TABLE query before the upgrade."
},

注意:

@007b
@007d
等于
{
}

我们的 RDS/MySQL 服务器包含每个客户端的数据库,数据库名称的格式为

{UUID}
。每个表可能有也可能没有客户和/或行项目表。每个表可能包含也可能不包含
FULLTEXT
索引。

数据库 桌子
{852f8697-856d-4fb0-9e3f-69f79e0ce59c}
客户、订单项
{466fe859-89c9-42df-95bf-49c600f18b2}
行项目
{47e2eb66-9e5e-429f-8f87-f43638cd6b02}
顾客
...100 多。 ...

我编写了一个 Laravel 作业,用于获取数据库列表,然后对每个客户和 lineitems 表(如果存在)执行以下操作:

  • 检查
    FULLTEXT
    索引。
  • 删除
    FULLTEXT
    (如果存在)。
  • 运行查询
    ALTER TABLE <table_name> ENGINE = InnoDB;
  • 运行查询
    OPTIMIZE TABLE <table_name>;

作业完成后(约 5 个多小时),我们尝试再次执行升级,但收到一个错误。

{
  "id": "auroraGetDanglingFulltextIndex",
  "title": "Tables with dangling FULLTEXT index reference",
  "status": "ERROR",
  "description": "Table '@007bb281b00a-14bb-4097-aa29-e9432f2e55db@007d.#sql-ib32025827-3477973988' doesn't exist"
},

我们已经尝试此升级几周了,这只是我们的最新尝试。

在我们之前的尝试中(在下面的作业中添加

OPTIMIZE
步骤之前),我们收到了与上面类似的单个错误,除了
.#sql-ib32025827-3477973988
部分等于
lineitems
customers
之外。我们可以手动运行该数据库/表的作业并再次尝试升级过程,但对于不同的数据库/表将返回另一个奇异错误。

这是 Laravel 作业处理程序:

    public function handle()
    {
        try {
            config([
                'database.connections.auto_master.database' => $this->database,
            ]);

            DB::purge('auto_master');

            // Attempt to reconnect to the database 5 times with a 100ms delay
            retry(
                5,
                function () {
                    DB::reconnect('auto_master');
                },
                100
            );

            $customersTableExists = Schema::connection('auto_master')->hasTable(
                'customers'
            );

            $nameIndexExists =
                $customersTableExists &&
                DB::select('SHOW INDEX FROM customers WHERE Key_name = ?', [
                    'name',
                ]);

            if ($customersTableExists) {
                Schema::connection('auto_master')->table('customers', function (
                    Blueprint $table
                ) use ($nameIndexExists) {
                    if ($nameIndexExists) {
                        $table->dropIndex('name');
                    }

                    // $table->fullText(['FirstName', 'LastName'], 'name');
                });

                DB::connection('auto_master')->statement(
                    'ALTER TABLE customers ENGINE = InnoDB;'
                );

                // Run Optimize Table to rebuild the table and fix the FTS index
                DB::connection('auto_master')->statement(
                    'OPTIMIZE TABLE customers;'
                );
            }

            $lineitemsTableExists = Schema::connection('auto_master')->hasTable(
                'lineitems'
            );

            $lineitemsDescriptionFullIndexExists =
                $lineitemsTableExists &&
                DB::select('SHOW INDEX FROM lineitems WHERE Key_name = ?', [
                    'lineitems_description_full',
                ]);

            if ($lineitemsTableExists) {
                Schema::connection('auto_master')->table('lineitems', function (
                    Blueprint $table
                ) use ($lineitemsDescriptionFullIndexExists) {
                    if ($lineitemsDescriptionFullIndexExists) {
                        $table->dropIndex('lineitems_description_full');
                    }

                    // $table->fullText('description', 'lineitems_description_full');
                });

                DB::connection('auto_master')->statement(
                    'ALTER TABLE lineitems ENGINE = InnoDB;'
                );

                // Run Optimize Table to rebuild the table and fix the FTS index
                DB::connection('auto_master')->statement(
                    'OPTIMIZE TABLE lineitems;'
                );
            }
        } catch (Throwable $th) {
            // Log the error

            throw $th;
        }
    }

这是选择数据库/模式并创建作业的查询。

        $databases = DB::select('SHOW DATABASES');

        $databasesFiltered = array_filter($databases, function ($database) use (
            $schema
        ) {
            if ($schema) {
                return $database->Database === $schema;
            }

            return preg_match('/^\{[a-f0-9\-]+\}$/', $database->Database);
        });

        foreach ($databasesFiltered as $database) {
            FixAuxBugForInnoDBFTSIndexesJob::dispatch($database->Database);
        }

我们正在继续尝试不同的选项,但每次尝试都会花费我们 4 到 8 个小时才能完成。

如果有人有任何建议,我们将不胜感激!

mysql amazon-rds amazon-aurora mysql-5.7 mysql-8.3
1个回答
0
投票

由于MySQL 5.7的DDL不是原子的,所以会生成临时文件。首先处理这些临时文件,然后检查升级,最后升级。

© www.soinside.com 2019 - 2024. All rights reserved.