apache / shardingsphere

Empowering Data Intelligence with Distributed SQL for Sharding, Scalability, and Security Across All Databases.
Apache License 2.0
19.95k stars 6.74k forks source link

分库分表+读写分离多从库配置并使用MyBatis时,只能路由到同一从库,且查询数据结果不对。 #488

Closed donghc closed 6 years ago

donghc commented 6 years ago

环境 springboot + mybatis + sharding-jdbc + druid + mysql

master: localhost:3306/demo_ds_master_0 slave0: localhost:3306/demo_ds_master_0_slave_0 slave1: localhost:3306/demo_ds_master_0_slave_1

版本信息: spring-boot-starter :1.5.9.RELEASE mybatis-spring-boot-starter : 1.3.0 sharding-jdbc-spring-boot-starter:2.0.0.M3 mysql-connector-java:5.1.30 druid:1.1.2

配置文件application.properties sharding.jdbc.datasource.names=ds_master_0,ds_master_0_slave_0,ds_master_0_slave_1

sharding.jdbc.datasource.ds_master_0.type=com.alibaba.druid.pool.DruidDataSource sharding.jdbc.datasource.ds_master_0.driver-class-name=com.mysql.jdbc.Driver sharding.jdbc.datasource.ds_master_0.url=jdbc:mysql://localhost:3306/demo_ds_master_0 sharding.jdbc.datasource.ds_master_0.username=root sharding.jdbc.datasource.ds_master_0.password=123456

sharding.jdbc.datasource.ds_master_0_slave_0.type=com.alibaba.druid.pool.DruidDataSource sharding.jdbc.datasource.ds_master_0_slave_0.driver-class-name=com.mysql.jdbc.Driver sharding.jdbc.datasource.ds_master_0_slave_0.url=jdbc:mysql://localhost:3306/demo_ds_master_0_slave_0 sharding.jdbc.datasource.ds_master_0_slave_0.username=root sharding.jdbc.datasource.ds_master_0_slave_0.password=123456

sharding.jdbc.datasource.ds_master_0_slave_1.type=com.alibaba.druid.pool.DruidDataSource sharding.jdbc.datasource.ds_master_0_slave_1.driver-class-name=com.mysql.jdbc.Driver sharding.jdbc.datasource.ds_master_0_slave_1.url=jdbc:mysql://localhost:3306/demo_ds_master_0_slave_1 sharding.jdbc.datasource.ds_master_0_slave_1.username=root sharding.jdbc.datasource.ds_master_0_slave_1.password=123456

sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=userid sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=ds${user_id % 1}

sharding.jdbc.config.sharding.tables.torder.actual-data-nodes=ds${0}.torder${0..2} sharding.jdbc.config.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id sharding.jdbc.config.sharding.tables.t_order.table-strategy.inline.algorithm-expression=torder${order_id % 3} sharding.jdbc.config.sharding.tables.t_order.key-generator-column-name=order_id

sharding.jdbc.config.sharding.master-slave-rules.ds_0.master-data-source-name=ds_master_0 sharding.jdbc.config.sharding.master-slave-rules.ds_0.slave-data-source-names=ds_master_0_slave_0, ds_master_0_slave_1

打印sql语句

sharding.jdbc.config.sharding.props.sql.show=true

问题描述 使用spring boot +mybatis+shardingjdbc 2.0.0.M3,读写分离+分表分库配置,发现一主2从库时,总是路由到同一个从库,而且数据归并不全。sql语句分离正确,数据库里面有6条数据,但是汇总完变成了一条数据。

sql语句: [INFO ] 2017-12-09 11:26:31,584 --http-nio-8080-exec-1-- [Sharding-JDBC-SQL] Logic SQL: select
order_id,user_id, status from t_order [INFO ] 2017-12-09 11:26:31,584 --http-nio-8080-exec-1-- [Sharding-JDBC-SQL] SQLStatement: SelectStatement(super=DQLStatement(super=AbstractSQLStatement(type=DQL, tables=Tables(tables=[Table(name=t_order, alias=Optional.absent())]), conditions=Conditions(conditions={}), sqlTokens=[TableToken(beginPosition=53, originalLiterals=t_order)], parametersIndex=0)), containStar=false, selectListLastPosition=48, groupByLastPosition=0, items=[CommonSelectItem(expression=user_id, alias=Optional.absent()), CommonSelectItem(expression=order_id, alias=Optional.absent()), CommonSelectItem(expression=status, alias=Optional.absent())], groupByItems=[], orderByItems=[], limit=null, subQueryStatement=null) [INFO ] 2017-12-09 11:26:31,585 --http-nio-8080-exec-1-- [Sharding-JDBC-SQL] Actual SQL: ds_0 ::: select
order_id,user_id, status from t_order_0 [INFO ] 2017-12-09 11:26:31,585 --http-nio-8080-exec-1-- [Sharding-JDBC-SQL] Actual SQL: ds_0 ::: select
order_id,user_id, status from t_order_1 [INFO ] 2017-12-09 11:26:31,585 --http-nio-8080-exec-1-- [Sharding-JDBC-SQL] Actual SQL: ds_0 ::: select
order_id,user_id, status from t_order_2

查询后获取结果:1条数据 数据库真实结果:ds_master_0_slave_0:5条数据,ds_master_0_slave_1:6条数据

当配置单从库时,数据获取正常。

terrymanu commented 6 years ago

这个问题应该在2.0.0.M3中已修复:https://github.com/shardingjdbc/sharding-jdbc/issues/436

请确定是否您使用的版本并非2.0.0.M3的正式发布版。 如果确认2.0.0.M3确实有问题,我们再修复

donghc commented 6 years ago

我确定是在2.0.0.M3版本的,pom文件的依赖项为:

    <dependency>
        <groupId>io.shardingjdbc</groupId>
        <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
        <version>2.0.0.M3</version>
    </dependency>

谢谢。

terrymanu commented 6 years ago

请提供一下可重现的代码,我们定位一下

donghc commented 6 years ago

你好,代码已上传到地址:https://gitee.com/donghc/sharding

haocao commented 6 years ago

感谢提供代码,因为两个从库数据并不一样,一个从库demo_ds_master_0_slave_0中没有数据,另外一个从库demo_ds_master_0_slave_1一共有6六条数据,t_order_0表中3条数据,t_order_1表中1条数据,t_order_2表中2条数据。对于RoundRobinMasterSlaveLoadBalanceAlgorithm算法,每次查询会轮询slave从库,因此轮询出来的结果是slave_0轮询两次,未查到数据,slave_1轮询一次,查询到1条数据。因此查询结果符合算法设计,理论上多个从库间应该是对等关系,数据应该是一致的。

donghc commented 6 years ago

确定不是bug就好,出现这个问题是由于我自己写样例demo进行学习,当时没有做数据同步的,想看看结果。不知道该从哪里debug开始,现在明白了这个路由原理,感谢解答。