Description
DM worker panics with runtime error: index out of range [17] with length 17 when syncing binlog events for a table with an expression index. The issue occurs during causality-key building in the binlog replication phase.
Reproduction
- Create table with expression index on source MySQL:
CREATE TABLE orders (
order_id int NOT NULL AUTO_INCREMENT,
customer_id int NOT NULL,
status int NOT NULL DEFAULT '1',
PRIMARY KEY (order_id),
UNIQUE KEY uk_pending_status ((case when status = 1 then customer_id end)),
KEY idx_customer_id (customer_id)
);
-- Insert or update any row in this table
INSERT INTO orders (customer_id, status) VALUES (1, 1);
- Create DM task syncing this table via binlog replication
- Trigger any DML (INSERT/UPDATE/DELETE) on the source table
- DM worker crashes with panic
Expected behavior
DML events on tables with expression indexes replicate successfully. Virtual/generated columns from index expressions should be excluded from row-value offset mapping.
Actual behavior
panic: runtime error: index out of range [17] with length 17
goroutine 635 [running]:
github.com/pingcap/tiflow/pkg/sqlmodel.getColsAndValuesOfIdx(...)
github.com/pingcap/tiflow/pkg/sqlmodel/utils.go:32
github.com/pingcap/tiflow/pkg/sqlmodel.(*RowChange).getCausalityString(...)
github.com/pingcap/tiflow/pkg/sqlmodel/causality.go:171 +0x8dc
github.com/pingcap/tiflow/pkg/sqlmodel.(*RowChange).CausalityKeys(...)
github.com/pingcap/tiflow/pkg/sqlmodel/causality.go:40 +0x144
github.com/pingcap/tiflow/dm/syncer.(*causality).run(...)
github.com/pingcap/tiflow/dm/syncer/causality.go:83 +0x200
Root cause
Expression indexes (MySQL 8.0+) are implemented as hidden virtual generated columns. The binlog row event contains only real columns (17 entries, offsets 0–16). DM's schema metadata includes the virtual column (offset 17). When getColsAndValuesOfIdx maps index column offsets to row values, it uses schema offsets directly without excluding virtual columns, causing an out-of-bounds index into the 17-entry row array.
Environment
- DM version: v8.5.5 (affects all 8.5.x releases)
- MySQL: 8.0+ (expression indexes support)
Workaround
Drop the expression index on source, or use DM's block-allow-list to skip the table.
Fix
Modify sqlmodel.getColsAndValuesOfIdx to skip virtual/generated columns when mapping schema offsets to row-image value positions. Track which columns are virtual (via schema) and adjust array indexing accordingly.
Description
DM worker panics with
runtime error: index out of range [17] with length 17when syncing binlog events for a table with an expression index. The issue occurs during causality-key building in the binlog replication phase.Reproduction
Expected behavior
DML events on tables with expression indexes replicate successfully. Virtual/generated columns from index expressions should be excluded from row-value offset mapping.
Actual behavior
Root cause
Expression indexes (MySQL 8.0+) are implemented as hidden virtual generated columns. The binlog row event contains only real columns (17 entries, offsets 0–16). DM's schema metadata includes the virtual column (offset 17). When
getColsAndValuesOfIdxmaps index column offsets to row values, it uses schema offsets directly without excluding virtual columns, causing an out-of-bounds index into the 17-entry row array.Environment
Workaround
Drop the expression index on source, or use DM's block-allow-list to skip the table.
Fix
Modify
sqlmodel.getColsAndValuesOfIdxto skip virtual/generated columns when mapping schema offsets to row-image value positions. Track which columns are virtual (via schema) and adjust array indexing accordingly.