{"record":{"id":"7030f1264d0212c7","repo":"vitessio/vitess","slug":"can-t-set-charset-for-statement-d-in-transaction","errorCode":null,"errorMessage":"can't set charset for statement %d in transaction %v: %v","messagePattern":"can't set charset for statement (.+?) in transaction (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/binlog/binlogplayer/binlog_player.go","lineNumber":466,"sourceCode":"\t\t// Make sure the statement is replayed in the proper charset.\n\t\tif dbClient, ok := blp.dbClient.(*dbClientImpl); ok {\n\t\t\tvar stmtCharset *binlogdatapb.Charset\n\t\t\tif stmt.Charset != nil {\n\t\t\t\tstmtCharset = stmt.Charset\n\t\t\t} else {\n\t\t\t\t// Streamer sends a nil Charset for statements that use the\n\t\t\t\t// charset we specified in the request.\n\t\t\t\tstmtCharset = blp.defaultCharset\n\t\t\t}\n\t\t\tif !proto.Equal(blp.currentCharset, stmtCharset) {\n\t\t\t\t// In regular MySQL replication, the charset is silently adjusted as\n\t\t\t\t// needed during event playback. Here we also adjust so that playback\n\t\t\t\t// proceeds, but in Vitess-land this usually means a misconfigured\n\t\t\t\t// server or a misbehaving client, so we spam the logs with warnings.\n\t\t\t\tlog.Warn(fmt.Sprintf(\"BinlogPlayer changing charset from %v to %v for statement %d in transaction %v\", blp.currentCharset, stmtCharset, i, tx))\n\t\t\t\terr = mysql.SetCharset(dbClient.dbConn, stmtCharset)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn false, fmt.Errorf(\"can't set charset for statement %d in transaction %v: %v\", i, tx, err)\n\t\t\t\t}\n\t\t\t\tblp.currentCharset = stmtCharset\n\t\t\t}\n\t\t}\n\t\tif _, err = blp.exec(string(stmt.Sql)); err == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif sqlErr, ok := err.(*sqlerror.SQLError); ok && sqlErr.Number() == sqlerror.ERLockDeadlock {\n\t\t\t// Deadlock: ask for retry\n\t\t\tlog.Info(fmt.Sprintf(\"Deadlock: %v\", err))\n\t\t\tif err = blp.dbClient.Rollback(); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\treturn false, nil\n\t\t}\n\t\t_ = blp.dbClient.Rollback()\n\t\treturn false, err\n\t}","sourceCodeStart":448,"sourceCodeEnd":484,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/binlog/binlogplayer/binlog_player.go#L448-L484","documentation":"Thrown by processTransaction when mysql.SetCharset fails while trying to switch the target connection's charset so a statement replays with the same charset it was logged with. Without this, statement text could be misinterpreted, so the transaction is aborted rather than replayed with wrong encoding.","triggerScenarios":"mysql.SetCharset(dbClient.dbConn, stmtCharset) errors: the requested charset/collation doesn't exist on the target MySQL version, the connection is broken, or the source logged a charset the target server was not compiled/configured with.","commonSituations":"Replicating from MySQL 8 (utf8mb4 variants, newer collations like utf8mb4_0900_ai_ci) to an older target that lacks them; source and target MySQL versions diverged; connection dropped mid-transaction.","solutions":["Verify the charset/collation exists on the target: `SHOW COLLATION LIKE '<from logged stmtCharset>'`.","Upgrade the target MySQL/Vitess version to support the source's charsets, or convert source tables to charsets the target supports.","Ensure target server character-set config includes the needed charsets (`character_set_server`, available charsets).","If the connection is the issue, restart the stream for a fresh dbConn."],"exampleFix":"// before: target lacks utf8mb4_0900_ai_ci\n//   mysql.SetCharset(dbConn, stmtCharset) // ER_UNKNOWN_COLLATION\n// after: upgrade target or align source\n//   ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- on source","handlingStrategy":"validation","validationCode":"// verify the source's charsets exist on the target before streaming\nfor _, cs := range sourceCharsets { // e.g. utf8mb4_0900_ai_ci\n    var n int\n    if err := targetDB.QueryRow(\n        \"SELECT COUNT(*) FROM information_schema.COLLATIONS WHERE COLLATION_NAME = ?\", cs,\n    ).Scan(&n); err != nil || n == 0 {\n        return fmt.Errorf(\"target lacks collation %s: binlog replay would fail\", cs)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Align source and target MySQL major versions (utf8mb4_0900_* needs MySQL 8+)","Convert source tables to charsets the target supports before replicating","Check SHOW COLLATION on the target covers all source collations in use"],"tags":["mysql","charset","binlog-replay","version-compat"],"backgroundTag":"charset-mismatch","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}