Skip to content

DM: panic in getColsAndValuesOfIdx when processing DML on table with expression index #12739

Description

@verbotenj

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

  1. 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);
  1. Create DM task syncing this table via binlog replication
  2. Trigger any DML (INSERT/UPDATE/DELETE) on the source table
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/dmIssues or PRs related to DM.contributionThis PR is from a community contributor.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions