debezium实现了一个mysql ddl语法解析器,用来解析ddl语句。debezium在最近会对解析器进行优化,更换mysql语法解析器。为什么debezium mysql connector需要ddl parser?
为什么需要DdlParser
debeizum mysql connector有2个reader,分别用于snapshot和增量订阅。它们内部都用到了ddl parser,充分说明了解析器的重要性。
SnapshotReader启动时会获取所有表的建表语句,使用DdlParser解析所有的建表语句;BinlogReader会对ddl进行监听,发生ddl时,会调用DdlParser解析;
如果没有DdlParser,我们无法获取dbz监听的表的最新schema,无法得到它们的字段类型。如果我们无法获取最新字段类型,那么dbz通过以上2个reader获取到的数据无法转换成正确的record格式,业务方也就无法正常处理数据。
上述的reader场景都会调用MysqlSchema.applyDdl方法,此方法内部会调用DdlParser.parse方法。
mysql对应的解析器是MysqlDdlParser,其重写了parseNextStatement方法
@Override
protected void parseNextStatement(Marker marker) {
if (tokens.matches(DdlTokenizer.COMMENT)) {
parseComment(marker);
} else if (tokens.matches("CREATE")) {
parseCreate(marker);
} else if (tokens.matches("ALTER")) {
parseAlter(marker);
} else if (tokens.matches("DROP")) {
parseDrop(marker);
} else if (tokens.matches("RENAME")) {
parseRename(marker);
} else if (tokens.matches("USE")) {
parseUse(marker);
} else if (tokens.matches("SET")) {
parseSet(marker);
} else if (tokens.matches("INSERT")) {
consumeStatement();
} else if (tokens.matches("DELETE")) {
consumeStatement();
} else {
parseUnknownStatement(marker);
}
}
此方法对于不同的语句,MysqlDdlParser分别作了处理。当然不管怎么处理,最后的目的就是让debezium维护的表结构和数据库的表结构一致(比如字段类型)。
为什么要表结构一致?
当debezium获取到mysql数据时,会创建和数据对应一条记录(record),内容为此次行变更数据。
行数据由多个列组成,每一列都有自己字段类型,debezium获取的记录和行类型需要进行类型转换。记录会根据debezium维护的表结构字段类型,进行正确的类型转换。具体的类型转化器都在MySqlValueConverters类中列出。
正确的字段类型就需要debezium维护的表结构和mysql表结构一致。这也就是为什么需要ddl解析器,解析ddl语法。

426

被折叠的 条评论
为什么被折叠?



