skip to Main Content

My team and I are attempting to upgrade our multi-tenancy AWS RDS/MySQL instance from MySQL 5.7 to 8. After trying the upgrade, we received a report showing a large number of errors for the customers, and lineitems tables.

Example Errors

{
    "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."
},

Note: @007b and @007d equal { and }

Our RDS/MySQL server contains a database for each client we have with the name of the database in the format of {UUID}. Each table may or may not have a customers and/or lineitems table. Each of those tables may or may not contain a FULLTEXT index.

Database Tables
{852f8697-856d-4fb0-9e3f-69f79e0ce59c} customers, lineitems
{466fe859-89c9-42df-95bf-49c600f18b2} lineitems
{47e2eb66-9e5e-429f-8f87-f43638cd6b02} customers
…100s more.

I wrote a Laravel job that fetches the list of databases and then performs the following actions for each of the customers and lineitems tables if they exist:

  • Check for the FULLTEXT index.
  • Drop the FULLTEXT if it exists.
  • Run the query ALTER TABLE <table_name> ENGINE = InnoDB;
  • Run the query OPTIMIZE TABLE <table_name>;

After the job was completed (~5+ hours), we attempted to perform the upgrade again and received a single error.

{
  "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"
},

We’ve been attempting this upgrade for a few weeks now and this is just our latest attempt.

In our previous attempts (Before adding the OPTIMIZE step in the job below), we were receiving a single error like the one above except the .#sql-ib32025827-3477973988 part would be equal to either lineitems or customers. We could manually run the job for that database/table and attempt the upgrade process again, but another singular error would be returned for a different database/table.

Here is the Laravel job handler:

    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;
        }
    }

And this is the query that selects the databases/schemas and creates the jobs.

        $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);
        }

We’re continuing to try different options, but each attempt is taking us anywhere from 4 to 8 hours to run through.

If anyone has any suggestions, it would be greatly appreciated!


Oct 25th update

We were able to run the following command and it returned some results that seemed promising.

SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%#sql-ib32025827-3477973988%';
TABLE_ID NAME FLAG N_COLS SPACE FILE_FORMAT ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE
8990518 @007bb281b00a@002d14bb@002d4097@002daa29@002de9432f2e55db@007d/#sql-ib32025827-3477973988 33 27 8717504 Barracuda Dynamic 0 Single

Based on these results, we attempted to drop the table in various ways, but all our efforts resulted in returning a "table not found" error.

These are a few of our attempts:

As-is

DROP TABLE `@007bb281b00a@002d14bb@002d4097@002daa29@002de9432f2e55db@007d`.`#sql-ib32025827-3477973988`;

Convert encoded characters

DROP TABLE `{b281b00a-14bb-4097-aa29-e9432f2e55db}`.`#sql-ib32025827-3477973988`;

Prepend "#mysql50#" to table name as suggested by AWS

DROP TABLE `{b281b00a-14bb-4097-aa29-e9432f2e55db}`.`#mysql50##sql-ib32025827-3477973988`;

2

Answers


  1. Because the DDL of MySQL 5.7 is not atomic, temporary files are generated. First, deal with these temporary files, then check the upgrade, and finally upgrade.

    Login or Signup to reply.
  2. After reading your issue I can tell you that the sql has created a dangling table. as far as I remember SQL uses B* tree algo to store and retrieve data. So in this case you need to either assign the HEADER (pointer) to the other table or remove it. You can try these steps:

    • Identify and Drop Orphaned Tables
    DROP TEMPORARY TABLE IF EXISTS `@007bb281b00a@002d14bb@002d4097@002daa29@002de9432f2e55db@007d/#sql-ib32025827-3477973988`;
    
    • Run the DROP Command with the Encoded Form and Hashing (recommended by AWS)
    DROP TABLE `@007bb281b00a@002d14bb@002d4097@002daa29@002de9432f2e55db@007d`.`#mysql50##sql-ib32025827-3477973988`;
    

    or you can just recreate affected tables without FULLTEXT Indexes (just a temporary fix)

    CREATE TABLE customers_backup LIKE customers;
    INSERT INTO customers_backup SELECT * FROM customers;
    DROP TABLE customers;
    RENAME TABLE customers_backup TO customers;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search