Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Three data sources were configured, but four data sources were created.(shardingsphere-jdbc:5.2.0) #21650

Closed
MrXionGe opened this issue Oct 19, 2022 · 10 comments

Comments

@MrXionGe
Copy link

Bug Report

Which version of ShardingSphere did you use?

5.2.0

Which project did you use? ShardingSphere-JDBC or ShardingSphere-Proxy?

shardingsphere-jdbc-core

Code

pom.xml(dependencies)
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>5.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core</artifactId>
            <version>5.2.0</version>
        </dependency>
JavaConfig
package cn.mrxionge.webtemplatemysql.config;

import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.driver.api.ShardingSphereDataSourceFactory;
import org.apache.shardingsphere.infra.config.algorithm.AlgorithmConfiguration;
import org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
import org.apache.shardingsphere.readwritesplitting.api.rule.ReadwriteSplittingDataSourceRuleConfiguration;
import org.apache.shardingsphere.readwritesplitting.api.strategy.StaticReadwriteSplittingStrategyConfiguration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * MySQL读写分离数据源
 */
@Slf4j
@Configuration
public class MySQLConfig {

    @Value("${mysql-ds.master.jdbc-url}")
    private String masterJdbcUrl;

    @Value("${mysql-ds.master.username}")
    private String masterUsername;

    @Value("${mysql-ds.master.password}")
    private String masterPassword;

    @Value("${mysql-ds.replica-1.jdbc-url}")
    private String replica1JdbcUrl;

    @Value("${mysql-ds.replica-1.username}")
    private String replica1Username;

    @Value("${mysql-ds.replica-1.password}")
    private String replica1Password;

    @Value("${mysql-ds.replica-2.jdbc-url}")
    private String replica2JdbcUrl;

    @Value("${mysql-ds.replica-2.username}")
    private String replica2Username;

    @Value("${mysql-ds.replica-2.password}")
    private String replica2Password;

    @Bean
    public DataSource dataSource() throws SQLException {
        //数据源Map
        Map<String, DataSource> dsMap = new HashMap<>();
        //配置主库
        HikariDataSource masterDs = new HikariDataSource();
        masterDs.setDriverClassName("com.mysql.cj.jdbc.Driver");
        masterDs.setJdbcUrl(masterJdbcUrl);
        masterDs.setMinimumIdle(16);
        masterDs.setMaximumPoolSize(32);
        masterDs.setConnectionInitSql("SET NAMES utf8mb4");
        masterDs.setUsername(masterUsername);
        masterDs.setPassword(masterPassword);
        dsMap.put("master_ds", masterDs);
        //配置读库1
        HikariDataSource replicaDs1 = new HikariDataSource();
        replicaDs1.setDriverClassName("com.mysql.cj.jdbc.Driver");
        replicaDs1.setJdbcUrl(replica1JdbcUrl);
        replicaDs1.setMinimumIdle(16);
        replicaDs1.setMaximumPoolSize(32);
        replicaDs1.setConnectionInitSql("SET NAMES utf8mb4");
        replicaDs1.setUsername(replica1Username);
        replicaDs1.setPassword(replica1Password);
        dsMap.put("replica_ds_1", replicaDs1);
        //配置读库2
        HikariDataSource replicaDs2 = new HikariDataSource();
        replicaDs2.setDriverClassName("com.mysql.cj.jdbc.Driver");
        replicaDs2.setJdbcUrl(replica2JdbcUrl);
        replicaDs2.setMinimumIdle(16);
        replicaDs2.setMaximumPoolSize(32);
        replicaDs2.setConnectionInitSql("SET NAMES utf8mb4");
        replicaDs2.setUsername(replica2Username);
        replicaDs2.setPassword(replica2Password);
        dsMap.put("replica_ds_2", replicaDs2);
        //主从数据源配置
        ReadwriteSplittingDataSourceRuleConfiguration dsConfig = new ReadwriteSplittingDataSourceRuleConfiguration("ds",
                new StaticReadwriteSplittingStrategyConfiguration("master_ds", List.of("replica_ds_1", "replica_ds_2")),
                null, "load_balancer");
        //负载均衡算法配置
        Map<String, AlgorithmConfiguration> loadBalanceMap = new HashMap<>();
        loadBalanceMap.put("load_balancer", new AlgorithmConfiguration("ROUND_ROBIN", new Properties()));
        ReadwriteSplittingRuleConfiguration ruleConfiguration = new ReadwriteSplittingRuleConfiguration(List.of(dsConfig), loadBalanceMap);
        //创建DS
        log.info("创建 ShardingSphere 读写分离数据源");
        return ShardingSphereDataSourceFactory.createDataSource(dsMap, List.of(ruleConfiguration), new Properties());
    }
}

Description

I created three data sources. A write data source(master_ds) and two read data sources(replica_ds_1&replica_ds_2).

Expected behavior

Initialize the three data sources.
I will see the log for 'hikari' in the console with 3 data sources created.

Actual behavior

There are four data sources created.
image

Reason analyze (If you can)

I'm not sure what the mistake was.
This is correct in version 5.1.2. However, this is incorrect in version 5.2.0.

@MrXionGe
Copy link
Author

supplement

The preceding error also occurs in version 5.2.1.

@linghengqian
Copy link
Member

  • FYI, if you are using the ShardingSphere JDBC Driver in ShardingSphere 5.1.2, this Log is also available. Is there anything you think you need to do in the master branch?

@MrXionGe
Copy link
Author

There have been some changes to the JavaConfigAPI since 5.1.2 to 5.2.0.
The steps for creating the data source have not changed.
That is, three data sources are configured and four data sources are created. This was unexpected.

@zhaojinchao95
Copy link
Contributor

@MrXionGe ShardingSphere default mode are Standalone mode , this is created inside ShardingSphere. You can refer to
JDBCRepository.calss

@MrXionGe
Copy link
Author

@zhaojinchao95
Do I need to change the JavaConfig?
I upgraded from 5.1.2 to 5.2.0. JavaConfig is included in the above description. Is there a bug in the code?

@MrXionGe
Copy link
Author

@zhaojinchao95
Or, the new version adds new features. So, there are three data sources configured and four data sources initialized.

@zhaojinchao95
Copy link
Contributor

@zhaojinchao95 Or, the new version adds new features. So, there are three data sources configured and four data sources initialized.

Yes, you are right.

@MrXionGe
Copy link
Author

@zhaojinchao95
I checked the source code.
When creating a data source, ShardingSphere will create an additional H2 database data source.
This should be a feature that did not exist before 5.2.0.

@TeslaCN
Copy link
Member

TeslaCN commented Dec 27, 2022

Consider doing heap dump to figure out what is the 4th data source instance.

@MrXionGe
Copy link
Author

@TeslaCN
Thank you for your reply. I have found the reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants