Spring Boot+Debezium同步MySQL DDL遇1046错误:未选择数据库
解决方案
核心问题
JdbcTemplate默认每次执行SQL时会从连接池中获取新连接,USE A;在一个连接上切换了数据库,但后续执行CREATE TABLE B;时用了另一个未切换库的连接,导致"未选择数据库"错误——本质是跨连接丢失了数据库上下文。
方案1:在同一个连接中执行关联SQL组
将拆分后的USE和后续DDL放在同一个数据库连接里执行,确保上下文延续。用JdbcTemplate的ConnectionCallback可实现:
jdbcTemplate.execute((Connection conn) -> { try (Statement stmt = conn.createStatement()) { // 先执行USE切换数据库 stmt.execute("USE A;"); // 再执行CREATE TABLE语句 stmt.execute("CREATE TABLE B (id INT PRIMARY KEY AUTO_INCREMENT);"); return null; } catch (SQLException e) { throw new RuntimeException("DDL执行失败", e); } });
两条语句在同一个连接内执行,USE的上下文会被保留,不会出现无库选择的错误。
方案2:让Debezium返回原始未拆分的DDL语句
Debezium默认会解析DDL并拆分为多条语句,你可以通过配置让它保留原始SQL语句,直接执行CREATE TABLE A.B;而非拆分后的语句:
在Debezium MySQL连接器的配置中添加:
# 开启原始SQL记录 include.query=true # 禁用DDL解析(若不需要Debezium解析表结构可开启) ddl.parser.mode=NONE
之后从Debezium事件中提取query字段(原始完整SQL),直接用JdbcTemplate执行这条DDL,就无需处理拆分后的USE语句了。这个方案最贴合你的需求——不用修改DDL,也无需指定固定schema。
方案3:调整Debezium解析规则(进阶)
如果需要Debezium解析DDL但不想拆分带库名的语句,可以尝试调整database.history相关配置,或使用transforms重构DDL,但相比前两个方案复杂度更高,不优先推荐。
内容的提问来源于stack exchange,提问作者arsenics
相关产品推荐
相关产品推荐

