{"record":{"id":"62cbeb4952af8e9d","repo":"risingwavelabs/risingwave","slug":"primary-key-column-column-name-not-found-in-up","errorCode":null,"errorMessage":"primary key column `{column_name}` not found in upstream MySQL primary key info","messagePattern":"primary key column `(.+?)` not found in upstream MySQL primary key info","errorType":"exception","errorClass":"ConnectorError","httpStatus":null,"severity":"error","filePath":"src/connector/src/source/cdc/external/mysql.rs","lineNumber":661,"sourceCode":"\n        drop(conn);\n\n        Ok(column_infos)\n    }\n\n    /// Check whether a column is `BIGINT UNSIGNED`.\n    ///\n    /// Frontend up-casts narrower unsigned integer types, and non-integer unsigned types\n    /// (`FLOAT`/`DOUBLE`/`DECIMAL UNSIGNED`) keep their own comparison semantics. Only\n    /// `BIGINT UNSIGNED` can be represented as a negative `i64` in RisingWave and needs\n    /// unsigned `u64` comparison/conversion.\n    fn needs_unsigned_i64_compare(&self, column_name: &str) -> ConnectorResult<bool> {\n        self.upstream_mysql_pk_infos\n            .iter()\n            .find(|(col_name, _)| col_name.eq_ignore_ascii_case(column_name))\n            .map(|(_, col_type)| mysql_type_is_unsigned_bigint(col_type))\n            .ok_or_else(|| {\n                anyhow!(\n                    \"primary key column `{column_name}` not found in upstream MySQL primary key info\"\n                )\n                .into()\n            })\n    }\n\n    /// For each given primary key column (by name), whether it needs unsigned `i64` comparison.\n    pub(crate) fn pk_column_unsigned_i64_compare_flags(\n        &self,\n        pk_names: &[String],\n    ) -> ConnectorResult<Vec<bool>> {\n        pk_names\n            .iter()\n            .map(|name| self.needs_unsigned_i64_compare(name))\n            .collect()\n    }\n\n    /// Convert negative i64 to unsigned u64 based on column type","sourceCodeStart":643,"sourceCodeEnd":679,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/source/cdc/external/mysql.rs#L643-L679","documentation":"During CDC snapshot reads, RisingWave builds a key-range comparison strategy for the table's primary key columns. It looks up each PK column in `upstream_mysql_pk_infos` (fetched from MySQL) using case-insensitive name matching; if a requested PK column is absent from that metadata, this error is thrown. It almost always means the upstream PK metadata is stale, incomplete, or was populated for a different table/column set.","triggerScenarios":"Calling `needs_unsigned_i64_compare` (via `pk_column_unsigned_i64_compare_flags` or `snapshot_read_inner`) with a column name that does not appear in `self.upstream_mysql_pk_infos` — e.g. the table's PK was altered after the CDC table was created, or the upstream info list was populated from a different table or a filtered schema.","commonSituations":"Altering the MySQL table's primary key while a CDC table exists; renaming a PK column upstream; pointing the CDC source at a table whose PK info was cached from another table; case-only naming differences not handled because upstream info itself is missing the column.","solutions":["Re-create or refresh the CDC table so `upstream_mysql_pk_infos` is re-fetched from the current MySQL schema.","Verify the upstream table actually has the expected primary key with `SHOW KEYS FROM <table> / information_schema.KEY_COLUMN_USAGE`.","Check the CDC table definition's PK columns match the upstream table's PK columns exactly.","If the upstream PK was altered, pause ingestion, align the RW table schema, then resume or rebuild the table."],"exampleFix":"// before (stale upstream pk infos for a table whose PK changed in MySQL)\nALTER TABLE orders DROP PRIMARY KEY, ADD PRIMARY KEY (order_uuid);\n// RW CDC table still has upstream_mysql_pk_infos for ('id')\n// after: rebuild the CDC table so PK info is refreshed\nDROP TABLE rw_orders;\nCREATE TABLE rw_orders (...) WITH (connector = 'mysql-cdc', table_name = 'orders');","handlingStrategy":"validation","validationCode":"// Before creating the CDC table, confirm RW PK columns match upstream MySQL PK info\nlet upstream_pk_names: Vec<String> = upstream_mysql_pk_infos.iter().map(|(c, _)| c.to_ascii_lowercase()).collect();\nfor col in rw_pk_columns {\n    assert!(upstream_pk_names.contains(&col.to_ascii_lowercase()), \"PK column {col} missing from upstream MySQL PK info\");\n}","typeGuard":null,"tryCatchPattern":"match needs_unsigned_i64_compare(col) {\n    Ok(flag) => flag,\n    Err(_) => { refresh_upstream_pk_infos_and_retry()? }\n}","preventionTips":["Avoid altering MySQL primary keys while a CDC table is active.","Re-create CDC tables after upstream PK changes.","Assert PK column parity between RisingWave and MySQL in deployment scripts."],"tags":["cdc","mysql","schema-mismatch","primary-key"],"backgroundTag":"resource-not-found","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}