{"record":{"id":"2d8c5316972de642","repo":"apache/seatunnel","slug":"unexpected-error-while-connecting-to-mysql-and-loo-2d8c53","errorCode":null,"errorMessage":"Unexpected error while connecting to MySQL and looking at gtid_purged variable: ","messagePattern":"Unexpected error while connecting to MySQL and looking at gtid_purged variable: ","errorType":"exception","errorClass":"ConnectException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-mysql/src/main/java/io/debezium/connector/mysql/legacy/MySqlJdbcContext.java","lineNumber":341,"sourceCode":"     * Get the purged GTID values from MySQL (gtid_purged value)\n     *\n     * @return A GTID set; may be empty if not using GTIDs or none have been purged yet\n     */\n    public GtidSet purgedGtidSet() {\n        AtomicReference<String> gtidSetStr = new AtomicReference<String>();\n        try {\n            jdbc.query(\n                    \"SELECT @@global.gtid_purged\",\n                    rs -> {\n                        if (rs.next() && rs.getMetaData().getColumnCount() > 0) {\n                            gtidSetStr.set(\n                                    rs.getString(\n                                            1)); // GTID set, may be null, blank, or contain a GTID\n                            // set\n                        }\n                    });\n        } catch (SQLException e) {\n            throw new ConnectException(\n                    \"Unexpected error while connecting to MySQL and looking at gtid_purged variable: \",\n                    e);\n        }\n\n        String result = gtidSetStr.get();\n        if (result == null) {\n            result = \"\";\n        }\n\n        return new GtidSet(result);\n    }\n\n    /**\n     * Determine if the current user has the named privilege. Note that if the user has the \"ALL\"\n     * privilege this method returns {@code true}.\n     *\n     * @param grantName the name of the MySQL privilege; may not be null\n     * @return {@code true} if the user has the named privilege, or {@code false} otherwise","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-mysql/src/main/java/io/debezium/connector/mysql/legacy/MySqlJdbcContext.java#L323-L359","documentation":"MySqlJdbcContext.purgedGtidSet() reads the `gtid_purged` system variable from MySQL to learn which GTIDs have already been purged from the binlogs. An SQLException while querying this variable is wrapped in a ConnectException with this message, preventing the connector from determining a safe restart GTID position.","triggerScenarios":"Calling purgedGtidSet() when the JDBC connection fails, when SHOW VARIABLES LIKE 'gtid_purged' errors, or when reading the result set throws; caught at MySqlJdbcContext.java:341 and rethrown as ConnectException.","commonSituations":"User lacks privileges for SHOW VARIABLES; connection dropped by an idle-timeout middlebox; GTID mode disabled on a replica so the variable query path errors; TLS/protocol mismatch between driver and server; MySQL restarted mid-operation.","solutions":["Read the wrapped SQLException cause to identify the true failure (privilege, timeout, protocol).","Run `SHOW VARIABLES LIKE 'gtid_purged'` with the connector's DB user to confirm access and non-empty results.","Ensure the connector user has the needed privileges (SELECT on mysql.* views or at least SHOW VARIABLES access).","Verify GTID_MODE=ON on the server (and replicas) since purged-GTID logic assumes GTID replication.","Restore connectivity (check host/port/firewall/TLS) and restart the connector task."],"exampleFix":"// before\nthrow new ConnectException(\"Unexpected error while connecting to MySQL and looking at gtid_purged variable: \", e);\n// after: actionable message with host and cause\nthrow new ConnectException(\"Failed to read gtid_purged from \" + hostname() + \": \" + e.getMessage(), e);","handlingStrategy":"validation","validationCode":"// Ensure gtid_purged is readable and GTID is on, before starting:\ntry (Connection c = DriverManager.getConnection(jdbcUrl, user, pass);\n     Statement s = c.createStatement();\n     ResultSet rs = s.executeQuery(\"SHOW VARIABLES WHERE Variable_name IN ('gtid_purged','gtid_mode')\")) {\n    Map<String,String> vars = new HashMap<>();\n    while (rs.next()) vars.put(rs.getString(1), rs.getString(2));\n    if (!\"ON\".equalsIgnoreCase(vars.get(\"gtid_mode\")))\n        throw new IllegalStateException(\"GTID_MODE must be ON\");\n}","typeGuard":"static boolean hasSqlCause(ConnectException ce) {\n    return ce.getCause() instanceof java.sql.SQLException;\n}","tryCatchPattern":"try {\n    engine.start();\n} catch (org.apache.kafka.connect.errors.ConnectException e) {\n    if (e.getMessage().contains(\"gtid_purged\")) {\n        log.error(\"gtid_purged query failed, cause={}\", e.getCause());\n        // fatal if privileges; retry if connection loss\n    } else { throw e; }\n}","preventionTips":["Verify `SHOW VARIABLES LIKE 'gtid_purged'` returns a row using the connector's account.","Enable GTID consistently on master and replicas to avoid variable-related query paths failing.","Validate credentials/TLS with a plain JDBC smoke test before connector deployment.","Watch for MySQL restarts/failovers and restart connector tasks with fresh connections.","Keep the MySQL connector/J driver version aligned with server version."],"tags":["mysql","jdbc","gtid","cdc","sql"],"backgroundTag":"sql-query-failed","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}