You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by ji...@apache.org on 2023/03/07 06:32:21 UTC
[shardingsphere] branch master updated: Add DistSQL UNLOCK CLUSTER (#24483)
This is an automated email from the ASF dual-hosted git repository.
jianglongtao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 134a24a80df Add DistSQL UNLOCK CLUSTER (#24483)
134a24a80df is described below
commit 134a24a80df9ef1ec959ea217db8cfd6a6f4cc2f
Author: ChenJiaHao <Pa...@163.com>
AuthorDate: Tue Mar 7 14:32:02 2023 +0800
Add DistSQL UNLOCK CLUSTER (#24483)
* Add DistSQL UNLOCK CLUSTER
* Fix code style
---
distsql/parser/src/main/antlr4/imports/Keyword.g4 | 4 ++
.../parser/src/main/antlr4/imports/RALStatement.g4 | 4 ++
.../parser/autogen/KernelDistSQLStatement.g4 | 1 +
.../core/kernel/KernelDistSQLStatementVisitor.java | 17 ++++--
.../ral/updatable/UnlockClusterStatement.java | 28 ++++++++++
.../infra/state/ClusterStateContextTest.java | 55 +++++++++++++++++++
.../datasource/ShardingSphereDataSourceTest.java | 3 +
.../driver/state/DriverStateContextTest.java | 2 +
.../mode/manager/ContextManager.java | 61 +++++++++++----------
.../ral/updatable/UnlockClusterUpdater.java | 64 ++++++++++++++++++++++
.../lock/impl/ClusterWriteLockStrategy.java | 2 +-
.../backend/state/impl/ReadOnlyProxyState.java | 3 +-
.../backend/state/impl/UnavailableProxyState.java | 3 +-
...ingsphere.distsql.handler.ral.update.RALUpdater | 1 +
.../proxy/backend/context/ProxyContextTest.java | 3 +
.../ral/updatable/UnlockClusterUpdaterTest.java | 56 +++++++++++++++++++
16 files changed, 269 insertions(+), 38 deletions(-)
diff --git a/distsql/parser/src/main/antlr4/imports/Keyword.g4 b/distsql/parser/src/main/antlr4/imports/Keyword.g4
index 246204dcc5a..ed493046e4e 100644
--- a/distsql/parser/src/main/antlr4/imports/Keyword.g4
+++ b/distsql/parser/src/main/antlr4/imports/Keyword.g4
@@ -347,6 +347,10 @@ LOCK
: L O C K
;
+UNLOCK
+ : U N L O C K
+ ;
+
CLUSTER
: C L U S T E R
;
diff --git a/distsql/parser/src/main/antlr4/imports/RALStatement.g4 b/distsql/parser/src/main/antlr4/imports/RALStatement.g4
index 867a6ea03f2..fba79333737 100644
--- a/distsql/parser/src/main/antlr4/imports/RALStatement.g4
+++ b/distsql/parser/src/main/antlr4/imports/RALStatement.g4
@@ -107,6 +107,10 @@ lockCluster
: LOCK CLUSTER WITH lockStrategy
;
+unlockCluster
+ : UNLOCK CLUSTER
+ ;
+
inventoryIncrementalRule
: LP_ readDefinition? (COMMA_? writeDefinition)? (COMMA_? streamChannel)? RP_
;
diff --git a/distsql/parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/KernelDistSQLStatement.g4 b/distsql/parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/KernelDistSQLStatement.g4
index 212e77299db..842ab54e121 100644
--- a/distsql/parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/KernelDistSQLStatement.g4
+++ b/distsql/parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/KernelDistSQLStatement.g4
@@ -52,5 +52,6 @@ execute
| showMigrationRule
| alterMigrationRule
| lockCluster
+ | unlockCluster
) SEMI?
;
diff --git a/distsql/parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java b/distsql/parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java
index 86385dd2e04..8415701d7fa 100644
--- a/distsql/parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java
+++ b/distsql/parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java
@@ -64,6 +64,7 @@ import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementPa
import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.StorageUnitDefinitionContext;
import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.StreamChannelContext;
import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.UnlabelComputeNodeContext;
+import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.UnlockClusterContext;
import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.UnregisterStorageUnitContext;
import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.WorkerThreadContext;
import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.WriteDefinitionContext;
@@ -94,6 +95,7 @@ import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.RefreshT
import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.SetDistVariableStatement;
import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.SetInstanceStatusStatement;
import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.UnlabelComputeNodeStatement;
+import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.UnlockClusterStatement;
import org.apache.shardingsphere.distsql.parser.statement.rdl.alter.AlterStorageUnitStatement;
import org.apache.shardingsphere.distsql.parser.statement.rdl.create.RegisterStorageUnitStatement;
import org.apache.shardingsphere.distsql.parser.statement.rdl.create.SetDefaultSingleTableStorageUnitStatement;
@@ -359,11 +361,6 @@ public final class KernelDistSQLStatementVisitor extends KernelDistSQLStatementB
return null == ctx ? null : (AlgorithmSegment) visit(ctx);
}
- @Override
- public ASTNode visitLockCluster(final LockClusterContext ctx) {
- return new LockClusterStatement((AlgorithmSegment) visitAlgorithmDefinition(ctx.lockStrategy().algorithmDefinition()));
- }
-
@Override
public ASTNode visitAlgorithmDefinition(final AlgorithmDefinitionContext ctx) {
return new AlgorithmSegment(getIdentifierValue(ctx.algorithmTypeName()), buildProperties(ctx.propertiesDefinition()));
@@ -392,6 +389,16 @@ public final class KernelDistSQLStatementVisitor extends KernelDistSQLStatementB
return null == ctx ? null : Integer.parseInt(ctx.intValue().getText());
}
+ @Override
+ public ASTNode visitLockCluster(final LockClusterContext ctx) {
+ return new LockClusterStatement((AlgorithmSegment) visitAlgorithmDefinition(ctx.lockStrategy().algorithmDefinition()));
+ }
+
+ @Override
+ public ASTNode visitUnlockCluster(final UnlockClusterContext ctx) {
+ return new UnlockClusterStatement();
+ }
+
@Override
public ASTNode visitRateLimiter(final RateLimiterContext ctx) {
return visit(ctx.algorithmDefinition());
diff --git a/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/ral/updatable/UnlockClusterStatement.java b/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/ral/updatable/UnlockClusterStatement.java
new file mode 100644
index 00000000000..5caad8d5b07
--- /dev/null
+++ b/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/ral/updatable/UnlockClusterStatement.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.distsql.parser.statement.ral.updatable;
+
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.distsql.parser.statement.ral.UpdatableRALStatement;
+
+/**
+ * Unlock cluster statement.
+ */
+@RequiredArgsConstructor
+public final class UnlockClusterStatement extends UpdatableRALStatement {
+}
diff --git a/infra/common/src/test/java/org/apache/shardingsphere/infra/state/ClusterStateContextTest.java b/infra/common/src/test/java/org/apache/shardingsphere/infra/state/ClusterStateContextTest.java
new file mode 100644
index 00000000000..a2b3b811af4
--- /dev/null
+++ b/infra/common/src/test/java/org/apache/shardingsphere/infra/state/ClusterStateContextTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.infra.state;
+
+import org.apache.shardingsphere.infra.state.cluster.ClusterState;
+import org.apache.shardingsphere.infra.state.cluster.ClusterStateContext;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public final class ClusterStateContextTest {
+
+ private final ClusterStateContext clusterStateContext = new ClusterStateContext();
+
+ @Test
+ public void assertSwitchStateWithUnavailable() {
+ clusterStateContext.switchState(ClusterState.UNAVAILABLE);
+ assertThat(clusterStateContext.getCurrentState(), is(ClusterState.UNAVAILABLE));
+ clusterStateContext.switchState(ClusterState.OK);
+ }
+
+ @Test
+ public void assertSwitchStateWithReadOnly() {
+ clusterStateContext.switchState(ClusterState.READ_ONLY);
+ assertThat(clusterStateContext.getCurrentState(), is(ClusterState.READ_ONLY));
+ clusterStateContext.switchState(ClusterState.OK);
+ }
+
+ @Test
+ public void assertSwitchStateWithMultiStateChange() {
+ clusterStateContext.switchState(ClusterState.UNAVAILABLE);
+ assertThrows(IllegalStateException.class, () -> clusterStateContext.switchState(ClusterState.READ_ONLY));
+ clusterStateContext.switchState(ClusterState.OK);
+ clusterStateContext.switchState(ClusterState.READ_ONLY);
+ assertThat(clusterStateContext.getCurrentState(), is(ClusterState.READ_ONLY));
+ clusterStateContext.switchState(ClusterState.OK);
+ }
+}
diff --git a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/datasource/ShardingSphereDataSourceTest.java b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/datasource/ShardingSphereDataSourceTest.java
index b1304c9e879..f76bd390a69 100644
--- a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/datasource/ShardingSphereDataSourceTest.java
+++ b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/datasource/ShardingSphereDataSourceTest.java
@@ -23,6 +23,7 @@ import org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConne
import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
import org.apache.shardingsphere.infra.database.DefaultDatabase;
import org.apache.shardingsphere.infra.executor.sql.execute.engine.ConnectionMode;
+import org.apache.shardingsphere.infra.state.cluster.ClusterState;
import org.apache.shardingsphere.infra.state.instance.InstanceState;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.parser.config.SQLParserRuleConfiguration;
@@ -62,6 +63,7 @@ public final class ShardingSphereDataSourceTest {
ShardingSphereDataSource actual = new ShardingSphereDataSource(DefaultDatabase.LOGIC_NAME, null);
ContextManager contextManager = getContextManager(actual);
assertNotNull(contextManager.getMetaDataContexts().getMetaData().getDatabase(DefaultDatabase.LOGIC_NAME));
+ assertThat(contextManager.getClusterStateContext().getCurrentState(), is(ClusterState.OK));
assertThat(contextManager.getInstanceContext().getInstance().getState().getCurrentState(), is(InstanceState.OK));
assertTrue(contextManager.getDataSourceMap(DefaultDatabase.LOGIC_NAME).isEmpty());
}
@@ -73,6 +75,7 @@ public final class ShardingSphereDataSourceTest {
ShardingSphereDataSource actual = createShardingSphereDataSource(new MockedDataSource(connection));
ContextManager contextManager = getContextManager(actual);
assertNotNull(contextManager.getMetaDataContexts().getMetaData().getDatabase(DefaultDatabase.LOGIC_NAME));
+ assertThat(contextManager.getClusterStateContext().getCurrentState(), is(ClusterState.OK));
assertThat(contextManager.getInstanceContext().getInstance().getState().getCurrentState(), is(InstanceState.OK));
assertThat(contextManager.getDataSourceMap(DefaultDatabase.LOGIC_NAME).size(), is(1));
assertThat(contextManager.getDataSourceMap(DefaultDatabase.LOGIC_NAME).get("ds").getConnection().getMetaData().getURL(), is("jdbc:mock://127.0.0.1/foo_ds"));
diff --git a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/state/DriverStateContextTest.java b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/state/DriverStateContextTest.java
index 8505665b1a2..b1c5e6b3b5b 100644
--- a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/state/DriverStateContextTest.java
+++ b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/state/DriverStateContextTest.java
@@ -25,6 +25,7 @@ import org.apache.shardingsphere.infra.database.type.dialect.MySQLDatabaseType;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRuleMetaData;
+import org.apache.shardingsphere.infra.state.cluster.ClusterStateContext;
import org.apache.shardingsphere.infra.state.instance.InstanceStateContext;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
@@ -66,6 +67,7 @@ public final class DriverStateContextTest {
mock(MetaDataPersistService.class), new ShardingSphereMetaData(databases, globalRuleMetaData, new ConfigurationProperties(new Properties())));
when(contextManager.getMetaDataContexts()).thenReturn(metaDataContexts);
when(contextManager.getInstanceContext().getInstance().getState()).thenReturn(new InstanceStateContext());
+ when(contextManager.getClusterStateContext()).thenReturn(new ClusterStateContext());
}
private Map<String, ShardingSphereDatabase> mockDatabases() {
diff --git a/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
index 547f2631bd8..9d141a169b3 100644
--- a/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
+++ b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
@@ -94,7 +94,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Renew meta data contexts.
- *
+ *
* @param metaDataContexts meta data contexts
*/
public synchronized void renewMetaDataContexts(final MetaDataContexts metaDataContexts) {
@@ -103,7 +103,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Get data source map.
- *
+ *
* @param databaseName database name
* @return data source map
*/
@@ -113,7 +113,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Add database.
- *
+ *
* @param databaseName database name
*/
public synchronized void addDatabase(final String databaseName) {
@@ -126,7 +126,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Drop database.
- *
+ *
* @param databaseName database name
*/
public synchronized void dropDatabase(final String databaseName) {
@@ -139,7 +139,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Add schema.
- *
+ *
* @param databaseName database name
* @param schemaName schema name
*/
@@ -152,7 +152,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Drop schema.
- *
+ *
* @param databaseName database name
* @param schemaName schema name
*/
@@ -165,7 +165,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Alter schema.
- *
+ *
* @param databaseName database name
* @param schemaName schema name
* @param toBeDeletedTableName to be deleted table name
@@ -178,7 +178,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Alter schema.
- *
+ *
* @param databaseName database name
* @param schemaName schema name
* @param toBeChangedTable to be changed table
@@ -227,7 +227,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Alter rule configuration.
- *
+ *
* @param databaseName database name
* @param ruleConfigs rule configurations
*/
@@ -247,7 +247,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Alter schema meta data.
- *
+ *
* @param databaseName database name
* @param reloadDatabase reload database
* @param currentDatabase current database
@@ -261,7 +261,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Alter data source configuration.
- *
+ *
* @param databaseName database name
* @param dataSourcePropsMap altered data source properties map
*/
@@ -291,7 +291,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Renew ShardingSphere databases.
- *
+ *
* @param database database
* @param resource resource
* @return ShardingSphere databases
@@ -307,7 +307,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Alter data source and rule configuration.
- *
+ *
* @param databaseName database name
* @param dataSourcePropsMap data source props map
* @param ruleConfigs rule configurations
@@ -337,7 +337,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Create meta data contexts.
- *
+ *
* @param databaseName database name
* @param switchingResource switching resource
* @param ruleConfigs rule configs
@@ -364,7 +364,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Create changed databases.
- *
+ *
* @param databaseName database name
* @param switchingResource switching resource
* @param ruleConfigs rule configs
@@ -402,7 +402,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Create new ShardingSphere database.
- *
+ *
* @param originalDatabase original database
* @return ShardingSphere databases
*/
@@ -414,7 +414,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Alter global rule configuration.
- *
+ *
* @param ruleConfigs global rule configuration
*/
@SuppressWarnings("rawtypes")
@@ -433,7 +433,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Alter properties.
- *
+ *
* @param props properties to be altered
*/
public synchronized void alterProperties(final Properties props) {
@@ -444,7 +444,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Reload database meta data from governance center.
- *
+ *
* @param databaseName to be reloaded database name
*/
public synchronized void reloadDatabaseMetaData(final String databaseName) {
@@ -466,7 +466,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Delete schema names.
- *
+ *
* @param databaseName database name
* @param reloadDatabase reload database
* @param currentDatabase current database
@@ -478,7 +478,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Reload schema.
- *
+ *
* @param databaseName database name
* @param schemaName to be reloaded schema name
* @param dataSourceName data source name
@@ -511,7 +511,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Reload table.
- *
+ *
* @param databaseName database name
* @param schemaName schema name
* @param tableName to be reloaded table name
@@ -527,7 +527,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Reload table from single data source.
- *
+ *
* @param databaseName database name
* @param schemaName schema name
* @param dataSourceName data source name
@@ -570,6 +570,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Drop ShardingSphere data database.
+ *
* @param databaseName database name
*/
public synchronized void dropShardingSphereDatabaseData(final String databaseName) {
@@ -581,7 +582,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Add ShardingSphere schema data.
- *
+ *
* @param databaseName database name
* @param schemaName schema name
*/
@@ -594,7 +595,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Drop ShardingSphere schema data.
- *
+ *
* @param databaseName database name
* @param schemaName schema name
*/
@@ -608,7 +609,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Add ShardingSphere table data.
- *
+ *
* @param databaseName database name
* @param schemaName schema name
* @param tableName table name
@@ -625,7 +626,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Drop ShardingSphere table data.
- *
+ *
* @param databaseName database name
* @param schemaName schema name
* @param tableName table name
@@ -639,7 +640,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Alter ShardingSphere row data.
- *
+ *
* @param databaseName database name
* @param schemaName schema name
* @param tableName table name
@@ -661,7 +662,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Delete ShardingSphere row data.
- *
+ *
* @param databaseName database name
* @param schemaName schema name
* @param tableName table name
@@ -677,7 +678,7 @@ public final class ContextManager implements AutoCloseable {
/**
* Update cluster state.
- *
+ *
* @param status status
*/
public void updateClusterState(final String status) {
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/UnlockClusterUpdater.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/UnlockClusterUpdater.java
new file mode 100644
index 00000000000..be35585ffe8
--- /dev/null
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/UnlockClusterUpdater.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.proxy.backend.handler.distsql.ral.updatable;
+
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.distsql.handler.ral.update.RALUpdater;
+import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.UnlockClusterStatement;
+import org.apache.shardingsphere.infra.lock.LockContext;
+import org.apache.shardingsphere.infra.state.cluster.ClusterState;
+import org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
+import org.apache.shardingsphere.infra.util.exception.external.sql.type.generic.UnsupportedSQLOperationException;
+import org.apache.shardingsphere.mode.lock.GlobalLockDefinition;
+import org.apache.shardingsphere.mode.manager.ContextManager;
+import org.apache.shardingsphere.mode.manager.cluster.coordinator.registry.status.cluster.event.ClusterStatusChangedEvent;
+import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
+
+/**
+ * Unlock cluster updater.
+ */
+@RequiredArgsConstructor
+public final class UnlockClusterUpdater implements RALUpdater<UnlockClusterStatement> {
+
+ @Override
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ public void executeUpdate(final String databaseName, final UnlockClusterStatement sqlStatement) {
+ checkMode();
+ checkState();
+ ContextManager contextManager = ProxyContext.getInstance().getContextManager();
+ LockContext lockContext = contextManager.getInstanceContext().getLockContext();
+ lockContext.unlock(new GlobalLockDefinition("cluster_lock"));
+ contextManager.getInstanceContext().getEventBusContext().post(new ClusterStatusChangedEvent(ClusterState.OK));
+ // TODO unlock snapshot info if locked
+ }
+
+ private void checkMode() {
+ ShardingSpherePreconditions.checkState(ProxyContext.getInstance().getContextManager().getInstanceContext().isCluster(),
+ () -> new UnsupportedSQLOperationException("Only allowed in cluster mode"));
+ }
+
+ private void checkState() {
+ ClusterState currentState = ProxyContext.getInstance().getContextManager().getClusterStateContext().getCurrentState();
+ ShardingSpherePreconditions.checkState(ClusterState.OK != currentState, () -> new IllegalStateException("Cluster is not locked"));
+ }
+
+ @Override
+ public String getType() {
+ return UnlockClusterStatement.class.getName();
+ }
+}
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/lock/impl/ClusterWriteLockStrategy.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/lock/impl/ClusterWriteLockStrategy.java
index 94a2d1b5f8f..d6974b366da 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/lock/impl/ClusterWriteLockStrategy.java
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/lock/impl/ClusterWriteLockStrategy.java
@@ -37,7 +37,7 @@ public class ClusterWriteLockStrategy implements ClusterLockStrategy {
LockContext lockContext = contextManager.getInstanceContext().getLockContext();
if (lockContext.tryLock(new GlobalLockDefinition("cluster_lock"), -1)) {
contextManager.getInstanceContext().getEventBusContext().post(new ClusterStatusChangedEvent(ClusterState.READ_ONLY));
- // TODO lock csn
+ // TODO lock snapshot info
}
}
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/ReadOnlyProxyState.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/ReadOnlyProxyState.java
index d0e7d6f0bb4..285e21a4039 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/ReadOnlyProxyState.java
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/ReadOnlyProxyState.java
@@ -18,6 +18,7 @@
package org.apache.shardingsphere.proxy.backend.state.impl;
import org.apache.shardingsphere.distsql.parser.statement.ral.UpdatableRALStatement;
+import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.UnlockClusterStatement;
import org.apache.shardingsphere.distsql.parser.statement.rdl.RDLStatement;
import org.apache.shardingsphere.proxy.backend.exception.ReadOnlyException;
import org.apache.shardingsphere.proxy.backend.state.spi.ProxyClusterState;
@@ -41,7 +42,7 @@ public final class ReadOnlyProxyState implements ProxyClusterState {
private boolean isUnsupportedStatement(final SQLStatement sqlStatement) {
return sqlStatement instanceof InsertStatement || sqlStatement instanceof UpdateStatement || sqlStatement instanceof DeleteStatement || sqlStatement instanceof DDLStatement
- || sqlStatement instanceof UpdatableRALStatement || sqlStatement instanceof RDLStatement;
+ || sqlStatement instanceof UpdatableRALStatement && !(sqlStatement instanceof UnlockClusterStatement) || sqlStatement instanceof RDLStatement;
}
@Override
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/UnavailableProxyState.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/UnavailableProxyState.java
index 9ec5f46ddd2..fdc55fdbcb6 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/UnavailableProxyState.java
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/UnavailableProxyState.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.proxy.backend.state.impl;
import org.apache.shardingsphere.distsql.parser.statement.ral.QueryableRALStatement;
import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.ImportMetaDataStatement;
+import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.UnlockClusterStatement;
import org.apache.shardingsphere.distsql.parser.statement.rql.RQLStatement;
import org.apache.shardingsphere.proxy.backend.exception.UnavailableException;
import org.apache.shardingsphere.proxy.backend.state.spi.ProxyClusterState;
@@ -42,7 +43,7 @@ public final class UnavailableProxyState implements ProxyClusterState {
private boolean isSupportedStatement(final SQLStatement sqlStatement) {
return sqlStatement instanceof ImportMetaDataStatement || sqlStatement instanceof ShowStatement || sqlStatement instanceof QueryableRALStatement || sqlStatement instanceof RQLStatement
- || sqlStatement instanceof MySQLShowDatabasesStatement || sqlStatement instanceof MySQLUseStatement;
+ || sqlStatement instanceof UnlockClusterStatement || sqlStatement instanceof MySQLShowDatabasesStatement || sqlStatement instanceof MySQLUseStatement;
}
@Override
diff --git a/proxy/backend/core/src/main/resources/META-INF/services/org.apache.shardingsphere.distsql.handler.ral.update.RALUpdater b/proxy/backend/core/src/main/resources/META-INF/services/org.apache.shardingsphere.distsql.handler.ral.update.RALUpdater
index 44eecacfe90..a0fccd573c7 100644
--- a/proxy/backend/core/src/main/resources/META-INF/services/org.apache.shardingsphere.distsql.handler.ral.update.RALUpdater
+++ b/proxy/backend/core/src/main/resources/META-INF/services/org.apache.shardingsphere.distsql.handler.ral.update.RALUpdater
@@ -25,4 +25,5 @@ org.apache.shardingsphere.proxy.backend.handler.distsql.ral.updatable.AlterReadw
org.apache.shardingsphere.proxy.backend.handler.distsql.ral.updatable.SetDistVariableUpdater
org.apache.shardingsphere.proxy.backend.handler.distsql.ral.updatable.RefreshDatabaseMetaDataUpdater
org.apache.shardingsphere.proxy.backend.handler.distsql.ral.updatable.LockClusterUpdater
+org.apache.shardingsphere.proxy.backend.handler.distsql.ral.updatable.UnlockClusterUpdater
org.apache.shardingsphere.proxy.backend.handler.distsql.ral.updatable.RefreshTableMetaDataUpdater
diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/context/ProxyContextTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/context/ProxyContextTest.java
index 9778c7d0998..6b743a997ff 100644
--- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/context/ProxyContextTest.java
+++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/context/ProxyContextTest.java
@@ -24,6 +24,7 @@ import org.apache.shardingsphere.infra.instance.InstanceContext;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRuleMetaData;
+import org.apache.shardingsphere.infra.state.cluster.ClusterState;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
import org.apache.shardingsphere.mode.metadata.persist.MetaDataPersistService;
@@ -67,6 +68,8 @@ public final class ProxyContextTest {
public void assertInit() {
MetaDataContexts metaDataContexts = new MetaDataContexts(mock(MetaDataPersistService.class), new ShardingSphereMetaData());
ProxyContext.init(new ContextManager(metaDataContexts, mock(InstanceContext.class, RETURNS_DEEP_STUBS)));
+ assertThat(ProxyContext.getInstance().getContextManager().getClusterStateContext(), is(ProxyContext.getInstance().getContextManager().getClusterStateContext()));
+ assertThat(ProxyContext.getInstance().getContextManager().getClusterStateContext().getCurrentState(), is(ClusterState.OK));
assertThat(ProxyContext.getInstance().getContextManager().getMetaDataContexts(), is(ProxyContext.getInstance().getContextManager().getMetaDataContexts()));
assertTrue(ProxyContext.getInstance().getInstanceStateContext().isPresent());
assertThat(ProxyContext.getInstance().getInstanceStateContext(), is(ProxyContext.getInstance().getInstanceStateContext()));
diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/UnlockClusterUpdaterTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/UnlockClusterUpdaterTest.java
new file mode 100644
index 00000000000..10eb288b1ea
--- /dev/null
+++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/UnlockClusterUpdaterTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.proxy.backend.handler.distsql.ral.updatable;
+
+import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.UnlockClusterStatement;
+import org.apache.shardingsphere.infra.state.cluster.ClusterState;
+import org.apache.shardingsphere.infra.util.exception.external.sql.type.generic.UnsupportedSQLOperationException;
+import org.apache.shardingsphere.mode.manager.ContextManager;
+import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
+import org.apache.shardingsphere.test.mock.AutoMockExtension;
+import org.apache.shardingsphere.test.mock.StaticMockSettings;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings(ProxyContext.class)
+public final class UnlockClusterUpdaterTest {
+
+ @Test
+ public void assertExecuteWithNotClusterMode() {
+ ContextManager contextManager = mock(ContextManager.class, RETURNS_DEEP_STUBS);
+ when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager);
+ UnlockClusterUpdater updater = new UnlockClusterUpdater();
+ assertThrows(UnsupportedSQLOperationException.class, () -> updater.executeUpdate("foo", new UnlockClusterStatement()));
+ }
+
+ @Test
+ public void assertExecuteWithNotLockedCluster() {
+ ContextManager contextManager = mock(ContextManager.class, RETURNS_DEEP_STUBS);
+ when(contextManager.getInstanceContext().isCluster()).thenReturn(true);
+ when(contextManager.getClusterStateContext().getCurrentState()).thenReturn(ClusterState.OK);
+ when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager);
+ UnlockClusterUpdater updater = new UnlockClusterUpdater();
+ assertThrows(IllegalStateException.class, () -> updater.executeUpdate("foo", new UnlockClusterStatement()));
+ }
+}