Merge branch 'master' into inner-2218_2

This commit is contained in:
wenyh
2023-07-18 15:42:25 +08:00
committed by GitHub
10 changed files with 162 additions and 43 deletions

View File

@@ -25,7 +25,7 @@
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
<grpc.version>1.5.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
<grpc.version>1.53.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
<log4j2.version>2.18.0</log4j2.version>
</properties>
<repositories>

View File

@@ -181,7 +181,7 @@ public final class UcoreSender extends AbstractConsulSender {
ManagedChannel channel = null;
try {
channel = ManagedChannelBuilder.forAddress(ip,
ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
setStubIfPossible(UcoreGrpc.newBlockingStub(channel).withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS));
output = stub.withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS).getKv(input);
} catch (Exception e2) {
@@ -221,7 +221,7 @@ public final class UcoreSender extends AbstractConsulSender {
ManagedChannel channel = null;
try {
channel = ManagedChannelBuilder.forAddress(ip,
ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
setStubIfPossible(UcoreGrpc.newBlockingStub(channel).withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS));
output = stub.withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS).getKvTree(input);
} catch (Exception e2) {
@@ -257,7 +257,7 @@ public final class UcoreSender extends AbstractConsulSender {
ManagedChannel channel = null;
try {
channel = ManagedChannelBuilder.forAddress(ip,
ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
setStubIfPossible(UcoreGrpc.newBlockingStub(channel).withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS));
stub.withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS).deleteKvTree(input);
flag = true;
@@ -288,7 +288,7 @@ public final class UcoreSender extends AbstractConsulSender {
ManagedChannel channel = null;
try {
channel = ManagedChannelBuilder.forAddress(ip,
ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
setStubIfPossible(UcoreGrpc.newBlockingStub(channel).withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS));
stub.withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS).deleteKv(input);
return;
@@ -321,7 +321,7 @@ public final class UcoreSender extends AbstractConsulSender {
ManagedChannel channel = null;
try {
channel = ManagedChannelBuilder.forAddress(ip,
ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
setStubIfPossible(UcoreGrpc.newBlockingStub(channel).withDeadlineAfter(GRPC_SUBTIMEOUT, TimeUnit.SECONDS));
UcoreInterface.SubscribeKvPrefixOutput output = stub.withDeadlineAfter(GRPC_SUBTIMEOUT, TimeUnit.SECONDS).subscribeKvPrefix(input);
return groupSubscribeResult(output);
@@ -346,7 +346,7 @@ public final class UcoreSender extends AbstractConsulSender {
for (String ip : getAvailableIpList()) {
ManagedChannel channel = null;
try {
channel = ManagedChannelBuilder.forAddress(ip, ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
channel = ManagedChannelBuilder.forAddress(ip, ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
setStubIfPossible(UcoreGrpc.newBlockingStub(channel).withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS));
stub.withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS).alert(input);
return;
@@ -370,7 +370,7 @@ public final class UcoreSender extends AbstractConsulSender {
for (String ip : getAvailableIpList()) {
ManagedChannel channel = null;
try {
channel = ManagedChannelBuilder.forAddress(ip, ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
channel = ManagedChannelBuilder.forAddress(ip, ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
setStubIfPossible(UcoreGrpc.newBlockingStub(channel).withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS));
stub.withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS).alertResolve(input);
return true;
@@ -421,7 +421,7 @@ public final class UcoreSender extends AbstractConsulSender {
ManagedChannel channel = null;
try {
channel = ManagedChannelBuilder.forAddress(ip,
ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
setStubIfPossible(UcoreGrpc.newBlockingStub(channel).withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS));
stub.withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS).renewSession(input);
return true;
@@ -463,7 +463,7 @@ public final class UcoreSender extends AbstractConsulSender {
ManagedChannel channel = null;
try {
channel = ManagedChannelBuilder.forAddress(ip,
ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
setStubIfPossible(UcoreGrpc.newBlockingStub(channel).withDeadlineAfter(GRPC_SUBTIMEOUT, TimeUnit.SECONDS));
return stub.withDeadlineAfter(GRPC_SUBTIMEOUT, TimeUnit.SECONDS).subscribeNodes(subscribeNodesInput);
} catch (Exception e2) {
@@ -595,7 +595,7 @@ public final class UcoreSender extends AbstractConsulSender {
Channel channel = null;
try {
channel = ManagedChannelBuilder.forAddress(ip,
ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
channel = ClientInterceptors.intercept(channel, new MetaDataClientInterceptor());
setStubIfPossible(UcoreGrpc.newBlockingStub(channel).withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS));
isSuccess = true;

View File

@@ -47,7 +47,7 @@ public class UshardSender extends AbstractConsulSender {
@Override
public void initConInfo() {
Channel channel = ManagedChannelBuilder.forAddress("127.0.0.1",
ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
setStubIfPossible(DbleClusterGrpc.newBlockingStub(channel).withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS));
}
@@ -56,7 +56,7 @@ public class UshardSender extends AbstractConsulSender {
serverId = SystemConfig.getInstance().getServerId();
sourceComponentId = SystemConfig.getInstance().getInstanceName();
Channel channel = ManagedChannelBuilder.forAddress("127.0.0.1",
ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
setStubIfPossible(DbleClusterGrpc.newBlockingStub(channel).withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS));
startUpdateNodes();
ClusterToXml.loadKVtoFile(this);
@@ -309,7 +309,7 @@ public class UshardSender extends AbstractConsulSender {
}
LOGGER.warn("error in ucore nodes watch,try for another time", e);
Channel channel = ManagedChannelBuilder.forAddress("127.0.0.1",
ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
UshardSender.this.setStubIfPossible(DbleClusterGrpc.newBlockingStub(channel).withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS));
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(2000));
}
@@ -346,7 +346,7 @@ public class UshardSender extends AbstractConsulSender {
ManagedChannel channel = null;
try {
channel = ManagedChannelBuilder.forAddress("127.0.0.1",
ClusterConfig.getInstance().getClusterPort()).usePlaintext(true).build();
ClusterConfig.getInstance().getClusterPort()).usePlaintext().build();
stub = DbleClusterGrpc.newBlockingStub(channel).withDeadlineAfter(ClusterConfig.getInstance().getGrpcTimeout(), TimeUnit.SECONDS);
//check connection is ready
ClusterHelper.isExist(ClusterPathUtil.getOnlinePath(SystemConfig.getInstance().getInstanceName()));

View File

@@ -33,6 +33,7 @@ public final class ParameterMapping {
private static List<String> errorParameters = new ArrayList<>();
private static final Map<String, String> COMPATIBLE_MAP = new HashMap<>();
private static Set<String> errorCompatibleSet = new HashSet<>();
private static final Set<String> ON_OFF_SET = new HashSet<>();
static {
@@ -42,6 +43,40 @@ public final class ParameterMapping {
COMPATIBLE_MAP.put("frontWorker", "processorExecutor");
COMPATIBLE_MAP.put("backendWorker", "backendProcessorExecutor");
COMPATIBLE_MAP.put("writeToBackendWorker", "writeToBackendExecutor");
ON_OFF_SET.add("useCompression");
ON_OFF_SET.add("usingAIO");
ON_OFF_SET.add("useThreadUsageStat");
ON_OFF_SET.add("usePerformanceMode");
ON_OFF_SET.add("useCostTimeStat");
ON_OFF_SET.add("autocommit");
ON_OFF_SET.add("checkTableConsistency");
ON_OFF_SET.add("recordTxn");
ON_OFF_SET.add("useSqlStat");
ON_OFF_SET.add("frontSocketNoDelay");
ON_OFF_SET.add("backSocketNoDelay");
ON_OFF_SET.add("enableGeneralLog");
ON_OFF_SET.add("enableBatchLoadData");
ON_OFF_SET.add("enableRoutePenetration");
ON_OFF_SET.add("enableAlert");
ON_OFF_SET.add("enableStatistic");
ON_OFF_SET.add("enableSessionActiveRatioStat");
ON_OFF_SET.add("enableConnectionAssociateThread");
ON_OFF_SET.add("enableAsyncRelease");
ON_OFF_SET.add("enableMemoryBufferMonitor");
ON_OFF_SET.add("enableMemoryBufferMonitorRecordPool");
ON_OFF_SET.add("enableSlowLog");
ON_OFF_SET.add("useCostTimeStat");
ON_OFF_SET.add("capClientFoundRows");
ON_OFF_SET.add("useJoinStrategy");
ON_OFF_SET.add("enableCursor");
ON_OFF_SET.add("enableFlowControl");
ON_OFF_SET.add("useOuterHa");
ON_OFF_SET.add("useNewJoinOptimizer");
ON_OFF_SET.add("inSubQueryTransformToJoin");
ON_OFF_SET.add("closeHeartBeatRecord");
}
public static void mapping(Object target, Properties src, ProblemReporter problemReporter) throws IllegalAccessException,
@@ -69,6 +104,7 @@ public final class ParameterMapping {
}
if (isPrimitiveType(cls)) {
try {
valStr = onOffProcess(name, cls, valStr);
value = convert(cls, valStr);
} catch (NumberFormatException nfe) {
String propertyName = pd.getName();
@@ -124,6 +160,7 @@ public final class ParameterMapping {
}
if (isPrimitiveType(cls)) {
try {
valStr = onOffProcess(propertyName, cls, valStr);
value = convert(cls, valStr);
} catch (NumberFormatException nfe) {
String msg = getTypeErrorMessage(propertyName, valStr, cls);
@@ -260,6 +297,38 @@ public final class ParameterMapping {
return valStr;
}
private static String onOffProcess(String name, Class<?> cls, String val) {
String value = val;
if (!ON_OFF_SET.contains(name)) {
return value;
}
if (!cls.equals(Integer.TYPE) && !cls.equals(Boolean.TYPE)) {
throw new NumberFormatException("parameter " + name + " is not boolean value or Integer value");
}
int valInteger;
boolean valBoolean;
if (BooleanUtil.isBoolean(val)) {
valBoolean = BooleanUtil.parseBoolean(val);
valInteger = booleanToInt(valBoolean);
} else {
valInteger = Integer.parseInt(val);
checkOnOffInteger(valInteger);
valBoolean = intToBoolean(valInteger);
}
if (cls.equals(Integer.TYPE)) {
value = String.valueOf(valInteger);
} else {
value = String.valueOf(valBoolean);
}
return value;
}
private static void checkOnOffInteger(int valInteger) {
if (valInteger < 0 || valInteger > 1) {
throw new NumberFormatException("value " + valInteger + " is illegal");
}
}
public static String getErrorCompatibleMessage(String name) {
String message = "";
if (errorCompatibleSet.contains(name)) {
@@ -272,8 +341,20 @@ public final class ParameterMapping {
private static String getTypeErrorMessage(String name, String values, Class<?> cls) {
String message = getErrorCompatibleMessage(name);
StringBuilder sb = new StringBuilder(message);
sb.append("property [ ").append(name).append(" ] '").append(values).append("' data type should be ").append(cls.toString());
if (ON_OFF_SET.contains(name)) {
sb.append("check the property [ ").append(name).append(" ] '").append(values).append("' data type or value");
} else {
sb.append("property [ ").append(name).append(" ] '").append(values).append("' data type should be ").append(cls.toString());
}
return sb.toString();
}
private static boolean intToBoolean(int num) {
return num != 0;
}
private static int booleanToInt(boolean bool) {
return bool ? 1 : 0;
}
}

View File

@@ -112,8 +112,8 @@ public final class ManagerTableUtil {
String value = null == row.getValue(i) ? null : new String(row.getValue(i), charset);
affectPk.put(columnName, value);
if (null != values) {
boolean match = values.entrySet().stream().anyMatch(valueEntry -> !StringUtil.equals(affectPk.get(valueEntry.getKey()), valueEntry.getValue()));
if (!match) {
boolean isSkipRow = values.entrySet().stream().allMatch(valueEntry -> affectPk.containsKey(valueEntry.getKey()) && StringUtil.equals(affectPk.get(valueEntry.getKey()), valueEntry.getValue()));
if (isSkipRow) {
breakFlag = true;
break;
}

View File

@@ -289,30 +289,30 @@ public class DbleDbGroup extends ManagerWritableTable {
}
}
}
String delayThresholdStr = row.get(COLUMN_DELAY_THRESHOLD);
String heartbeatTimeoutStr = row.get(COLUMN_HEARTBEAT_TIMEOUT);
String heartbeatRetryStr = row.get(COLUMN_HEARTBEAT_RETRY);
if (!StringUtil.isBlank(delayThresholdStr) && IntegerUtil.parseInt(delayThresholdStr) < -1) {
throw new ConfigException("Column '" + COLUMN_DELAY_THRESHOLD + "' should be an integer greater than or equal to -1!");
}
if (!StringUtil.isBlank(heartbeatTimeoutStr) && IntegerUtil.parseInt(heartbeatTimeoutStr) < 0) {
throw new ConfigException("Column '" + COLUMN_HEARTBEAT_TIMEOUT + "' should be an integer greater than or equal to 0!");
}
if (!StringUtil.isBlank(heartbeatRetryStr) && IntegerUtil.parseInt(heartbeatRetryStr) < 0) {
throw new ConfigException("Column '" + COLUMN_HEARTBEAT_RETRY + "' should be an integer greater than or equal to 0!");
}
String heartbeatKeepAliveStr = row.get(COLUMN_KEEP_ALIVE);
if (!StringUtil.isBlank(heartbeatKeepAliveStr) && IntegerUtil.parseInt(heartbeatKeepAliveStr) < 0) {
throw new ConfigException("Column '" + COLUMN_KEEP_ALIVE + "' should be an integer greater than or equal to 0!");
}
String delayPeriodMillis = row.get(DELAY_PERIOD_MILLIS);
delayDetectionCheck(delayPeriodMillis);
checkInterValue(row);
}
}
private void delayDetectionCheck(String delayPeriodMillis) {
if (!StringUtil.isBlank(delayPeriodMillis) && IntegerUtil.parseInt(delayPeriodMillis) < -1) {
throw new ConfigException("Column '" + COLUMN_DELAY_THRESHOLD + "' should be an integer greater than -1!");
private void checkInterValue(LinkedHashMap<String, String> row) {
String delayThresholdStr = row.get(COLUMN_DELAY_THRESHOLD);
String heartbeatTimeoutStr = row.get(COLUMN_HEARTBEAT_TIMEOUT);
String heartbeatRetryStr = row.get(COLUMN_HEARTBEAT_RETRY);
if (row.containsKey(COLUMN_DELAY_THRESHOLD) && (StringUtil.isBlank(delayThresholdStr) || IntegerUtil.parseInt(delayThresholdStr) < -1)) {
throw new ConfigException("Column '" + COLUMN_DELAY_THRESHOLD + "' should be an integer greater than or equal to -1!");
}
if (row.containsKey(COLUMN_HEARTBEAT_TIMEOUT) && (StringUtil.isBlank(heartbeatTimeoutStr) || IntegerUtil.parseInt(heartbeatTimeoutStr) < 0)) {
throw new ConfigException("Column '" + COLUMN_HEARTBEAT_TIMEOUT + "' should be an integer greater than or equal to 0!");
}
if (row.containsKey(COLUMN_HEARTBEAT_RETRY) && (StringUtil.isBlank(heartbeatRetryStr) || IntegerUtil.parseInt(heartbeatRetryStr) < 0)) {
throw new ConfigException("Column '" + COLUMN_HEARTBEAT_RETRY + "' should be an integer greater than or equal to 0!");
}
String heartbeatKeepAliveStr = row.get(COLUMN_KEEP_ALIVE);
if (row.containsKey(COLUMN_KEEP_ALIVE) && (StringUtil.isBlank(heartbeatKeepAliveStr) || IntegerUtil.parseInt(heartbeatKeepAliveStr) < 0)) {
throw new ConfigException("Column '" + COLUMN_KEEP_ALIVE + "' should be an integer greater than or equal to 0!");
}
String delayPeriodMillis = row.get(DELAY_PERIOD_MILLIS);
if (row.containsKey(DELAY_PERIOD_MILLIS) && (StringUtil.isBlank(delayPeriodMillis) || IntegerUtil.parseInt(delayPeriodMillis) < -1)) {
throw new ConfigException("Column '" + DELAY_PERIOD_MILLIS + "' should be an integer greater than or equal to -1!");
}
}

View File

@@ -402,6 +402,8 @@ public class DbleDbInstance extends ManagerWritableTable {
DBInstance dbInstance = new DBInstance();
StringBuilder url = new StringBuilder();
List<Property> propertyList = Lists.newArrayList();
String key;
String entryValue;
for (Map.Entry<String, String> entry : map.entrySet()) {
switch (entry.getKey()) {
case COLUMN_NAME:
@@ -469,6 +471,13 @@ public class DbleDbInstance extends ManagerWritableTable {
case COLUMN_TEST_ON_BORROW:
case COLUMN_TEST_ON_RETURN:
case COLUMN_TEST_WHILE_IDLE:
key = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, entry.getKey());
entryValue = entry.getValue();
if (StringUtil.isBlank(entryValue) || (!StringUtil.equalsIgnoreCase(entryValue, Boolean.FALSE.toString()) && !StringUtil.equalsIgnoreCase(entryValue, Boolean.TRUE.toString()))) {
throw new ConfigException("Column '" + entry.getKey() + "' values only support 'false' or 'true'.");
}
propertyList.add(new Property(entryValue, key));
break;
case COLUMN_CONNECTION_TIMEOUT:
case COLUMN_CONNECTION_HEARTBEAT_TIMEOUT:
case COLUMN_TIME_BETWEEN_EVICTION_RUNS_MILLIS:
@@ -477,8 +486,12 @@ public class DbleDbInstance extends ManagerWritableTable {
case COLUMN_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS:
case COLUMN_FLOW_HIGH_LEVEL:
case COLUMN_FLOW_LOW_LEVEL:
String key = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, entry.getKey());
propertyList.add(new Property(entry.getValue(), key));
key = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, entry.getKey());
entryValue = entry.getValue();
if (StringUtil.isBlank(entryValue) || IntegerUtil.parseInt(entryValue) <= 0) {
throw new ConfigException("Column '" + entry.getKey() + "' should be an integer greater than 0!");
}
propertyList.add(new Property(entryValue, key));
break;
default:
break;

View File

@@ -6,16 +6,22 @@
package com.actiontech.dble.util;
public final class BooleanUtil {
private static final String TRUE = "true";
private static final String FALSE = "false";
private BooleanUtil() {
}
public static boolean parseBoolean(String val) {
if ("true".equalsIgnoreCase(val)) {
if (TRUE.equalsIgnoreCase(val)) {
return true;
} else if ("false".equalsIgnoreCase(val)) {
} else if (FALSE.equalsIgnoreCase(val)) {
return false;
} else {
throw new NumberFormatException("value " + val + " is not boolean value");
}
}
public static boolean isBoolean(String val) {
return TRUE.equalsIgnoreCase(val) || FALSE.equalsIgnoreCase(val);
}
}

View File

@@ -50,12 +50,20 @@
</schema>
<!-- sharding testdb2 route to database named dn5 in localhost2 -->
<schema name="testdb2" shardingNode="dn5"/>
<schema name="testdb3" apNode="apNode1">
<globalTable name="tb_global1" shardingNode="dn1,dn2" sqlMaxLimit="103"/>
<globalTable name="tb_global1" shardingNode="dn1,dn2,dn3,dn4" cron="0 0 0 * * ?" checkClass="CHECKSUM"/>
</schema>
<shardingNode name="dn1" dbGroup="dbGroup1" database="db_1"/>
<shardingNode name="dn2" dbGroup="dbGroup2" database="db_2"/>
<shardingNode name="dn3" dbGroup="dbGroup1" database="db_3"/>
<shardingNode name="dn4" dbGroup="dbGroup2" database="db_4"/>
<shardingNode name="dn5" dbGroup="dbGroup1" database="db_5"/>
<shardingNode name="dn6" dbGroup="dbGroup2" database="db_6"/>
<apNode name="apNode1" dbGroup="dbGroup3" database="ap_db1"/>
<!-- enum partition -->
<function name="func_enum" class="Enum">
<property name="mapFile">partition-enum.txt</property>

View File

@@ -30,6 +30,17 @@
<!--rwSplitUser not work for now-->
<!--<rwSplitUser name="rwsu1" password="123456" dbGroup="dbGroup1" blacklist="blacklist1" maxCon="20"/>-->
<analysisUser name="analysisUser" password="123456" dbGroup="dbGroup3" blacklist="blacklist1" maxCon="20"/>
<hybridTAUser name="hysu1" password="111111" schemas="testdb3" maxCon="20"/>
<hybridTAUser name="hysu2" password="111111" schemas="testdb3" maxCon="20" blacklist="blacklist1" tenant="tenant2">
<privileges check="true">
<schema name="testdb3" dml="0110">
<table name="tb_global1" dml="0000"/>
<table name="tb_global2" dml="1111"/>
</schema>
</privileges>
</hybridTAUser>
<blacklist name="blacklist1">
<property name="selelctAllow">true</property>
</blacklist>