一.发现问题:
调研mycat整合seata的可行性,测试AT模式的demo时,出现以下报错:
java.lang.NullPointerException: null
at io.seata.rm.datasource.sql.struct.TableMeta.getPrimaryKeyMap(TableMeta.java:121) ~[seata-all-1.3.0.jar:1.3.0]
at io.seata.rm.datasource.sql.struct.TableMeta.getPrimaryKeyOnlyName(TableMeta.java:141) ~[seata-all-1.3.0.jar:1.3.0]
at io.seata.rm.datasource.AbstractConnectionProxy.prepareStatement(AbstractConnectionProxy.java:119) ~[seata-all-1.3.0.jar:1.3.0]
中间件版本:
mycat-server:1.6.7.4
seata-server:1.3.0
二.定位问题:
根据异常,加断点debug:
TableMeta.getPrimaryKeyMap
->AbstractConnectionProxy.prepareStatement
//以下逻辑仅第一次获取表结构数据时会进入(seata的AT模式需要创建undolog,log的记录按照原业务表的主键关联,所以需要获取业务表的结构和主键)
AbstractTableMetaCache.getTableMeta
->MysqlTableMetaCache.fetchSchema
->MysqlTableMetaCache.resultSetMetaToSchema
->DatabaseMetaData.getColumns
->DatabaseMetaData.getTables
最终定位到show full tables语句执行报错:
工具连接mycat,直接执行该条sql,果然报错:
三.解决问题:
去github的mycat-server下搜索是否有人提过相关issue,果然有:https://github.com/MyCATApache/Mycat-Server/issues/2570,已在1.6.7.6上修复,下载1.6.7.6版本的mycat-server,启动后用工具再次执行该sql:
提示找不到对应的逻辑库,看下mycat的配置,可见逻辑库名为"seata_test",对应的mysql数据库名为“seata_account”,可发现seata获取表结构时,取得的库是真实数据库(该部分逻辑待跟踪):
临时调整逻辑库名与mysql数据库名一致为“seata_account”来绕过该问题:
重启mycat后用工具再次执行该sql,已能正常查出结果:
启动服务验证,却发现启动服务报错了:
看报错疑似驱动版本问题(mycat-server换回1.6.7.4正常),继续issue上搜问题,https://github.com/MyCATApache/Mycat-Server/issues/2738,根据解决方案把我的mysql版本配置好后,重启服务,正常: