From e6571ae02834f3efca4a0cff2a9d4c036389d0d2 Mon Sep 17 00:00:00 2001 From: linghengqian Date: Mon, 25 Nov 2024 16:47:17 +0800 Subject: [PATCH 1/2] Support local transactions of ClickHouse under GraalVM Native Image --- .../optional-plugins/clickhouse/_index.cn.md | 2 +- .../optional-plugins/clickhouse/_index.en.md | 2 +- .../reflect-config.json | 35 +++++++++++++++---- .../resource-config.json | 6 ++++ .../natived/commons/TestShardingService.java | 6 ++++ .../repository/OrderItemRepository.java | 2 +- .../commons/repository/OrderRepository.java | 2 +- .../jdbc/databases/ClickHouseTest.java | 29 +++++++++++---- .../xml/clickhouse-transactions.xml | 25 +++++++++++++ .../yaml/jdbc/databases/clickhouse.yaml | 8 ----- .../yaml/jdbc/databases/hive/simple.yaml | 8 ----- .../jdbc/databases/hive/zookeeper-sde.yaml | 8 ----- .../yaml/jdbc/databases/mysql.yaml | 8 ----- .../yaml/jdbc/databases/opengauss.yaml | 8 ----- .../yaml/jdbc/databases/postgresql.yaml | 8 ----- .../yaml/jdbc/databases/sqlserver.yaml | 8 ----- .../yaml/jdbc/features/encrypt.yaml | 8 ----- .../test-native/yaml/jdbc/features/mask.yaml | 8 ----- .../jdbc/features/readwrite-splitting.yaml | 8 ----- .../yaml/jdbc/features/shadow.yaml | 8 ----- .../yaml/jdbc/features/sharding.yaml | 8 ----- .../yaml/jdbc/modes/cluster/etcd.yaml | 3 -- .../yaml/jdbc/modes/cluster/zookeeper.yaml | 3 -- .../yaml/jdbc/transactions/base/seata.yaml | 8 ----- .../yaml/jdbc/transactions/xa/atomikos.yaml | 8 ----- .../yaml/jdbc/transactions/xa/narayana.yaml | 8 ----- 26 files changed, 91 insertions(+), 144 deletions(-) create mode 100644 test/native/src/test/resources/test-native/xml/clickhouse-transactions.xml diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.cn.md b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.cn.md index cc401c672aecc..039eccab1792b 100644 --- a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.cn.md +++ b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.cn.md @@ -76,7 +76,7 @@ CREATE DATABASE demo_ds_2; ```sql -- noinspection SqlNoDataSourceInspectionForFile create table IF NOT EXISTS t_order ( - order_id Int64 NOT NULL DEFAULT rand(), + order_id Int64 NOT NULL, order_type Int32, user_id Int32 NOT NULL, address_id Int64 NOT NULL, diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.en.md b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.en.md index d2fccfdfcdc36..43205c1ebdc76 100644 --- a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.en.md +++ b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.en.md @@ -77,7 +77,7 @@ to connect to ClickHouse and execute the following SQL. ```sql -- noinspection SqlNoDataSourceInspectionForFile create table IF NOT EXISTS t_order ( - order_id Int64 NOT NULL DEFAULT rand(), + order_id Int64 NOT NULL, order_type Int32, user_id Int32 NOT NULL, address_id Int64 NOT NULL, diff --git a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/reflect-config.json b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/reflect-config.json index 31fa795126018..fe75b38e7ab6d 100644 --- a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/reflect-config.json +++ b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/reflect-config.json @@ -16,7 +16,7 @@ "name":"[Lcom.github.dockerjava.api.model.VolumesFrom;" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007fb05bce1828"}, + "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007f4b07ce0c30"}, "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;" }, { @@ -75,10 +75,6 @@ "condition":{"typeReachable":"org.apache.shardingsphere.mode.repository.standalone.jdbc.JDBCRepository"}, "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;" }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.proxy.backend.connector.jdbc.datasource.JDBCBackendDataSource"}, - "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;" -}, { "condition":{"typeReachable":"org.apache.shardingsphere.proxy.frontend.postgresql.command.query.extended.Portal"}, "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;" @@ -1071,7 +1067,7 @@ "name":"org.apache.shardingsphere.driver.yaml.YamlJDBCConfiguration", "allDeclaredFields":true, "queryAllPublicMethods":true, - "methods":[{"name":"","parameterTypes":[] }, {"name":"setDataSources","parameterTypes":["java.util.Map"] }, {"name":"setMode","parameterTypes":["org.apache.shardingsphere.infra.yaml.config.pojo.mode.YamlModeConfiguration"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }, {"name":"setRules","parameterTypes":["java.util.Collection"] }, {"name":"setSqlParser","parameterTypes":["org.apache.shardingsphere.parser.yaml.config.YamlSQLParserRuleConfiguration"] }, {"name":"setTransaction","parameterTypes":["org.apache.shardingsphere.transaction.yaml.config.YamlTransactionRuleConfiguration"] }] + "methods":[{"name":"","parameterTypes":[] }, {"name":"setDataSources","parameterTypes":["java.util.Map"] }, {"name":"setMode","parameterTypes":["org.apache.shardingsphere.infra.yaml.config.pojo.mode.YamlModeConfiguration"] }, {"name":"setRules","parameterTypes":["java.util.Collection"] }, {"name":"setSqlParser","parameterTypes":["org.apache.shardingsphere.parser.yaml.config.YamlSQLParserRuleConfiguration"] }, {"name":"setTransaction","parameterTypes":["org.apache.shardingsphere.transaction.yaml.config.YamlTransactionRuleConfiguration"] }] }, { "condition":{"typeReachable":"org.apache.shardingsphere.infra.util.yaml.YamlEngine"}, @@ -2078,7 +2074,7 @@ "queryAllDeclaredMethods":true }, { - "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.listener.DatabaseMetaDataChangedListener$$Lambda/0x00007fb05bb277d8"}, + "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.listener.DatabaseMetaDataChangedListener$$Lambda/0x00007f4b07b277d8"}, "name":"org.apache.shardingsphere.mode.manager.cluster.event.subscriber.dispatch.MetaDataChangedSubscriber" }, { @@ -3131,6 +3127,16 @@ "name":"org.apache.shardingsphere.single.yaml.config.YamlSingleRuleConfiguration", "allDeclaredFields":true }, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSphereStatement"}, + "name":"org.apache.shardingsphere.sql.parser.clickhouse.parser.ClickHouseLexer", + "methods":[{"name":"","parameterTypes":["org.antlr.v4.runtime.CharStream"] }] +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSphereStatement"}, + "name":"org.apache.shardingsphere.sql.parser.clickhouse.parser.ClickHouseParser", + "methods":[{"name":"","parameterTypes":["org.antlr.v4.runtime.TokenStream"] }] +}, { "condition":{"typeReachable":"org.apache.shardingsphere.proxy.backend.handler.ProxySQLComQueryParser"}, "name":"org.apache.shardingsphere.sql.parser.clickhouse.parser.ClickHouseParserFacade" @@ -3140,6 +3146,11 @@ "name":"org.apache.shardingsphere.sql.parser.clickhouse.visitor.statement.ClickHouseStatementVisitorFacade", "methods":[{"name":"","parameterTypes":[] }] }, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSphereStatement"}, + "name":"org.apache.shardingsphere.sql.parser.clickhouse.visitor.statement.type.ClickHouseDMLStatementVisitor", + "methods":[{"name":"","parameterTypes":[] }] +}, { "condition":{"typeReachable":"org.apache.shardingsphere.sql.parser.core.database.cache.ParseTreeCacheBuilder"}, "name":"org.apache.shardingsphere.sql.parser.core.database.cache.ParseTreeCacheLoader" @@ -3327,6 +3338,11 @@ "name":"org.apache.shardingsphere.sql.parser.statement.clickhouse.dml.ClickHouseSelectStatement", "methods":[{"name":"","parameterTypes":[] }] }, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSphereStatement"}, + "name":"org.apache.shardingsphere.sql.parser.statement.clickhouse.dml.ClickHouseSelectStatement", + "methods":[{"name":"","parameterTypes":[] }] +}, { "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement"}, "name":"org.apache.shardingsphere.sql.parser.statement.hive.dml.HiveInsertStatement", @@ -3607,5 +3623,10 @@ { "condition":{"typeReachable":"org.apache.shardingsphere.proxy.initializer.BootstrapInitializer"}, "name":"org.apache.shardingsphere.transaction.yaml.config.YamlTransactionRuleConfigurationCustomizer" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.infra.executor.kernel.ExecutorEngine"}, + "name":"sun.security.provider.SecureRandom", + "methods":[{"name":"","parameterTypes":[] }, {"name":"","parameterTypes":["java.security.SecureRandomParameters"] }] } ] \ No newline at end of file diff --git a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/resource-config.json b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/resource-config.json index 6861bc941ff55..294fcfe11ad1e 100644 --- a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/resource-config.json +++ b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/resource-config.json @@ -75,6 +75,12 @@ }, { "condition":{"typeReachable":"org.apache.shardingsphere.transaction.xa.atomikos.manager.AtomikosTransactionManagerProvider"}, "pattern":"\\QMETA-INF/services/com.atomikos.recovery.OltpLogFactory\\E" + }, { + "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager"}, + "pattern":"\\QMETA-INF/services/com.clickhouse.client.ClickHouseClient\\E" + }, { + "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007f4b07b34b38"}, + "pattern":"\\QMETA-INF/services/com.clickhouse.client.ClickHouseClient\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource"}, "pattern":"\\QMETA-INF/services/com.clickhouse.client.ClickHouseClient\\E" diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/TestShardingService.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/TestShardingService.java index c167304b9df0f..b2f6ac9259099 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/TestShardingService.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/TestShardingService.java @@ -24,10 +24,12 @@ import org.apache.shardingsphere.test.natived.commons.repository.AddressRepository; import org.apache.shardingsphere.test.natived.commons.repository.OrderItemRepository; import org.apache.shardingsphere.test.natived.commons.repository.OrderRepository; +import org.awaitility.Awaitility; import javax.sql.DataSource; import java.sql.SQLException; import java.sql.Statement; +import java.time.Duration; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -84,6 +86,7 @@ public void processSuccessInClickHouse() throws SQLException { assertThat(orderRepository.selectAll(), equalTo(Collections.emptyList())); assertThat(orderItemRepository.selectAll(), equalTo(Collections.emptyList())); assertThat(addressRepository.selectAll(), equalTo(Collections.emptyList())); + orderItemRepository.assertRollbackWithTransactions(); } private void extracted() throws SQLException { @@ -173,11 +176,14 @@ public void deleteData(final Collection orderIds) throws SQLException { /** * Delete data in ClickHouse. + * TODO It is necessary to avoid the use of {@code Awaitility.await().pollDelay(Duration.ofSeconds(9L)).until(()->true)}. + * After ClickHouse enables experimental transactions, performance drops significantly. * * @param orderIds orderId of the insert statement. * @throws SQLException An exception that provides information on a database access error or other errors. */ public void deleteDataInClickHouse(final Collection orderIds) throws SQLException { + Awaitility.await().pollDelay(Duration.ofSeconds(9L)).until(() -> true); long count = 1L; for (Long each : orderIds) { orderRepository.deleteInClickHouse(each); diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderItemRepository.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderItemRepository.java index ce58a765bd0cb..180bc6ef0e7f0 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderItemRepository.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderItemRepository.java @@ -110,7 +110,7 @@ public void createTableInSQLServer() throws SQLException { */ public void createTableIfNotExistsInClickHouse() throws SQLException { String sql = "create table IF NOT EXISTS t_order_item( \n" - + "order_item_id Int64 NOT NULL DEFAULT rand(), \n" + + "order_item_id Int64 NOT NULL, \n" + "order_id Int64 NOT NULL, \n" + "user_id Int32 NOT NULL, \n" + "phone String,\n" diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderRepository.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderRepository.java index 30fdd6625687e..73e2679472322 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderRepository.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderRepository.java @@ -107,7 +107,7 @@ public void createTableInSQLServer() throws SQLException { */ public void createTableIfNotExistsInClickHouse() throws SQLException { String sql = "create table IF NOT EXISTS t_order( \n" - + "order_id Int64 NOT NULL DEFAULT rand(), \n" + + "order_id Int64 NOT NULL, \n" + "order_type Int32, \n" + "user_id Int32 NOT NULL, \n" + "address_id Int64 NOT NULL,\n" diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/ClickHouseTest.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/ClickHouseTest.java index 2295102d790fd..db2ad31090b52 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/ClickHouseTest.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/ClickHouseTest.java @@ -26,8 +26,11 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledInNativeImage; import org.testcontainers.clickhouse.ClickHouseContainer; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.Network; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.MountableFile; import javax.sql.DataSource; import java.sql.Connection; @@ -46,13 +49,24 @@ * Cannot use testcontainers-java style jdbcURL for Clickhouse Server due to unresolved * testcontainers/testcontainers-java#8736. */ -@SuppressWarnings("SqlNoDataSourceInspection") +@SuppressWarnings({"SqlNoDataSourceInspection", "resource"}) @EnabledInNativeImage @Testcontainers class ClickHouseTest { + private static final Network NETWORK = Network.newNetwork(); + + @Container + private static final GenericContainer ZOOKEEPER_CONTAINER = new GenericContainer<>("zookeeper:3.9.3-jre-17") + .withNetwork(NETWORK) + .withNetworkAliases("foo"); + @Container - public static final ClickHouseContainer CONTAINER = new ClickHouseContainer("clickhouse/clickhouse-server:24.10.2.80"); + public static final ClickHouseContainer CONTAINER = new ClickHouseContainer("clickhouse/clickhouse-server:24.10.2.80") + .withCopyFileToContainer(MountableFile.forClasspathResource("test-native/xml/clickhouse-transactions.xml"), + "/etc/clickhouse-server/config.d/transactions.xml") + .withNetwork(NETWORK) + .dependsOn(ZOOKEEPER_CONTAINER); private static final String SYSTEM_PROP_KEY_PREFIX = "fixture.test-native.yaml.database.clickhouse."; @@ -69,6 +83,7 @@ static void beforeAll() { @AfterAll static void afterAll() { + NETWORK.close(); System.clearProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url"); System.clearProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url"); System.clearProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url"); @@ -125,9 +140,9 @@ private DataSource createDataSource() throws SQLException { HikariConfig config = new HikariConfig(); config.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver"); config.setJdbcUrl("jdbc:shardingsphere:classpath:test-native/yaml/jdbc/databases/clickhouse.yaml?placeholder-type=system_props"); - System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url", jdbcUrlPrefix + "demo_ds_0"); - System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url", jdbcUrlPrefix + "demo_ds_1"); - System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url", jdbcUrlPrefix + "demo_ds_2"); + System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url", jdbcUrlPrefix + "demo_ds_0?transactionSupport=true"); + System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url", jdbcUrlPrefix + "demo_ds_1?transactionSupport=true"); + System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url", jdbcUrlPrefix + "demo_ds_2?transactionSupport=true"); return new HikariDataSource(config); } @@ -137,7 +152,7 @@ private void initTable(final String databaseName) { Statement statement = connection.createStatement()) { statement.executeUpdate("create table IF NOT EXISTS t_order\n" + "(\n" - + " order_id Int64 NOT NULL DEFAULT rand(),\n" + + " order_id Int64 NOT NULL,\n" + " order_type Int32,\n" + " user_id Int32 NOT NULL,\n" + " address_id Int64 NOT NULL,\n" @@ -147,7 +162,7 @@ private void initTable(final String databaseName) { + " order by (order_id)"); statement.executeUpdate("create table IF NOT EXISTS t_order_item\n" + "(\n" - + " order_item_id Int64 NOT NULL DEFAULT rand(),\n" + + " order_item_id Int64 NOT NULL,\n" + " order_id Int64 NOT NULL,\n" + " user_id Int32 NOT NULL,\n" + " phone String,\n" diff --git a/test/native/src/test/resources/test-native/xml/clickhouse-transactions.xml b/test/native/src/test/resources/test-native/xml/clickhouse-transactions.xml new file mode 100644 index 0000000000000..4ded8989a1004 --- /dev/null +++ b/test/native/src/test/resources/test-native/xml/clickhouse-transactions.xml @@ -0,0 +1,25 @@ + + + 1 + + + foo + 2181 + + + diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/databases/clickhouse.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/databases/clickhouse.yaml index dccec2814753e..037cebf0f5c0b 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/databases/clickhouse.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/databases/clickhouse.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -73,6 +68,3 @@ rules: - !BROADCAST tables: - t_address - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/simple.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/simple.yaml index 46056faffc4f9..2a5ff41f4312f 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/simple.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/simple.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -67,6 +62,3 @@ rules: - !BROADCAST tables: - t_address - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/zookeeper-sde.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/zookeeper-sde.yaml index 6e72411c70224..11adae6a432f2 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/zookeeper-sde.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/databases/hive/zookeeper-sde.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -67,6 +62,3 @@ rules: - !BROADCAST tables: - t_address - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/databases/mysql.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/databases/mysql.yaml index 5291896aa4e90..78a812a4f06c3 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/databases/mysql.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/databases/mysql.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -73,6 +68,3 @@ rules: - !BROADCAST tables: - t_address - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/databases/opengauss.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/databases/opengauss.yaml index a3e6b8d937638..38f5051da17cb 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/databases/opengauss.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/databases/opengauss.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -73,6 +68,3 @@ rules: - !BROADCAST tables: - t_address - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/databases/postgresql.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/databases/postgresql.yaml index e6415b5a8ab3a..9d240e0381e39 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/databases/postgresql.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/databases/postgresql.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -67,6 +62,3 @@ rules: - !BROADCAST tables: - t_address - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/databases/sqlserver.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/databases/sqlserver.yaml index 2a0f7518c0685..3376792b2877f 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/databases/sqlserver.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/databases/sqlserver.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -67,6 +62,3 @@ rules: - !BROADCAST tables: - t_address - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/features/encrypt.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/features/encrypt.yaml index f5264168e18d1..e4cf07cf1aad1 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/features/encrypt.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/features/encrypt.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -57,6 +52,3 @@ rules: props: aes-key-value: 123456 digest-algorithm-name: SHA-1 - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/features/mask.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/features/mask.yaml index 948845285d49d..96708da063ab3 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/features/mask.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/features/mask.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -42,6 +37,3 @@ rules: first-n: 3 last-m: 4 replace-char: '*' - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/features/readwrite-splitting.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/features/readwrite-splitting.yaml index dcf4c85f43508..25efb7075de84 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/features/readwrite-splitting.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/features/readwrite-splitting.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -51,6 +46,3 @@ rules: readDataSourceNames: - ds_1 - ds_2 - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/features/shadow.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/features/shadow.yaml index 89c73ad895f6d..bb67eb127be84 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/features/shadow.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/features/shadow.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -82,6 +77,3 @@ sqlParser: parseTreeCache: initialCapacity: 2000 maximumSize: 65535 - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/features/sharding.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/features/sharding.yaml index 3671c4176d297..c59e15721247a 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/features/sharding.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/features/sharding.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -76,6 +71,3 @@ rules: - !BROADCAST tables: - t_address - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/modes/cluster/etcd.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/modes/cluster/etcd.yaml index e4bf8f4e41eaa..3f5fec30ab73d 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/modes/cluster/etcd.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/modes/cluster/etcd.yaml @@ -76,6 +76,3 @@ rules: - !BROADCAST tables: - t_address - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/modes/cluster/zookeeper.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/modes/cluster/zookeeper.yaml index f778adc264303..f9e0bfaa47180 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/modes/cluster/zookeeper.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/modes/cluster/zookeeper.yaml @@ -76,6 +76,3 @@ rules: - !BROADCAST tables: - t_address - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/transactions/base/seata.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/transactions/base/seata.yaml index fdb7fd77ff362..750f452a776c2 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/transactions/base/seata.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/transactions/base/seata.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -71,6 +66,3 @@ rules: transaction: defaultType: BASE providerType: Seata - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/transactions/xa/atomikos.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/transactions/xa/atomikos.yaml index 26efecf48d9df..8b584217bf2da 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/transactions/xa/atomikos.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/transactions/xa/atomikos.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -77,6 +72,3 @@ rules: transaction: defaultType: XA providerType: Atomikos - -props: - sql-show: false diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/transactions/xa/narayana.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/transactions/xa/narayana.yaml index 5fa3628ef2f8c..679059bb4719d 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/transactions/xa/narayana.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/transactions/xa/narayana.yaml @@ -15,11 +15,6 @@ # limitations under the License. # -mode: - type: Standalone - repository: - type: JDBC - dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource @@ -77,6 +72,3 @@ rules: transaction: defaultType: XA providerType: Narayana - -props: - sql-show: false From ba595fcf55ec88064d78b486a20eaa4469ae4f2b Mon Sep 17 00:00:00 2001 From: linghengqian Date: Mon, 25 Nov 2024 20:08:44 +0800 Subject: [PATCH 2/2] Replaces Zookeeper with ClickHouse Keeper --- RELEASE-NOTES.md | 1 + .../optional-plugins/clickhouse/_index.cn.md | 174 ++++++++++++++++- .../optional-plugins/clickhouse/_index.en.md | 177 +++++++++++++++++- .../optional-plugins/hiveserver2/_index.cn.md | 13 +- .../optional-plugins/hiveserver2/_index.en.md | 15 +- .../reflect-config.json | 6 +- .../resource-config.json | 2 +- .../reflect-config.json | 15 -- .../natived/commons/TestShardingService.java | 4 +- .../commons/repository/AddressRepository.java | 19 -- .../repository/OrderItemRepository.java | 71 ++----- .../commons/repository/OrderRepository.java | 46 ----- .../jdbc/databases/ClickHouseTest.java | 50 +++-- .../jdbc/databases/hive/HiveSimpleTest.java | 27 +-- .../HiveZookeeperServiceDiscoveryTest.java | 24 +-- .../natived/proxy/databases/PostgresTest.java | 2 +- .../natived/proxy/features/ShardingTest.java | 2 +- .../resource-config.json | 3 + .../sql/test-native-databases-hive.sql | 7 +- .../test-native/xml/keeper_config.xml | 31 +++ ...ouse-transactions.xml => transactions.xml} | 4 +- .../yaml/jdbc/features/sharding.yaml | 3 + 22 files changed, 451 insertions(+), 245 deletions(-) create mode 100644 test/native/src/test/resources/test-native/xml/keeper_config.xml rename test/native/src/test/resources/test-native/xml/{clickhouse-transactions.xml => transactions.xml} (92%) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 01833a33ee55e..4cd92365e0220 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -27,6 +27,7 @@ 1. Infra: Support connecting to HiveServer2 through database connection pools other than HikariCP - [#33762](https://github.com/apache/shardingsphere/pull/33762) 1. Infra: Partial support for connecting to embedded ClickHouse `chDB` - [#33786](https://github.com/apache/shardingsphere/pull/33786) 1. Proxy Native: Support connecting to HiveServer2 with ZooKeeper Service Discovery enabled in GraalVM Native Image - [#33768](https://github.com/apache/shardingsphere/pull/33768) +1. Proxy Native: Support local transactions of ClickHouse under GraalVM Native Image - [#33801](https://github.com/apache/shardingsphere/pull/33801) 1. Doc: Adds documentation for ClickHouse support - [#33779](https://github.com/apache/shardingsphere/pull/33779) ### Bug Fixes diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.cn.md b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.cn.md index 039eccab1792b..ecf0eaeca0b53 100644 --- a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.cn.md +++ b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.cn.md @@ -80,7 +80,7 @@ create table IF NOT EXISTS t_order ( order_type Int32, user_id Int32 NOT NULL, address_id Int64 NOT NULL, - status String + status VARCHAR(50) ) engine = MergeTree primary key (order_id) order by (order_id); @@ -158,7 +158,7 @@ public class ExampleUtils { ### SQL 限制 -ShardingSphere JDBC DataSource 尚不支持执行 ClickHouse 的 `CREATE TABLE` 语句和 `TRUNCATE TABLE` 语句。 +ShardingSphere JDBC DataSource 尚不支持执行 ClickHouse 的 `create table`,`truncate table` 和 `drop table` 语句。 用户应考虑为 ShardingSphere 提交包含单元测试的 PR。 ### 分布式序列限制 @@ -207,9 +207,177 @@ public class ExampleTest { ### 事务限制 -ClickHouse 不支持 ShardingSphere 集成级别的本地事务,XA 事务和 Seata AT 模式事务, +ClickHouse 不支持 ShardingSphere 集成级别的 XA 事务, +因为 https://github.com/ClickHouse/clickhouse-java 未实现 `javax.sql.XADataSource` 的相关 Java 接口。 + +ClickHouse 不支持 ShardingSphere 集成级别的 Seata AT 模式事务, +因为 https://github.com/apache/incubator-seata 未实现 ClickHouse 的 SQL 方言解析。 + +ClickHouse 支持 ShardingSphere 集成级别的本地事务,但需要对 ClickHouse 进行额外配置, 更多讨论位于 https://github.com/ClickHouse/clickhouse-docs/issues/2300 。 +引入讨论,编写 Docker Compose 文件来启动 ClickHouse 和 ClickHouse Keeper。 + +```yaml +services: + clickhouse-keeper-01: + image: clickhouse/clickhouse-keeper:24.10.2.80 + volumes: + - ./keeper_config.xml:/etc/clickhouse-keeper/keeper_config.xml + clickhouse-server: + image: clickhouse/clickhouse-server:24.10.2.80 + depends_on: + - clickhouse-keeper-01 + ports: + - "8123:8123" + volumes: + - ./transactions.xml:/etc/clickhouse-server/config.d/transactions.xml +``` + +`./keeper_config.xml` 的内容如下, + +```xml + + 0.0.0.0 + + 9181 + 1 + /var/lib/clickhouse/coordination/snapshots + + + 1 + clickhouse-keeper-01 + 9234 + + + + +``` + +`./transactions.xml` 的内容如下, + +```xml + + 1 + + + clickhouse-keeper-01 + 9181 + + + +``` + +在 DBeaver Community 内,使用 `jdbc:ch://localhost:8123/default` 的 `jdbcUrl`,`default` 的`username` 连接至 ClickHouse, +`password` 留空。 +执行如下 SQL, + +```sql +-- noinspection SqlNoDataSourceInspectionForFile +CREATE DATABASE demo_ds_0; +CREATE DATABASE demo_ds_1; +CREATE DATABASE demo_ds_2; +``` + +分别使用 `jdbc:ch://localhost:8123/demo_ds_0` , +`jdbc:ch://localhost:8123/demo_ds_1` 和 `jdbc:ch://localhost:8123/demo_ds_2` 的 `jdbcUrl` 连接至 ClickHouse 来执行如下 SQL, + +```sql +-- noinspection SqlNoDataSourceInspectionForFile +create table IF NOT EXISTS t_order ( + order_id Int64 NOT NULL, + order_type Int32, + user_id Int32 NOT NULL, + address_id Int64 NOT NULL, + status VARCHAR(50) +) engine = MergeTree + primary key (order_id) + order by (order_id); + +TRUNCATE TABLE t_order; +``` + +在业务项目引入`前提条件`涉及的依赖后,在业务项目的 classpath 上编写 ShardingSphere 数据源的配置文件`demo.yaml`, + +```yaml +dataSources: + ds_0: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: com.clickhouse.jdbc.ClickHouseDriver + jdbcUrl: jdbc:ch://localhost:8123/demo_ds_0?transactionSupport=true + ds_1: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: com.clickhouse.jdbc.ClickHouseDriver + jdbcUrl: jdbc:ch://localhost:8123/demo_ds_1?transactionSupport=true + ds_2: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: com.clickhouse.jdbc.ClickHouseDriver + jdbcUrl: jdbc:ch://localhost:8123/demo_ds_2?transactionSupport=true +rules: +- !SHARDING + tables: + t_order: + actualDataNodes: + keyGenerateStrategy: + column: order_id + keyGeneratorName: snowflake + defaultDatabaseStrategy: + standard: + shardingColumn: user_id + shardingAlgorithmName: inline + shardingAlgorithms: + inline: + type: INLINE + props: + algorithm-expression: ds_${user_id % 2} + keyGenerators: + snowflake: + type: SNOWFLAKE +``` + +创建 ShardingSphere 的数据源后可正常使用本地事务, + +```java +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import java.sql.Connection; +import java.sql.SQLException; +@SuppressWarnings({"SqlNoDataSourceInspection", "AssertWithSideEffects"}) +public class ExampleUtils { + void test() throws SQLException { + HikariConfig config = new HikariConfig(); + config.setJdbcUrl("jdbc:shardingsphere:classpath:demo.yaml"); + config.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver"); + try (HikariDataSource dataSource = new HikariDataSource(config); Connection connection = dataSource.getConnection()) { + try { + connection.setAutoCommit(false); + connection.createStatement().executeUpdate("INSERT INTO t_order (user_id, order_type, address_id, status) VALUES (2024, 0, 2024, 'INSERT_TEST')"); + connection.createStatement().executeUpdate("INSERT INTO t_order_does_not_exist (test_id_does_not_exist) VALUES (2024)"); + connection.commit(); + } catch (final SQLException ignored) { + connection.rollback(); + } finally { + connection.setAutoCommit(true); + } + try (Connection conn = dataSource.getConnection()) { + assert !conn.createStatement().executeQuery("SELECT * FROM t_order WHERE user_id = 2024").next(); + } + } + } +} +``` + +一旦在 ShardingSphere 的配置文件为 ClickHouse JDBC Driver 的 jdbcUrl 设置 `transactionSupport=true`, +用户在执行 `alter table` 语句前应确保没有尚未完成执行的 `insert` 语句,以避免如下 Error 的发生, + +```shell +java.sql.BatchUpdateException: Code: 341. DB::Exception: Exception happened during execution of mutation 'mutation_6.txt' with part 'all_1_1_0' reason: 'Serialization error: part all_1_1_0 is locked by transaction 5672402456378293316'. This error maybe retryable or not. In case of unretryable error, mutation can be killed with KILL MUTATION query. (UNFINISHED) (version 24.10.2.80 (official build)) + at com.clickhouse.jdbc.SqlExceptionUtils.batchUpdateError(SqlExceptionUtils.java:107) + at com.clickhouse.jdbc.internal.SqlBasedPreparedStatement.executeAny(SqlBasedPreparedStatement.java:223) + at com.clickhouse.jdbc.internal.SqlBasedPreparedStatement.executeLargeUpdate(SqlBasedPreparedStatement.java:302) + at com.clickhouse.jdbc.internal.AbstractPreparedStatement.executeUpdate(AbstractPreparedStatement.java:135) +``` + ### 嵌入式 ClickHouse 限制 嵌入式 ClickHouse `chDB` 尚未发布 Java 客户端, diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.en.md b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.en.md index 43205c1ebdc76..9cfd11bacf31c 100644 --- a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.en.md +++ b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/clickhouse/_index.en.md @@ -81,7 +81,7 @@ create table IF NOT EXISTS t_order ( order_type Int32, user_id Int32 NOT NULL, address_id Int64 NOT NULL, - status String + status VARCHAR(50) ) engine = MergeTree primary key (order_id) order by (order_id); @@ -160,7 +160,8 @@ public class ExampleUtils { ### SQL Limitations -ShardingSphere JDBC DataSource does not yet support the execution of ClickHouse's `CREATE TABLE` statement and `TRUNCATE TABLE` statement. +ShardingSphere JDBC DataSource does not yet support executing ClickHouse's `create table`, `truncate table`, +and `drop table` statements. Users should consider submitting a PR containing unit tests for ShardingSphere. ### Key Generate restrictions @@ -212,8 +213,176 @@ public class ExampleTest { ### Transaction Limitations -ClickHouse does not support ShardingSphere integration-level local transactions, XA transactions, and Seata AT mode transactions. -More discussions are at https://github.com/ClickHouse/clickhouse-docs/issues/2300 . +ClickHouse does not support XA transactions at the ShardingSphere integration level, +because https://github.com/ClickHouse/clickhouse-java does not implement the relevant Java interface of `javax.sql.XADataSource`. + +ClickHouse does not support Seata AT mode transactions at the ShardingSphere integration level, +because https://github.com/apache/incubator-seata does not implement ClickHouse's SQL dialect parsing. + +ClickHouse supports local transactions at the ShardingSphere integration level, but additional configuration of ClickHouse is required, +For more discussion, please visit https://github.com/ClickHouse/clickhouse-docs/issues/2300 . + +Introduce the discussion of writing a Docker Compose file to start ClickHouse and ClickHouse Keeper. + +```yaml +services: + clickhouse-keeper-01: + image: clickhouse/clickhouse-keeper:24.10.2.80 + volumes: + - ./keeper_config.xml:/etc/clickhouse-keeper/keeper_config.xml + clickhouse-server: + image: clickhouse/clickhouse-server:24.10.2.80 + depends_on: + - clickhouse-keeper-01 + ports: + - "8123:8123" + volumes: + - ./transactions.xml:/etc/clickhouse-server/config.d/transactions.xml +``` + +The content of `./keeper_config.xml` is as follows, + +```xml + + 0.0.0.0 + + 9181 + 1 + /var/lib/clickhouse/coordination/snapshots + + + 1 + clickhouse-keeper-01 + 9234 + + + + +``` + +The content of `./transactions.xml` is as follows, + +```xml + + 1 + + + clickhouse-keeper-01 + 9181 + + + +``` + +In DBeaver Community, use `jdbcUrl` of `jdbc:ch://localhost:8123/default`, `username` of `default` to connect to ClickHouse, +and leave `password` blank. Execute the following SQL, + +```sql +-- noinspection SqlNoDataSourceInspectionForFile +CREATE DATABASE demo_ds_0; +CREATE DATABASE demo_ds_1; +CREATE DATABASE demo_ds_2; +``` + +Use `jdbcUrl` of `jdbc:ch://localhost:8123/demo_ds_0`, `jdbc:ch://localhost:8123/demo_ds_1` +and `jdbc:ch://localhost:8123/demo_ds_2` to connect to ClickHouse and execute the following SQL. + +```sql +-- noinspection SqlNoDataSourceInspectionForFile +create table IF NOT EXISTS t_order ( + order_id Int64 NOT NULL, + order_type Int32, + user_id Int32 NOT NULL, + address_id Int64 NOT NULL, + status VARCHAR(50) +) engine = MergeTree + primary key (order_id) + order by (order_id); + +TRUNCATE TABLE t_order; +``` + +After the business project introduces the dependencies involved in the `prerequisites`, +write the ShardingSphere data source configuration file `demo.yaml` on the classpath of the business project. + +```yaml +dataSources: + ds_0: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: com.clickhouse.jdbc.ClickHouseDriver + jdbcUrl: jdbc:ch://localhost:8123/demo_ds_0?transactionSupport=true + ds_1: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: com.clickhouse.jdbc.ClickHouseDriver + jdbcUrl: jdbc:ch://localhost:8123/demo_ds_1?transactionSupport=true + ds_2: + dataSourceClassName: com.zaxxer.hikari.HikariDataSource + driverClassName: com.clickhouse.jdbc.ClickHouseDriver + jdbcUrl: jdbc:ch://localhost:8123/demo_ds_2?transactionSupport=true +rules: +- !SHARDING + tables: + t_order: + actualDataNodes: + keyGenerateStrategy: + column: order_id + keyGeneratorName: snowflake + defaultDatabaseStrategy: + standard: + shardingColumn: user_id + shardingAlgorithmName: inline + shardingAlgorithms: + inline: + type: INLINE + props: + algorithm-expression: ds_${user_id % 2} + keyGenerators: + snowflake: + type: SNOWFLAKE +``` + +After creating the ShardingSphere data source, local transactions can be used normally. + +```java +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import java.sql.Connection; +import java.sql.SQLException; +@SuppressWarnings({"SqlNoDataSourceInspection", "AssertWithSideEffects"}) +public class ExampleUtils { + void test() throws SQLException { + HikariConfig config = new HikariConfig(); + config.setJdbcUrl("jdbc:shardingsphere:classpath:demo.yaml"); + config.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver"); + try (HikariDataSource dataSource = new HikariDataSource(config); Connection connection = dataSource.getConnection()) { + try { + connection.setAutoCommit(false); + connection.createStatement().executeUpdate("INSERT INTO t_order (user_id, order_type, address_id, status) VALUES (2024, 0, 2024, 'INSERT_TEST')"); + connection.createStatement().executeUpdate("INSERT INTO t_order_does_not_exist (test_id_does_not_exist) VALUES (2024)"); + connection.commit(); + } catch (final SQLException ignored) { + connection.rollback(); + } finally { + connection.setAutoCommit(true); + } + try (Connection conn = dataSource.getConnection()) { + assert !conn.createStatement().executeQuery("SELECT * FROM t_order WHERE user_id = 2024").next(); + } + } + } +} +``` + +Once `transactionSupport=true` is set for the jdbcUrl of ClickHouse JDBC Driver in the ShardingSphere configuration file, +users should ensure that there are no unfinished `insert` statements before executing the `alter table` statement to avoid the following Error. + +```shell +java.sql.BatchUpdateException: Code: 341. DB::Exception: Exception happened during execution of mutation 'mutation_6.txt' with part 'all_1_1_0' reason: 'Serialization error: part all_1_1_0 is locked by transaction 5672402456378293316'. This error maybe retryable or not. In case of unretryable error, mutation can be killed with KILL MUTATION query. (UNFINISHED) (version 24.10.2.80 (official build)) + at com.clickhouse.jdbc.SqlExceptionUtils.batchUpdateError(SqlExceptionUtils.java:107) + at com.clickhouse.jdbc.internal.SqlBasedPreparedStatement.executeAny(SqlBasedPreparedStatement.java:223) + at com.clickhouse.jdbc.internal.SqlBasedPreparedStatement.executeLargeUpdate(SqlBasedPreparedStatement.java:302) + at com.clickhouse.jdbc.internal.AbstractPreparedStatement.executeUpdate(AbstractPreparedStatement.java:135) +``` ### Embedded ClickHouse Limitations diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.cn.md b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.cn.md index bb11ed7def68a..239a753ec74c4 100644 --- a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.cn.md +++ b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.cn.md @@ -130,7 +130,7 @@ set iceberg.mr.schema.auto.conversion=true; CREATE TABLE IF NOT EXISTS t_order ( - order_id BIGINT, + order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, @@ -260,7 +260,7 @@ set iceberg.mr.schema.auto.conversion=true; CREATE TABLE IF NOT EXISTS t_order ( - order_id BIGINT, + order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, @@ -380,7 +380,7 @@ set iceberg.mr.schema.auto.conversion=true; CREATE TABLE IF NOT EXISTS t_order ( - order_id BIGINT, + order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, @@ -438,8 +438,9 @@ HiveServer2 JDBC Driver `4.0.1` 不支持 Hadoop `3.4.1`, ### SQL 限制 -ShardingSphere JDBC DataSource 尚不支持执行 HiveServer2 的 `SET` 语句,`CREATE TABLE` 语句和 `TRUNCATE TABLE` 语句。 +HiveServer2 并不能保证每一条 `insert` 相关的 DML SQL 都能成功执行,尽管可能没有任何异常被抛出。 +ShardingSphere JDBC DataSource 尚不支持执行 HiveServer2 的 `set`,`create table`,`truncate table` 和 `drop table` 语句。 用户应考虑为 ShardingSphere 提交包含单元测试的 PR。 ### 在 ShardingSphere 数据源上使用 DML SQL 语句的前提条件 @@ -462,7 +463,7 @@ set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; CREATE TABLE IF NOT EXISTS t_order ( - order_id BIGINT, + order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, @@ -480,7 +481,7 @@ set iceberg.mr.schema.auto.conversion=true; CREATE TABLE IF NOT EXISTS t_order ( - order_id BIGINT, + order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.en.md b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.en.md index 38c6781a568e2..91967f757f8b1 100644 --- a/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.en.md +++ b/docs/document/content/user-manual/shardingsphere-jdbc/optional-plugins/hiveserver2/_index.en.md @@ -133,7 +133,7 @@ set iceberg.mr.schema.auto.conversion=true; CREATE TABLE IF NOT EXISTS t_order ( - order_id BIGINT, + order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, @@ -264,7 +264,7 @@ set iceberg.mr.schema.auto.conversion=true; CREATE TABLE IF NOT EXISTS t_order ( - order_id BIGINT, + order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, @@ -385,7 +385,7 @@ set iceberg.mr.schema.auto.conversion=true; CREATE TABLE IF NOT EXISTS t_order ( - order_id BIGINT, + order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, @@ -444,9 +444,10 @@ Reference https://github.com/apache/hive/pull/5500. ### SQL Limitations -ShardingSphere JDBC DataSource does not yet support executing HiveServer2's `SET` statement, -`CREATE TABLE` statement, and `TRUNCATE TABLE` statement. +HiveServer2 does not guarantee that every `insert` related DML SQL can be executed successfully, although no exception may be thrown. +ShardingSphere JDBC DataSource does not yet support executing HiveServer2's `set`, `create table`, `truncate table`, +and `drop table` statements. Users should consider submitting a PR containing unit tests for ShardingSphere. ### Prerequisites for using DML SQL statements on ShardingSphere data sources @@ -471,7 +472,7 @@ set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; CREATE TABLE IF NOT EXISTS t_order ( - order_id BIGINT, + order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, @@ -489,7 +490,7 @@ set iceberg.mr.schema.auto.conversion=true; CREATE TABLE IF NOT EXISTS t_order ( - order_id BIGINT, + order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, diff --git a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/reflect-config.json b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/reflect-config.json index fe75b38e7ab6d..c09eb7197a5b9 100644 --- a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/reflect-config.json +++ b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/reflect-config.json @@ -16,7 +16,7 @@ "name":"[Lcom.github.dockerjava.api.model.VolumesFrom;" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007f4b07ce0c30"}, + "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007ff897cab858"}, "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;" }, { @@ -1067,7 +1067,7 @@ "name":"org.apache.shardingsphere.driver.yaml.YamlJDBCConfiguration", "allDeclaredFields":true, "queryAllPublicMethods":true, - "methods":[{"name":"","parameterTypes":[] }, {"name":"setDataSources","parameterTypes":["java.util.Map"] }, {"name":"setMode","parameterTypes":["org.apache.shardingsphere.infra.yaml.config.pojo.mode.YamlModeConfiguration"] }, {"name":"setRules","parameterTypes":["java.util.Collection"] }, {"name":"setSqlParser","parameterTypes":["org.apache.shardingsphere.parser.yaml.config.YamlSQLParserRuleConfiguration"] }, {"name":"setTransaction","parameterTypes":["org.apache.shardingsphere.transaction.yaml.config.YamlTransactionRuleConfiguration"] }] + "methods":[{"name":"","parameterTypes":[] }, {"name":"setDataSources","parameterTypes":["java.util.Map"] }, {"name":"setMode","parameterTypes":["org.apache.shardingsphere.infra.yaml.config.pojo.mode.YamlModeConfiguration"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }, {"name":"setRules","parameterTypes":["java.util.Collection"] }, {"name":"setSqlParser","parameterTypes":["org.apache.shardingsphere.parser.yaml.config.YamlSQLParserRuleConfiguration"] }, {"name":"setTransaction","parameterTypes":["org.apache.shardingsphere.transaction.yaml.config.YamlTransactionRuleConfiguration"] }] }, { "condition":{"typeReachable":"org.apache.shardingsphere.infra.util.yaml.YamlEngine"}, @@ -2074,7 +2074,7 @@ "queryAllDeclaredMethods":true }, { - "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.listener.DatabaseMetaDataChangedListener$$Lambda/0x00007f4b07b277d8"}, + "condition":{"typeReachable":"org.apache.shardingsphere.mode.manager.cluster.listener.DatabaseMetaDataChangedListener$$Lambda/0x00007ff897b26e30"}, "name":"org.apache.shardingsphere.mode.manager.cluster.event.subscriber.dispatch.MetaDataChangedSubscriber" }, { diff --git a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/resource-config.json b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/resource-config.json index 294fcfe11ad1e..2c4176936c6ca 100644 --- a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/resource-config.json +++ b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/generated-reachability-metadata/resource-config.json @@ -79,7 +79,7 @@ "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager"}, "pattern":"\\QMETA-INF/services/com.clickhouse.client.ClickHouseClient\\E" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007f4b07b34b38"}, + "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007ff897b369d0"}, "pattern":"\\QMETA-INF/services/com.clickhouse.client.ClickHouseClient\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource"}, diff --git a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/shardingsphere-infra-reachability-metadata/reflect-config.json b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/shardingsphere-infra-reachability-metadata/reflect-config.json index 46d056e7c417f..4597bf4a5967c 100644 --- a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/shardingsphere-infra-reachability-metadata/reflect-config.json +++ b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/shardingsphere-infra-reachability-metadata/reflect-config.json @@ -304,21 +304,6 @@ "name":"org.apache.shardingsphere.sql.parser.postgresql.visitor.statement.type.PostgreSQLTCLStatementVisitor", "methods":[{"name":"","parameterTypes":[] }] }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.sql.parser.clickhouse.parser.ClickHouseLexer"}, - "name":"org.apache.shardingsphere.sql.parser.clickhouse.parser.ClickHouseLexer", - "methods":[{"name":"","parameterTypes":["org.antlr.v4.runtime.CharStream"] }] -}, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.sql.parser.clickhouse.parser.ClickHouseParser"}, - "name":"org.apache.shardingsphere.sql.parser.clickhouse.parser.ClickHouseParser", - "methods":[{"name":"","parameterTypes":["org.antlr.v4.runtime.TokenStream"] }] -}, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.sql.parser.clickhouse.visitor.statement.type.ClickHouseDMLStatementVisitor"}, - "name":"org.apache.shardingsphere.sql.parser.clickhouse.visitor.statement.type.ClickHouseDMLStatementVisitor", - "methods":[{"name":"","parameterTypes":[] }] -}, { "condition":{"typeReachable":"org.apache.shardingsphere.sharding.yaml.config.strategy.sharding.YamlBaseShardingStrategyConfiguration"}, "name":"org.apache.shardingsphere.sharding.yaml.config.strategy.sharding.YamlBaseShardingStrategyConfiguration", diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/TestShardingService.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/TestShardingService.java index b2f6ac9259099..37a78afc0370b 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/TestShardingService.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/TestShardingService.java @@ -176,14 +176,14 @@ public void deleteData(final Collection orderIds) throws SQLException { /** * Delete data in ClickHouse. - * TODO It is necessary to avoid the use of {@code Awaitility.await().pollDelay(Duration.ofSeconds(9L)).until(()->true)}. + * TODO It is necessary to avoid the use of {@code Awaitility.await().pollDelay(Duration.ofSeconds(5L)).until(()->true)}. * After ClickHouse enables experimental transactions, performance drops significantly. * * @param orderIds orderId of the insert statement. * @throws SQLException An exception that provides information on a database access error or other errors. */ public void deleteDataInClickHouse(final Collection orderIds) throws SQLException { - Awaitility.await().pollDelay(Duration.ofSeconds(9L)).until(() -> true); + Awaitility.await().pollDelay(Duration.ofSeconds(5L)).until(() -> true); long count = 1L; for (Long each : orderIds) { orderRepository.deleteInClickHouse(each); diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/AddressRepository.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/AddressRepository.java index 2797433e0a61f..1774289c577ce 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/AddressRepository.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/AddressRepository.java @@ -70,25 +70,6 @@ public void createTableInSQLServer() throws SQLException { } } - /** - * create table t_address if not exists in Hive. - * - * @throws SQLException SQL exception - */ - public void createTableIfNotExistsInHive() throws SQLException { - String sql = "CREATE TABLE IF NOT EXISTS t_address\n" - + "(\n" - + " address_id BIGINT NOT NULL,\n" - + " address_name VARCHAR(100) NOT NULL,\n" - + " PRIMARY KEY (address_id) disable novalidate\n" - + ") STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2')"; - try ( - Connection connection = dataSource.getConnection(); - Statement statement = connection.createStatement()) { - statement.executeUpdate(sql); - } - } - /** * drop table t_address. * diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderItemRepository.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderItemRepository.java index 180bc6ef0e7f0..bcd26777467dd 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderItemRepository.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderItemRepository.java @@ -102,52 +102,6 @@ public void createTableInSQLServer() throws SQLException { } } - /** - * create table if not exists in ClickHouse. - * ClickHouse does not support `AUTO_INCREMENT`, refer to ClickHouse/ClickHouse#56228 . - * - * @throws SQLException SQL exception - */ - public void createTableIfNotExistsInClickHouse() throws SQLException { - String sql = "create table IF NOT EXISTS t_order_item( \n" - + "order_item_id Int64 NOT NULL, \n" - + "order_id Int64 NOT NULL, \n" - + "user_id Int32 NOT NULL, \n" - + "phone String,\n" - + "status String\n" - + ") engine = MergeTree \n" - + "primary key (order_item_id)\n" - + "order by(order_item_id); "; - try ( - Connection connection = dataSource.getConnection(); - Statement statement = connection.createStatement()) { - statement.executeUpdate(sql); - } - } - - /** - * create table if not exists in Hive. - * Hive does not support `AUTO_INCREMENT`, refer to HIVE-6905 . - * - * @throws SQLException SQL exception - */ - public void createTableIfNotExistsInHive() throws SQLException { - String sql = "CREATE TABLE IF NOT EXISTS t_order_item\n" - + "(\n" - + " order_item_id BIGINT,\n" - + " order_id BIGINT NOT NULL,\n" - + " user_id INT NOT NULL,\n" - + " phone VARCHAR(50),\n" - + " status VARCHAR(50),\n" - + " PRIMARY KEY (order_item_id) disable novalidate\n" - + ") STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2')"; - try ( - Connection connection = dataSource.getConnection(); - Statement statement = connection.createStatement()) { - statement.executeUpdate(sql); - } - } - /** * drop table. * @@ -323,22 +277,23 @@ public List selectAll() throws SQLException { /** * Assert rollback with transactions. - * This is currently just a simple test against a non-existent table and does not involve the competition scenario of distributed transactions. + * This is currently just a simple test against a non-existent table {@code t_order_item_does_not_exist} + * and does not involve the competition scenario of distributed transactions. * * @throws SQLException An exception that provides information on a database access error or other errors. */ public void assertRollbackWithTransactions() throws SQLException { - Connection connection = dataSource.getConnection(); - try { - connection.setAutoCommit(false); - connection.createStatement().executeUpdate("INSERT INTO t_order_item (order_id, user_id, phone, status) VALUES (2024, 2024, '13800000001', 'INSERT_TEST')"); - connection.createStatement().executeUpdate("INSERT INTO t_order_item_does_not_exist (test_id_does_not_exist) VALUES (2024)"); - connection.commit(); - } catch (final SQLException ignored) { - connection.rollback(); - } finally { - connection.setAutoCommit(true); - connection.close(); + try (Connection connection = dataSource.getConnection()) { + try { + connection.setAutoCommit(false); + connection.createStatement().executeUpdate("INSERT INTO t_order_item (order_id, user_id, phone, status) VALUES (2024, 2024, '13800000001', 'INSERT_TEST')"); + connection.createStatement().executeUpdate("INSERT INTO t_order_item_does_not_exist (test_id_does_not_exist) VALUES (2024)"); + connection.commit(); + } catch (final SQLException ignored) { + connection.rollback(); + } finally { + connection.setAutoCommit(true); + } } try ( Connection conn = dataSource.getConnection(); diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderRepository.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderRepository.java index 73e2679472322..8e9683b529044 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderRepository.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/commons/repository/OrderRepository.java @@ -99,52 +99,6 @@ public void createTableInSQLServer() throws SQLException { } } - /** - * create table in ClickHouse. - * ClickHouse does not support `AUTO_INCREMENT`, refer to ClickHouse/ClickHouse#56228 . - * - * @throws SQLException SQL exception - */ - public void createTableIfNotExistsInClickHouse() throws SQLException { - String sql = "create table IF NOT EXISTS t_order( \n" - + "order_id Int64 NOT NULL, \n" - + "order_type Int32, \n" - + "user_id Int32 NOT NULL, \n" - + "address_id Int64 NOT NULL,\n" - + "status String\n" - + ") engine = MergeTree \n" - + "primary key (order_id)\n" - + "order by(order_id)"; - try ( - Connection connection = dataSource.getConnection(); - Statement statement = connection.createStatement()) { - statement.executeUpdate(sql); - } - } - - /** - * create table in Hive. - * Hive does not support `AUTO_INCREMENT`, refer to HIVE-6905 . - * - * @throws SQLException SQL exception - */ - public void createTableIfNotExistsInHive() throws SQLException { - String sql = "CREATE TABLE IF NOT EXISTS t_order\n" - + "(\n" - + " order_id BIGINT,\n" - + " order_type INT,\n" - + " user_id INT NOT NULL,\n" - + " address_id BIGINT NOT NULL,\n" - + " status VARCHAR(50),\n" - + " PRIMARY KEY (order_id) disable novalidate\n" - + ") STORED BY ICEBERG STORED AS ORC TBLPROPERTIES ('format-version' = '2')"; - try ( - Connection connection = dataSource.getConnection(); - Statement statement = connection.createStatement()) { - statement.executeUpdate(sql); - } - } - /** * drop table. * TODO There is a bug in this function in shadow's unit test and requires additional fixes. diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/ClickHouseTest.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/ClickHouseTest.java index db2ad31090b52..b24a06dac8fc2 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/ClickHouseTest.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/ClickHouseTest.java @@ -33,6 +33,7 @@ import org.testcontainers.utility.MountableFile; import javax.sql.DataSource; +import java.nio.file.Paths; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; @@ -57,23 +58,25 @@ class ClickHouseTest { private static final Network NETWORK = Network.newNetwork(); @Container - private static final GenericContainer ZOOKEEPER_CONTAINER = new GenericContainer<>("zookeeper:3.9.3-jre-17") + private static final GenericContainer CLICKHOUSE_KEEPER_CONTAINER = new GenericContainer<>("clickhouse/clickhouse-keeper:24.10.2.80") + .withCopyFileToContainer( + MountableFile.forHostPath(Paths.get("src/test/resources/test-native/xml/keeper_config.xml").toAbsolutePath()), + "/etc/clickhouse-keeper/keeper_config.xml") .withNetwork(NETWORK) - .withNetworkAliases("foo"); + .withNetworkAliases("clickhouse-keeper-01"); @Container public static final ClickHouseContainer CONTAINER = new ClickHouseContainer("clickhouse/clickhouse-server:24.10.2.80") - .withCopyFileToContainer(MountableFile.forClasspathResource("test-native/xml/clickhouse-transactions.xml"), + .withCopyFileToContainer( + MountableFile.forHostPath(Paths.get("src/test/resources/test-native/xml/transactions.xml").toAbsolutePath()), "/etc/clickhouse-server/config.d/transactions.xml") .withNetwork(NETWORK) - .dependsOn(ZOOKEEPER_CONTAINER); + .dependsOn(CLICKHOUSE_KEEPER_CONTAINER); private static final String SYSTEM_PROP_KEY_PREFIX = "fixture.test-native.yaml.database.clickhouse."; private String jdbcUrlPrefix; - private TestShardingService testShardingService; - @BeforeAll static void beforeAll() { assertThat(System.getProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url"), is(nullValue())); @@ -90,33 +93,17 @@ static void afterAll() { } /** - * TODO Need to fix `shardingsphere-parser-sql-clickhouse` module to use {@link TestShardingService#cleanEnvironment()} - * after {@link TestShardingService#processSuccessInClickHouse()}. + * TODO The {@code shardingsphere-parser-sql-clickhouse} module needs to be fixed to use SQL like `create table`, + * `truncate table` and `drop table`. */ @Test void assertShardingInLocalTransactions() throws SQLException { jdbcUrlPrefix = "jdbc:ch://localhost:" + CONTAINER.getMappedPort(8123) + "/"; DataSource dataSource = createDataSource(); - testShardingService = new TestShardingService(dataSource); + TestShardingService testShardingService = new TestShardingService(dataSource); testShardingService.processSuccessInClickHouse(); } - /** - * TODO Need to fix `shardingsphere-parser-sql-clickhouse` module to use `initEnvironment()` - * before {@link TestShardingService#processSuccessInClickHouse()}. - * - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - @SuppressWarnings("unused") - private void initEnvironment() throws SQLException { - testShardingService.getOrderRepository().createTableIfNotExistsInClickHouse(); - testShardingService.getOrderItemRepository().createTableIfNotExistsInClickHouse(); - testShardingService.getAddressRepository().createTableIfNotExistsInMySQL(); - testShardingService.getOrderRepository().truncateTable(); - testShardingService.getOrderItemRepository().truncateTable(); - testShardingService.getAddressRepository().truncateTable(); - } - private Connection openConnection(final String databaseName) throws SQLException { Properties props = new Properties(); props.setProperty("user", CONTAINER.getUsername()); @@ -146,6 +133,13 @@ private DataSource createDataSource() throws SQLException { return new HikariDataSource(config); } + /** + * ClickHouse does not support `AUTO_INCREMENT`, + * refer to ClickHouse/ClickHouse#56228 . + * + * @param databaseName database name + * @throws RuntimeException SQL exception + */ private void initTable(final String databaseName) { try ( Connection connection = openConnection(databaseName); @@ -156,7 +150,7 @@ private void initTable(final String databaseName) { + " order_type Int32,\n" + " user_id Int32 NOT NULL,\n" + " address_id Int64 NOT NULL,\n" - + " status String\n" + + " status VARCHAR(50)\n" + ") engine = MergeTree\n" + " primary key (order_id)\n" + " order by (order_id)"); @@ -165,8 +159,8 @@ private void initTable(final String databaseName) { + " order_item_id Int64 NOT NULL,\n" + " order_id Int64 NOT NULL,\n" + " user_id Int32 NOT NULL,\n" - + " phone String,\n" - + " status String\n" + + " phone VARCHAR(50),\n" + + " status VARCHAR(50)\n" + ") engine = MergeTree\n" + " primary key (order_item_id)\n" + " order by (order_item_id)"); diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveSimpleTest.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveSimpleTest.java index adaa894756bc4..72e0e781489b6 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveSimpleTest.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveSimpleTest.java @@ -56,12 +56,10 @@ class HiveSimpleTest { private static final String SYSTEM_PROP_KEY_PREFIX = "fixture.test-native.yaml.database.hive.simple."; // Due to https://issues.apache.org/jira/browse/HIVE-28317 , the `initFile` parameter of HiveServer2 JDBC Driver must be an absolute path. - private static final String ABSOLUTE_PATH = Paths.get("src/test/resources/test-native/sql/test-native-databases-hive.sql").toAbsolutePath().normalize().toString(); + private static final String ABSOLUTE_PATH = Paths.get("src/test/resources/test-native/sql/test-native-databases-hive.sql").toAbsolutePath().toString(); private String jdbcUrlPrefix; - private TestShardingService testShardingService; - @BeforeAll static void beforeAll() { assertThat(System.getProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url"), is(nullValue())); @@ -76,35 +74,14 @@ static void afterAll() { System.clearProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url"); } - /** - * TODO Need to fix `shardingsphere-parser-sql-hive` module to use {@link TestShardingService#cleanEnvironment()} - * after {@link TestShardingService#processSuccessInHive()}. - * - * @throws SQLException An exception that provides information on a database access error or other errors. - */ @Test void assertShardingInLocalTransactions() throws SQLException { jdbcUrlPrefix = "jdbc:hive2://localhost:" + CONTAINER.getMappedPort(10000) + "/"; DataSource dataSource = createDataSource(); - testShardingService = new TestShardingService(dataSource); + TestShardingService testShardingService = new TestShardingService(dataSource); testShardingService.processSuccessInHive(); } - /** - * TODO Need to fix `shardingsphere-parser-sql-hive` module to use `initEnvironment()` before {@link TestShardingService#processSuccessInHive()}. - * - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - @SuppressWarnings("unused") - private void initEnvironment() throws SQLException { - testShardingService.getOrderRepository().createTableIfNotExistsInHive(); - testShardingService.getOrderItemRepository().createTableIfNotExistsInHive(); - testShardingService.getAddressRepository().createTableIfNotExistsInHive(); - testShardingService.getOrderRepository().truncateTable(); - testShardingService.getOrderItemRepository().truncateTable(); - testShardingService.getAddressRepository().truncateTable(); - } - private Connection openConnection() throws SQLException { Properties props = new Properties(); return DriverManager.getConnection(jdbcUrlPrefix, props); diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveZookeeperServiceDiscoveryTest.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveZookeeperServiceDiscoveryTest.java index 1debb4aa849bf..5c6a9e7c35da7 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveZookeeperServiceDiscoveryTest.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/jdbc/databases/hive/HiveZookeeperServiceDiscoveryTest.java @@ -67,6 +67,7 @@ class HiveZookeeperServiceDiscoveryTest { /** * TODO Maybe we should be able to find a better solution than {@link InstanceSpec#getRandomPort()} to use a random available port on the host. * It is not a good practice to use {@link FixedHostPortGenericContainer}. + * See testcontainers/testcontainers-java#9553 . */ @SuppressWarnings("unused") @Container @@ -83,14 +84,12 @@ class HiveZookeeperServiceDiscoveryTest { private static final String SYSTEM_PROP_KEY_PREFIX = "fixture.test-native.yaml.database.hive.zookeeper.sde."; // Due to https://issues.apache.org/jira/browse/HIVE-28317 , the `initFile` parameter of HiveServer2 JDBC Driver must be an absolute path. - private static final String ABSOLUTE_PATH = Paths.get("src/test/resources/test-native/sql/test-native-databases-hive.sql").toAbsolutePath().normalize().toString(); + private static final String ABSOLUTE_PATH = Paths.get("src/test/resources/test-native/sql/test-native-databases-hive.sql").toAbsolutePath().toString(); private final String jdbcUrlSuffix = ";serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2"; private String jdbcUrlPrefix; - private TestShardingService testShardingService; - @BeforeAll static void beforeAll() { assertThat(System.getProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url"), is(nullValue())); @@ -107,8 +106,6 @@ static void afterAll() { } /** - * TODO Need to fix `shardingsphere-parser-sql-hive` module to use {@link TestShardingService#cleanEnvironment()} - * after {@link TestShardingService#processSuccessInHive()}. * TODO Same problem {@link InstanceSpec#getRandomPort()} as {@code HIVE_SERVER2_1_CONTAINER}. * * @throws SQLException An exception that provides information on a database access error or other errors. @@ -117,7 +114,7 @@ static void afterAll() { void assertShardingInLocalTransactions() throws SQLException { jdbcUrlPrefix = "jdbc:hive2://" + ZOOKEEPER_CONTAINER.getHost() + ":" + ZOOKEEPER_CONTAINER.getMappedPort(2181) + "/"; DataSource dataSource = createDataSource(); - testShardingService = new TestShardingService(dataSource); + TestShardingService testShardingService = new TestShardingService(dataSource); testShardingService.processSuccessInHive(); HIVE_SERVER2_1_CONTAINER.stop(); int randomPortSecond = InstanceSpec.getRandomPort(); @@ -137,21 +134,6 @@ void assertShardingInLocalTransactions() throws SQLException { } } - /** - * TODO Need to fix `shardingsphere-parser-sql-hive` module to use `initEnvironment()` before {@link TestShardingService#processSuccessInHive()}. - * - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - @SuppressWarnings("unused") - private void initEnvironment() throws SQLException { - testShardingService.getOrderRepository().createTableIfNotExistsInHive(); - testShardingService.getOrderItemRepository().createTableIfNotExistsInHive(); - testShardingService.getAddressRepository().createTableIfNotExistsInHive(); - testShardingService.getOrderRepository().truncateTable(); - testShardingService.getOrderItemRepository().truncateTable(); - testShardingService.getAddressRepository().truncateTable(); - } - private Connection openConnection() throws SQLException { Properties props = new Properties(); return DriverManager.getConnection(jdbcUrlPrefix + jdbcUrlSuffix, props); diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/proxy/databases/PostgresTest.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/proxy/databases/PostgresTest.java index cc1a1625612c1..4e5413aba1a95 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/proxy/databases/PostgresTest.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/proxy/databases/PostgresTest.java @@ -67,7 +67,7 @@ static void beforeAll() throws SQLException { statement.executeUpdate("CREATE DATABASE demo_ds_1"); statement.executeUpdate("CREATE DATABASE demo_ds_2"); } - String absolutePath = Paths.get("src/test/resources/test-native/yaml/proxy/databases/postgresql").toAbsolutePath().normalize().toString(); + String absolutePath = Paths.get("src/test/resources/test-native/yaml/proxy/databases/postgresql").toAbsolutePath().toString(); proxyTestingServer = new ProxyTestingServer(absolutePath); Awaitility.await().atMost(Duration.ofSeconds(30L)).ignoreExceptions().until(() -> { openConnection("root", "root", "jdbc:postgresql://127.0.0.1:" + proxyTestingServer.getProxyPort() + "/postgres").close(); diff --git a/test/native/src/test/java/org/apache/shardingsphere/test/natived/proxy/features/ShardingTest.java b/test/native/src/test/java/org/apache/shardingsphere/test/natived/proxy/features/ShardingTest.java index 8c993bfb91752..3b318ea4f5501 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/test/natived/proxy/features/ShardingTest.java +++ b/test/native/src/test/java/org/apache/shardingsphere/test/natived/proxy/features/ShardingTest.java @@ -68,7 +68,7 @@ static void beforeAll() throws SQLException { statement.executeUpdate("CREATE DATABASE demo_ds_1"); statement.executeUpdate("CREATE DATABASE demo_ds_2"); } - String absolutePath = Paths.get("src/test/resources/test-native/yaml/proxy/features/sharding").toAbsolutePath().normalize().toString(); + String absolutePath = Paths.get("src/test/resources/test-native/yaml/proxy/features/sharding").toAbsolutePath().toString(); proxyTestingServer = new ProxyTestingServer(absolutePath); Awaitility.await().atMost(Duration.ofSeconds(30L)).ignoreExceptionsMatching(e -> e instanceof CommunicationsException).until(() -> { openConnection("root", "root", "jdbc:mysql://127.0.0.1:" + proxyTestingServer.getProxyPort()).close(); diff --git a/test/native/src/test/resources/META-INF/native-image/shardingsphere-test-native-test-metadata/resource-config.json b/test/native/src/test/resources/META-INF/native-image/shardingsphere-test-native-test-metadata/resource-config.json index 5a22d077ea78e..0f6f4683a75bf 100644 --- a/test/native/src/test/resources/META-INF/native-image/shardingsphere-test-native-test-metadata/resource-config.json +++ b/test/native/src/test/resources/META-INF/native-image/shardingsphere-test-native-test-metadata/resource-config.json @@ -6,6 +6,9 @@ }, { "condition":{"typeReachable":"org.apache.shardingsphere.test.natived.jdbc.transactions.base.SeataTest"}, "pattern":".*test-native/sql/.+\\.sql$" + }, { + "condition":{"typeReachable":"org.apache.shardingsphere.test.natived.jdbc.databases.ClickHouseTest"}, + "pattern":".*test-native/xml/.+\\.xml$" }, { "condition":{"typeReachable":"org.apache.shardingsphere.test.natived.jdbc.databases.SQLServerTest"}, "pattern":"\\Qcontainer-license-acceptance.txt\\E" diff --git a/test/native/src/test/resources/test-native/sql/test-native-databases-hive.sql b/test/native/src/test/resources/test-native/sql/test-native-databases-hive.sql index 43bc516e458e2..82f8d0dacfb00 100644 --- a/test/native/src/test/resources/test-native/sql/test-native-databases-hive.sql +++ b/test/native/src/test/resources/test-native/sql/test-native-databases-hive.sql @@ -15,15 +15,16 @@ -- limitations under the License. -- --- TODO `shardingsphere-parser-sql-hive` module does not support `CREATE`, `SET`, `TRUNCATE` statements yet, +-- TODO `shardingsphere-parser-sql-hive` module does not support `create table`, `truncate table` and `drop table` statements yet, -- we always need to execute the following Hive Session-level SQL in the current `javax.sql.DataSource`. +-- Hive does not support `AUTO_INCREMENT`, refer to HIVE-6905 . -- Fixes `Unsupported Hive type VARCHAR, use string instead or enable automatic type conversion, set 'iceberg.mr.schema.auto.conversion' to true` set iceberg.mr.schema.auto.conversion=true; CREATE TABLE IF NOT EXISTS t_order ( - order_id BIGINT, + order_id BIGINT NOT NULL, order_type INT, user_id INT NOT NULL, address_id BIGINT NOT NULL, @@ -33,7 +34,7 @@ CREATE TABLE IF NOT EXISTS t_order CREATE TABLE IF NOT EXISTS t_order_item ( - order_item_id BIGINT, + order_item_id BIGINT NOT NULL, order_id BIGINT NOT NULL, user_id INT NOT NULL, phone VARCHAR(50), diff --git a/test/native/src/test/resources/test-native/xml/keeper_config.xml b/test/native/src/test/resources/test-native/xml/keeper_config.xml new file mode 100644 index 0000000000000..2a7d254adfa74 --- /dev/null +++ b/test/native/src/test/resources/test-native/xml/keeper_config.xml @@ -0,0 +1,31 @@ + + + 0.0.0.0 + + 9181 + 1 + /var/lib/clickhouse/coordination/snapshots + + + 1 + clickhouse-keeper-01 + 9234 + + + + diff --git a/test/native/src/test/resources/test-native/xml/clickhouse-transactions.xml b/test/native/src/test/resources/test-native/xml/transactions.xml similarity index 92% rename from test/native/src/test/resources/test-native/xml/clickhouse-transactions.xml rename to test/native/src/test/resources/test-native/xml/transactions.xml index 4ded8989a1004..1c54dd5f003d5 100644 --- a/test/native/src/test/resources/test-native/xml/clickhouse-transactions.xml +++ b/test/native/src/test/resources/test-native/xml/transactions.xml @@ -18,8 +18,8 @@ 1 - foo - 2181 + clickhouse-keeper-01 + 9181 diff --git a/test/native/src/test/resources/test-native/yaml/jdbc/features/sharding.yaml b/test/native/src/test/resources/test-native/yaml/jdbc/features/sharding.yaml index c59e15721247a..7c572d08b61aa 100644 --- a/test/native/src/test/resources/test-native/yaml/jdbc/features/sharding.yaml +++ b/test/native/src/test/resources/test-native/yaml/jdbc/features/sharding.yaml @@ -71,3 +71,6 @@ rules: - !BROADCAST tables: - t_address + +props: + sql-show: false