Bug #121211 InnoDB INPLACE table rebuild corrupts a spatial index after a scan latch release
Submitted: 2 Sep 11:59
Reporter: George Ma (OCA) Email Updates:
Status: Open Impact on me:
None 
Category:MySQL Server: Storage Engines Severity:S3 (Non-critical)
Version:9.7.2 OS:Any
Assigned to: CPU Architecture:Any

[2 Sep 11:59] George Ma
Description:
An INPLACE null rebuild of an InnoDB table that already has a spatial index can
build a corrupt R-tree and abort a debug server.

The issue was reproduced from unmodified MySQL Community Server 9.7.2 source,
commit `008e09c2834b98143a8c067d4d225c90953050cf` (the `mysql-9.7.2` tag and
`upstream/9.7` point to the same commit). The source tree has no local
changes in the InnoDB implementation. It was built with `WITH_DEBUG=ON` and
GCC 13.3.1 on Linux x86_64. The local binary reports `9.7.2-rds-debug`
because of a build-only version suffix; no downstream source patch is involved.
The MTR server configuration uses `--innodb_buffer_pool_size=5M`.

The reproducer was run five times serially. All five runs reached the same
failure. There is no concurrent DML, delete, purge, or schema change while the
rebuild is paused.

`ALTER TABLE ... ENGINE=InnoDB, ALGORITHM=INPLACE` is a supported null rebuild
operation, and the spatial column is declared `NOT NULL` as required for an
InnoDB spatial index. The operation should complete and `CHECK TABLE t1`
should report `OK`. Instead, InnoDB detects records in the wrong order in
`sp_g` and the debug validation aborts the server:

```
[ERROR] [MY-012726] [InnoDB] Records in wrong order on space 7 page 5 index `sp_g`
[ERROR] [MY-012738] [InnoDB] Apparent corruption in space 7 page 5 index `sp_g`
[ERROR] [MY-013050] [InnoDB] In page 5 of index `sp_g` of table `test`.`#sql-...`
[ERROR] [MY-013183] [InnoDB] Assertion failure: ddl0ctx.cc:523:
err != DB_SUCCESS || loader.validate_indexes()

#0  print_fatal_signal
#1  my_server_abort
#2  my_abort
#3  ut_dbg_assertion_failed
#4  ddl::Context::build() at storage/innobase/ddl/ddl0ctx.cc:523
#5  ha_innobase::inplace_alter_table_impl()
```

The R-tree validation output also shows the appended primary-key field reading
as `0x78787878` (`xxxx`), rather than an integer primary-key value. This is
data from the LOB workload, not a valid primary-key value.

How to repeat:
Build a debug MySQL Community Server 9.7.2 server. Start the MTR server with
`--innodb_buffer_pool_size=5M`. The following is the complete test body:

```
--source include/have_debug.inc
--source include/have_debug_sync.inc

CREATE TABLE t1 (
  id INT NOT NULL AUTO_INCREMENT,
  c LONGBLOB,
  pad CHAR(60) NOT NULL,
  g LINESTRING NOT NULL,
  PRIMARY KEY (id),
  SPATIAL KEY sp_g (g)
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;

INSERT INTO t1 (c, pad, g)
VALUES
  (REPEAT('x', 6 * 1024 * 1024), REPEAT('a', 60),
   ST_GeomFromText('LINESTRING(0 0, 1 1, 2 2)')),
  (REPEAT('x', 6 * 1024 * 1024), REPEAT('b', 60),
   ST_GeomFromText('LINESTRING(0 0, 1 1, 2 2)')),
  (REPEAT('x', 6 * 1024 * 1024), REPEAT('c', 60),
   ST_GeomFromText('LINESTRING(0 0, 1 1, 2 2)'));

--connect (con1, localhost, root,,)
SET DEBUG='+d,ddl_buf_add_two';
SET DEBUG_SYNC='ddl_bulk_inserter_latches_released SIGNAL ddl_latches_released WAIT_FOR ddl_continue';
--send ALTER TABLE t1 ENGINE=InnoDB, ALGORITHM=INPLACE

--connection default
SET DEBUG_SYNC='now WAIT_FOR ddl_latches_released';
SET DEBUG_SYNC='now SIGNAL ddl_continue';

--connection con1
--reap
CHECK TABLE t1;
```

The companion MTR option file contains:

```
--innodb_buffer_pool_size=5M
```

On the affected debug build, the client receives:

```
ERROR HY000: Lost connection to MySQL server during query
```

and the server error log contains the corruption messages and assertion shown
in the Description section. Repeating the test serially five times produced the
same assertion in all five runs.

Expected result: the ALTER succeeds and `CHECK TABLE t1` reports `status OK`.

Actual result: the ALTER aborts the debug server after `sp_g` has been built
with invalid key data. On a non-debug build, the same path can leave a corrupt
spatial index instead of stopping at the debug validation assertion.
[2 Sep 12:03] George Ma
Test case

Attachment: bug_121211.patch (application/octet-stream, text), 1.95 KiB.