DistSQL:像数据库一样使用 Apache ShardingSphere

@zjcnb 能再帮忙看下这个问题吗?image
我在ss-proxy端添加了source,但是java-sharding-jdbc客户端拿到的jdbcurl为null,用户名密码是能拿到的。我是哪个环节出了问题?

@zjcnb 上面的问题解决了,要配置schemaName
但是现在又有如下错误:

Error querying database. Cause: java.lang.NullPointerException: Can not find transaction manager of XA

The error may exist in com/xieyc/sharding/mapper/OrderMapper.java (best guess)

The error may involve com.xieyc.sharding.mapper.OrderMapper.selectList

The error occurred while executing a query

Cause: java.lang.NullPointerException: Can not find transaction manager of XA] with root cause

java.lang.NullPointerException: Can not find transaction manager of XA
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:987) ~[guava-30.0-jre.jar:na]
at org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine.getTransactionManager(ShardingSphereTransactionManagerEngine.java:87) ~[shardingsphere-transaction-core-5.1.0.jar:5.1.0]
at org.apache.shardingsphere.transaction.ConnectionTransaction.(ConnectionTransaction.java:49) ~[shardingsphere-transaction-core-5.1.0.jar:5.1.0]
at org.apache.shardingsphere.transaction.ConnectionTransaction.(ConnectionTransaction.java:44) ~[shardingsphere-transaction-core-5.1.0.jar:5.1.0]
at org.apache.shardingsphere.driver.jdbc.core.connection.ConnectionManager.lambda$createConnectionTransaction$0(ConnectionManager.java:135) ~[shardingsphere-jdbc-core-5.1.0.jar:5.1.0]
at java.base/java.util.Optional.map(Optional.java:265) ~[na:na]
at org.apache.shardingsphere.driver.jdbc.core.connection.ConnectionManager.createConnectionTransaction(ConnectionManager.java:135) ~[shardingsphere-jdbc-core-5.1.0.jar:5.1.0]
at org.apache.shardingsphere.driver.jdbc.core.connection.ConnectionManager.(ConnectionManager.java:86) ~[shardingsphere-jdbc-core-5.1.0.jar:5.1.0]
at org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection.(ShardingSphereConnection.java:60) ~[shardingsphere-jdbc-core-5.1.0.jar:5.1.0]
at org.apache.shardingsphere.driver.state.ok.OKDriverState.getConnection(OKDriverState.java:33) ~[shardingsphere-jdbc-core-5.1.0.jar:5.1.0]
at org.apache.shardingsphere.driver.state.DriverStateContext.getConnection(DriverStateContext.java:48) ~[shardingsphere-jdbc-core-5.1.0.jar:5.1.0]
at org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource.getConnection(ShardingSphereDataSource.java:86) ~[shardingsphere-jdbc-core-5.1.0.jar:5.1.0]
at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:158) ~[spring-jdbc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:116) ~[spring-jdbc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:79) ~[spring-jdbc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) ~[mybatis-spring-2.0.6.jar:2.0.6]
at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) ~[mybatis-spring-2.0.6.jar:2.0.6]
at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:337) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:86) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:89) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:151) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:145) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140) ~[mybatis-3.5.9.jar:3.5.9]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427) ~[mybatis-spring-2.0.6.jar:2.0.6]
at com.sun.proxy.$Proxy204.selectList(Unknown Source) ~[na:na]
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) ~[mybatis-spring-2.0.6.jar:2.0.6]
at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForMany(MybatisMapperMethod.java:166) ~[mybatis-plus-core-3.5.1.jar:3.5.1]
at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:77) ~[mybatis-plus-core-3.5.1.jar:3.5.1]
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148) ~[mybatis-plus-core-3.5.1.jar:3.5.1]
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89) ~[mybatis-plus-core-3.5.1.jar:3.5.1]
at com.sun.proxy.$Proxy205.selectList(Unknown Source) ~[na:na]
at com.xieyc.sharding.service.impl.OrderServiceImpl.list(OrderServiceImpl.java:19) ~[classes/:na]
at com.xieyc.sharding.controller.OrderController.list(OrderController.java:21) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.34.jar:9.0.34]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.34.jar:9.0.34]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

麻烦提供下配置, server.yaml 以及其它的关于 ShardingSphere 的配置文件

@zjcnb
sharding-jdbc配置:

spring:
  shardingsphere:
    schema:
      name: sharding_db
    mode:
      type: Cluster
      repository:
        type: ZooKeeper
        props:
          namespace: governance_ds
          server-lists: localhost:2181
          retryIntervalMilliseconds: 500
          timeToLiveSeconds: 60
          maxRetries: 3
          operationTimeoutMilliseconds: 500
      overwrite: false

server.yml配置:

mode:
  type: Cluster
  repository:
    type: ZooKeeper
    props:
      namespace: governance_ds
      server-lists: localhost:2181
      retryIntervalMilliseconds: 500
      timeToLiveSeconds: 60
      maxRetries: 3
      operationTimeoutMilliseconds: 500
  overwrite: false

rules:
  - !AUTHORITY
    users:
      - root@%:root
      - sharding@:sharding
    provider:
      type: ALL_PRIVILEGES_PERMITTED
  - !TRANSACTION
    defaultType: XA
    providerType: Atomikos
  - !SQL_PARSER
    sqlCommentParseEnabled: true
    sqlStatementCache:
      initialCapacity: 2000
      maximumSize: 65535
      concurrencyLevel: 4
    parseTreeCache:
      initialCapacity: 128
      maximumSize: 1024
      concurrencyLevel: 4

props:
  max-connections-size-per-query: 1
  kernel-executor-size: 16  # Infinite by default.
  proxy-frontend-flush-threshold: 128  # The default value is 128.
  proxy-opentracing-enabled: false
  proxy-hint-enabled: true
  sql-show: false
  check-table-metadata-enabled: false
  show-process-list-enabled: false
    # Proxy backend query fetch size. A larger value may increase the memory usage of ShardingSphere Proxy.
    # The default value is -1, which means set the minimum value for different JDBC drivers.
  proxy-backend-query-fetch-size: -1
  check-duplicate-table-enabled: false
  proxy-frontend-executor-size: 0 # Proxy frontend executor size. The default value is 0, which means let Netty decide.
    # Available options of proxy backend executor suitable: OLAP(default), OLTP. The OLTP option may reduce time cost of writing packets to client, but it may increase the latency of SQL execution
    # and block other clients if client connections are more than `proxy-frontend-executor-size`, especially executing slow SQL.
  proxy-backend-executor-suitable: OLAP
  proxy-frontend-max-connections: 0 # Less than or equal to 0 means no limitation.
  sql-federation-enabled: false
    # Available proxy backend driver type: JDBC (default), ExperimentalVertx
  proxy-backend-driver-type: JDBC

@zjcnb 大佬,怎么说?看了没有

  1. 您的 server.yamlconfig-sharding.yaml 是不是复制错了?
  2. 如果您不打算使用 XA 事务的话, 可以将 :
 - !TRANSACTION
    defaultType: XA
    providerType: Atomikos

注释掉. 并且把 Zookeeper 上的配置修改下.

@zjcnb 能加个微信或者QQ吗?比较急

说下您的微信吧.

@zjcnb lsf520forever

@SphereEx官方君 @zjcnb 我看文档 RAL :: ShardingSphere 这里用(set sharding hint database_value = yy 针对当前连接,设置 hint 仅对数据库分片有效,并添加分片值,yy:数据库分片值 set sharding hint database_value = 100) 指定数据库分片字段。然后我在 proxy的配置中,启用了hit(proxy-hint-enabled: true),在java代码中 mybitsplus 执行的地方,改写了sql(String newSql = "set sharding hint database_value = demo_ds_0; " + oldSql;),但是执行好像没有返回数据。

您好, 方便提供一个 demo 吗? 这样更容易排查问题

@zjcnb 刚已经解决了,DistSql使用的方式不太对,hit是用sql注释的方式弄得,稍后我把demo贴一下,供大家参考。

数据源信息:


两个schema都有goods表,demo_ds_0 的goods里面有id=123,和id=234数据。demo_ds_1的goods里面有id=123的数据。
然后poxy的 goods里面就有id in(123,234,123)的数据。
以上是数据情况。
我的目标是:如果租户0过来goods就会返回demo_ds_0的123,234,如果是租户1过来查询goods就会返回demo_ds_1的123的数据。

proxy的config-sharding.ymal配置如下(感觉配置写的还是有问题,因为我不用数据字段判断了,所以下列的配置,是不是可以调整一下呢,其实tid也没用):
schemaName: sharding_db

dataSources:
demo_ds_0:
url:
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
demo_ds_1:
url:
username:
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1

rules:

  • !SHARDING
    tables:
    goods:
    logicTable: goods
    t_order:
    logicTable: t_order
    defaultDatabaseStrategy:
    standard:
    shardingColumn: t_id
    shardingAlgorithmName: database_inline
    defaultTableStrategy:
    none:

shardingAlgorithms:
database_inline:
type: INLINE
props:
algorithm-expression: demo_ds_${t_id}

代码使用的mybitsplus 操作数据库的,我在sql执行前,修改了sql,加入hit 代码如下:
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
String url = ThreadContextHolder.getHttpRequest().getQueryString();//这里模拟获取租户标识
String oldSql = boundSql.getSql();
log.info(“oldSql:” + oldSql);
String newSql = “/* ShardingSphere hint: dataSourceName=”+url+" */ " + oldSql;
log.info(“newSql:” + newSql);
PluginUtils.MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);
mpBoundSql.sql(newSql);
}

@zjcnb demo如上。

好的, 感谢您的分享.

@zjcnb 我把不用的配置都去掉了,但是proxy在启动之后,会莫名其妙的报以下错误 ,请教一下,大概是啥情况呀

配置如下:

可以看下您的 server.yaml 吗? 可能把配置 copy 上来吗?

@zjcnb server.yaml配置如下:

rules:

  • !AUTHORITY

    users:

    • root@%:root

    • sharding@:sharding

    provider:

    type: ALL_PRIVILEGES_PERMITTED

  • !TRANSACTION

    defaultType: XA

    providerType: Atomikos

  • !SQL_PARSER

    sqlCommentParseEnabled: true

    sqlStatementCache:

    initialCapacity: 2000

    maximumSize: 65535

    concurrencyLevel: 4

    parseTreeCache:

    initialCapacity: 128

    maximumSize: 1024

    concurrencyLevel: 4

props:

max-connections-size-per-query: 1

kernel-executor-size: 16 # Infinite by default.

proxy-frontend-flush-threshold: 128 # The default value is 128.

proxy-opentracing-enabled: false

proxy-hint-enabled: true

sql-show: false

check-table-metadata-enabled: false

show-process-list-enabled: false

proxy-backend-query-fetch-size: -1

check-duplicate-table-enabled: false

proxy-frontend-executor-size: 0 # Proxy frontend executor size. The default value is 0, which means let Netty decide.

proxy-backend-executor-suitable: OLAP

proxy-frontend-max-connections: 0 # Less than or equal to 0 means no limitation.

sql-federation-enabled: false

proxy-backend-driver-type: JDBC

zookeeper怎么配置的,没看到相关说明呢

@liguoping 没有配置zk。

@zjcnb 麻烦帮忙看下

京ICP备2021015875号