{"record":{"id":"5c05c004bcb8e755","repo":"risingwavelabs/risingwave","slug":"bad-result-from-mysql","errorCode":null,"errorMessage":"bad result from mysql","messagePattern":"bad result from mysql","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/meta/src/rpc/election/sql.rs","lineNumber":366,"sourceCode":"            .await?;\n\n        let query_result = self\n            .conn\n            .query_one(Statement::from_sql_and_values(\n                DatabaseBackend::MySql,\n                format!(\n                    r#\"SELECT service, id, last_heartbeat FROM {table} WHERE service = ?;\"#,\n                    table = Self::election_table_name(),\n                ),\n                vec![Value::from(service_name)],\n            ))\n            .await?;\n\n        let row = query_result\n            .map(|query_result| ElectionRow::from_query_result(&query_result, \"\"))\n            .transpose()?;\n\n        let row = row.ok_or_else(|| anyhow!(\"bad result from mysql\"))?;\n\n        Ok(row)\n    }\n\n    async fn leader(&self, service_name: &str) -> MetaResult<Option<ElectionRow>> {\n        let query_result = self\n            .conn\n            .query_one(Statement::from_sql_and_values(\n                DatabaseBackend::MySql,\n                format!(\n                    r#\"SELECT service, id, last_heartbeat FROM {table} WHERE service = ?;\"#,\n                    table = Self::election_table_name()\n                ),\n                vec![Value::from(service_name)],\n            ))\n            .await?;\n\n        let row = query_result","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/rpc/election/sql.rs#L348-L384","documentation":"Same contract as the sqlite variant: the MySQL-backed election client's try_campaign expects its campaign upsert statement to return exactly one row (the leader row). An empty result is rejected with 'bad result from mysql', meaning the store failed to return the row that should have just been written.","triggerScenarios":"try_campaign on MySqlElectionClient when the campaign query returns zero rows despite executing successfully.","commonSituations":"MySQL server misconfiguration or replication lag wiping the read-back row; using a non-InnoDB table or unusual isolation level for the election table; connection pool pointing at a different database node between write and read.","solutions":["Confirm the election table exists in the configured database and is InnoDB with proper primary key.","Check that all meta nodes point to the same MySQL instance/schema (no split-brain across replicas or proxy).","Inspect MySQL error log and meta logs for lock wait/timeout errors around the campaign time.","Retry election; if persistent, verify mysql_async driver version compatibility."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match client.try_campaign(service, lock_id).await {\n    Err(e) if e.to_string().contains(\"bad result from mysql\") => {\n        // check connectivity to the same primary instance, then retry\n        tokio::time::sleep(Duration::from_secs(1)).await;\n    }\n    other => other?,\n}","preventionTips":["Point all meta nodes at the same MySQL primary (no split-brain proxies or lagging replicas).","Use an InnoDB table with a proper primary key for the election table.","Monitor for lock-wait timeouts on the election table."],"tags":["mysql","election","meta","leader-election"],"backgroundTag":"empty-result-set","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"}