use of io.mycat.config.model.TableConfig in project Mycat-Server by MyCATApache.
the class ConfigComparer method loadMigratorTables.
/*
* 加载迁移表信息,tables大小为0表示迁移schema下所有表
*/
private void loadMigratorTables(String schemaName, String[] tables) {
if (!DataMigratorUtil.isKeyExistIgnoreCase(oldSchemas, schemaName)) {
throw new ConfigException("oldSchema:" + schemaName + " is not exists!");
}
if (!DataMigratorUtil.isKeyExistIgnoreCase(newSchemas, schemaName)) {
throw new ConfigException("newSchema:" + schemaName + " is not exists!");
}
Map<String, TableConfig> oldTables = DataMigratorUtil.getValueIgnoreCase(oldSchemas, schemaName).getTables();
Map<String, TableConfig> newTables = DataMigratorUtil.getValueIgnoreCase(newSchemas, schemaName).getTables();
if (tables.length > 0) {
// 指定schema下的表进行迁移
for (int i = 0; i < tables.length; i++) {
TableConfig oldTable = DataMigratorUtil.getValueIgnoreCase(oldTables, tables[i]);
TableConfig newTable = DataMigratorUtil.getValueIgnoreCase(newTables, tables[i]);
loadMigratorTable(oldTable, newTable, schemaName, tables[i]);
}
} else {
// 迁移schema下所有的表
// 校验新旧schema中的table配置是否一致
Set<String> oldSet = oldTables.keySet();
Set<String> newSet = newTables.keySet();
if (!oldSet.equals(newSet)) {
throw new ConfigException("new & old table config is not equal!");
}
for (String tableName : oldSet) {
TableConfig oldTable = oldTables.get(tableName);
TableConfig newTable = newTables.get(tableName);
loadMigratorTable(oldTable, newTable, schemaName, tableName);
}
}
}
use of io.mycat.config.model.TableConfig in project Mycat-Server by MyCATApache.
the class MycatServer method performXARecoveryLog.
// XA recovery log check
private void performXARecoveryLog() {
// fetch the recovery log
CoordinatorLogEntry[] coordinatorLogEntries = getCoordinatorLogEntries();
for (int i = 0; i < coordinatorLogEntries.length; i++) {
CoordinatorLogEntry coordinatorLogEntry = coordinatorLogEntries[i];
boolean needRollback = false;
for (int j = 0; j < coordinatorLogEntry.participants.length; j++) {
ParticipantLogEntry participantLogEntry = coordinatorLogEntry.participants[j];
if (participantLogEntry.txState == TxState.TX_PREPARED_STATE) {
needRollback = true;
break;
}
}
if (needRollback) {
for (int j = 0; j < coordinatorLogEntry.participants.length; j++) {
ParticipantLogEntry participantLogEntry = coordinatorLogEntry.participants[j];
// XA rollback
String xacmd = "XA ROLLBACK " + coordinatorLogEntry.id + ';';
OneRawSQLQueryResultHandler resultHandler = new OneRawSQLQueryResultHandler(new String[0], new XARollbackCallback());
outloop: for (SchemaConfig schema : MycatServer.getInstance().getConfig().getSchemas().values()) {
for (TableConfig table : schema.getTables().values()) {
for (String dataNode : table.getDataNodes()) {
PhysicalDBNode dn = MycatServer.getInstance().getConfig().getDataNodes().get(dataNode);
if (dn.getDbPool().getSource().getConfig().getIp().equals(participantLogEntry.uri) && dn.getDatabase().equals(participantLogEntry.resourceName)) {
// XA STATE ROLLBACK
participantLogEntry.txState = TxState.TX_ROLLBACKED_STATE;
SQLJob sqlJob = new SQLJob(xacmd, dn.getDatabase(), resultHandler, dn.getDbPool().getSource());
sqlJob.run();
LOGGER.debug(String.format("[XA ROLLBACK] [%s] Host:[%s] schema:[%s]", xacmd, dn.getName(), dn.getDatabase()));
break outloop;
}
}
}
}
}
}
}
// init into in memory cached
for (int i = 0; i < coordinatorLogEntries.length; i++) {
MultiNodeCoordinator.inMemoryRepository.put(coordinatorLogEntries[i].id, coordinatorLogEntries[i]);
}
// discard the recovery log
MultiNodeCoordinator.fileRepository.writeCheckpoint(MultiNodeCoordinator.inMemoryRepository.getAllCoordinatorLogEntries());
}
use of io.mycat.config.model.TableConfig in project Mycat-Server by MyCATApache.
the class RouterUtil method changeCreateTable.
private static String changeCreateTable(SchemaConfig schema, String tableName, String sql) {
if (schema.getTables().containsKey(tableName)) {
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement insertStatement = parser.parseStatement();
if (insertStatement instanceof MySqlCreateTableStatement) {
TableConfig tableConfig = schema.getTables().get(tableName);
AbstractPartitionAlgorithm algorithm = tableConfig.getRule().getRuleAlgorithm();
if (algorithm instanceof SlotFunction) {
SQLColumnDefinition column = new SQLColumnDefinition();
column.setDataType(new SQLCharacterDataType("int"));
column.setName(new SQLIdentifierExpr("_slot"));
column.setComment(new SQLCharExpr("自动迁移算法slot,禁止修改"));
((SQLCreateTableStatement) insertStatement).getTableElementList().add(column);
return insertStatement.toString();
}
}
}
return sql;
}
use of io.mycat.config.model.TableConfig in project Mycat-Server by MyCATApache.
the class RouterUtil method tryRouteForOneTable.
/**
* 单表路由
*/
public static RouteResultset tryRouteForOneTable(SchemaConfig schema, DruidShardingParseInfo ctx, RouteCalculateUnit routeUnit, String tableName, RouteResultset rrs, boolean isSelect, LayerCachePool cachePool) throws SQLNonTransientException {
if (isNoSharding(schema, tableName)) {
return routeToSingleNode(rrs, schema.getDataNode(), ctx.getSql());
}
TableConfig tc = schema.getTables().get(tableName);
if (tc == null) {
String msg = "can't find table define in schema " + tableName + " schema:" + schema.getName();
LOGGER.warn(msg);
throw new SQLNonTransientException(msg);
}
if (tc.isDistTable()) {
return routeToDistTableNode(tableName, schema, rrs, ctx.getSql(), routeUnit.getTablesAndConditions(), cachePool, isSelect);
}
if (tc.isGlobalTable()) {
// 全局表
if (isSelect) {
// global select ,not cache route result
rrs.setCacheAble(false);
return routeToSingleNode(rrs, getAliveRandomDataNode(tc), /*getRandomDataNode(tc)*/
ctx.getSql());
} else {
// insert into 全局表的记录
return routeToMultiNode(false, rrs, tc.getDataNodes(), ctx.getSql(), true);
}
} else {
// 单表或者分库表
if (!checkRuleRequired(schema, ctx, routeUnit, tc)) {
throw new IllegalArgumentException("route rule for table " + tc.getName() + " is required: " + ctx.getSql());
}
if (tc.getPartitionColumn() == null && !tc.isSecondLevel()) {
// return RouterUtil.routeToSingleNode(rrs, tc.getDataNodes().get(0),ctx.getSql());
return routeToMultiNode(rrs.isCacheAble(), rrs, tc.getDataNodes(), ctx.getSql());
} else {
// 每个表对应的路由映射
Map<String, Set<String>> tablesRouteMap = new HashMap<String, Set<String>>();
if (routeUnit.getTablesAndConditions() != null && routeUnit.getTablesAndConditions().size() > 0) {
RouterUtil.findRouteWithcConditionsForTables(schema, rrs, routeUnit.getTablesAndConditions(), tablesRouteMap, ctx.getSql(), cachePool, isSelect);
if (rrs.isFinishedRoute()) {
return rrs;
}
}
if (tablesRouteMap.get(tableName) == null) {
return routeToMultiNode(rrs.isCacheAble(), rrs, tc.getDataNodes(), ctx.getSql());
} else {
return routeToMultiNode(rrs.isCacheAble(), rrs, tablesRouteMap.get(tableName), ctx.getSql());
}
}
}
}
use of io.mycat.config.model.TableConfig in project Mycat-Server by MyCATApache.
the class RouterUtil method tryRouteForTables.
/**
* 多表路由
*/
public static RouteResultset tryRouteForTables(SchemaConfig schema, DruidShardingParseInfo ctx, RouteCalculateUnit routeUnit, RouteResultset rrs, boolean isSelect, LayerCachePool cachePool) throws SQLNonTransientException {
List<String> tables = ctx.getTables();
if (schema.isNoSharding() || (tables.size() >= 1 && isNoSharding(schema, tables.get(0)))) {
return routeToSingleNode(rrs, schema.getDataNode(), ctx.getSql());
}
// 只有一个表的
if (tables.size() == 1) {
return RouterUtil.tryRouteForOneTable(schema, ctx, routeUnit, tables.get(0), rrs, isSelect, cachePool);
}
Set<String> retNodesSet = new HashSet<String>();
// 每个表对应的路由映射
Map<String, Set<String>> tablesRouteMap = new HashMap<String, Set<String>>();
// 分库解析信息不为空
Map<String, Map<String, Set<ColumnRoutePair>>> tablesAndConditions = routeUnit.getTablesAndConditions();
if (tablesAndConditions != null && tablesAndConditions.size() > 0) {
// 为分库表找路由
RouterUtil.findRouteWithcConditionsForTables(schema, rrs, tablesAndConditions, tablesRouteMap, ctx.getSql(), cachePool, isSelect);
if (rrs.isFinishedRoute()) {
return rrs;
}
}
// 为全局表和单库表找路由
for (String tableName : tables) {
TableConfig tableConfig = schema.getTables().get(tableName.toUpperCase());
if (tableConfig == null) {
// add 如果表读取不到则先将表名从别名中读取转化后再读取
String alias = ctx.getTableAliasMap().get(tableName);
if (!StringUtil.isEmpty(alias)) {
tableConfig = schema.getTables().get(alias.toUpperCase());
}
if (tableConfig == null) {
String msg = "can't find table define in schema " + tableName + " schema:" + schema.getName();
LOGGER.warn(msg);
throw new SQLNonTransientException(msg);
}
}
if (tableConfig.isGlobalTable()) {
// 全局表
if (tablesRouteMap.get(tableName) == null) {
tablesRouteMap.put(tableName, new HashSet<String>());
}
tablesRouteMap.get(tableName).addAll(tableConfig.getDataNodes());
} else if (tablesRouteMap.get(tableName) == null) {
// 余下的表都是单库表
tablesRouteMap.put(tableName, new HashSet<String>());
tablesRouteMap.get(tableName).addAll(tableConfig.getDataNodes());
}
}
boolean isFirstAdd = true;
for (Map.Entry<String, Set<String>> entry : tablesRouteMap.entrySet()) {
if (entry.getValue() == null || entry.getValue().size() == 0) {
throw new SQLNonTransientException("parent key can't find any valid datanode ");
} else {
if (isFirstAdd) {
retNodesSet.addAll(entry.getValue());
isFirstAdd = false;
} else {
retNodesSet.retainAll(entry.getValue());
if (retNodesSet.size() == 0) {
// 两个表的路由无交集
String errMsg = "invalid route in sql, multi tables found but datanode has no intersection " + " sql:" + ctx.getSql();
LOGGER.warn(errMsg);
throw new SQLNonTransientException(errMsg);
}
}
}
}
if (retNodesSet != null && retNodesSet.size() > 0) {
String tableName = tables.get(0);
TableConfig tableConfig = schema.getTables().get(tableName.toUpperCase());
if (tableConfig.isDistTable()) {
routeToDistTableNode(tableName, schema, rrs, ctx.getSql(), tablesAndConditions, cachePool, isSelect);
return rrs;
}
if (retNodesSet.size() > 1 && isAllGlobalTable(ctx, schema)) {
// mulit routes ,not cache route result
if (isSelect) {
rrs.setCacheAble(false);
routeToSingleNode(rrs, retNodesSet.iterator().next(), ctx.getSql());
} else {
// delete 删除全局表的记录
routeToMultiNode(isSelect, rrs, retNodesSet, ctx.getSql(), true);
}
} else {
routeToMultiNode(isSelect, rrs, retNodesSet, ctx.getSql());
}
}
return rrs;
}
Aggregations