Bug #121102 INPLACE rebuild may corrupt long-prefix secondary indexes
Submitted: 17 Aug 1:29
Reporter: George Ma (OCA) Email Updates:
Status: Open Impact on me:
None 
Category:MySQL Server: DDL Severity:S3 (Non-critical)
Version:9.7.2 OS:Any
Assigned to: CPU Architecture:Any

[17 Aug 1:29] George Ma
Description:
  When rebuilding an InnoDB table with `ALGORITHM=INPLACE`, converting from
  `ROW_FORMAT=REDUNDANT`/`COMPACT` to `DYNAMIC`/`COMPRESSED` can create a corrupt
  secondary index if:

  - an indexed `VARCHAR` or `TEXT` value is externally stored; and
  - the new index prefix needs more than 767 bytes.

  The ALTER succeeds, but the rebuilt index entry is truncated. A later update
  of the primary key cannot delete that entry correctly.

  Debug builds abort; release builds may report successful DML while leaving the
  secondary index corrupt.

How to repeat:
  ```sql
  CREATE TABLE t1 (
    id INT NOT NULL,
    c VARCHAR(1000) CHARACTER SET utf8mb4 NOT NULL,
    -- Add enough fixed-length columns to force c off-page
    PRIMARY KEY (id),
    KEY k_c (c(191))
  ) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;

  INSERT INTO t1 VALUES (1, REPEAT(_utf8mb4 0xF09F9880, 1000));

  ALTER TABLE t1
    ROW_FORMAT=DYNAMIC,
    DROP KEY k_c, ADD KEY k_c (c(768)),
    ALGORITHM=INPLACE;

  UPDATE t1 SET id = 2 WHERE id = 1;
  CHECK TABLE t1;
```

  Expected: the update succeeds and CHECK TABLE returns OK.

  Actual: the old index entry contains only about 767 bytes instead of the
  required 3072 bytes. In release builds, CHECK TABLE reports a corrupt index.