use of io.mycat.config.model.rule.RuleConfig in project Mycat-Server by MyCATApache.
the class XMLSchemaLoader method loadTables.
private Map<String, TableConfig> loadTables(Element node) {
// Map<String, TableConfig> tables = new HashMap<String, TableConfig>();
// 支持表名中包含引号[`] BEN GONG
Map<String, TableConfig> tables = new TableConfigMap();
NodeList nodeList = node.getElementsByTagName("table");
for (int i = 0; i < nodeList.getLength(); i++) {
Element tableElement = (Element) nodeList.item(i);
String tableNameElement = tableElement.getAttribute("name").toUpperCase();
//TODO:路由, 增加对动态日期表的支持
String tableNameSuffixElement = tableElement.getAttribute("nameSuffix").toUpperCase();
if (!"".equals(tableNameSuffixElement)) {
if (tableNameElement.split(",").length > 1) {
throw new ConfigException("nameSuffix " + tableNameSuffixElement + ", require name parameter cannot multiple breaks!");
}
//前缀用来标明日期格式
tableNameElement = doTableNameSuffix(tableNameElement, tableNameSuffixElement);
}
//记录主键,用于之后路由分析,以及启用自增长主键
String[] tableNames = tableNameElement.split(",");
String primaryKey = tableElement.hasAttribute("primaryKey") ? tableElement.getAttribute("primaryKey").toUpperCase() : null;
//记录是否主键自增,默认不是,(启用全局sequence handler)
boolean autoIncrement = false;
if (tableElement.hasAttribute("autoIncrement")) {
autoIncrement = Boolean.parseBoolean(tableElement.getAttribute("autoIncrement"));
}
//记录是否需要加返回结果集限制,默认需要加
boolean needAddLimit = true;
if (tableElement.hasAttribute("needAddLimit")) {
needAddLimit = Boolean.parseBoolean(tableElement.getAttribute("needAddLimit"));
}
//记录type,是否为global
String tableTypeStr = tableElement.hasAttribute("type") ? tableElement.getAttribute("type") : null;
int tableType = TableConfig.TYPE_GLOBAL_DEFAULT;
if ("global".equalsIgnoreCase(tableTypeStr)) {
tableType = TableConfig.TYPE_GLOBAL_TABLE;
}
//记录dataNode,就是分布在哪些dataNode上
String dataNode = tableElement.getAttribute("dataNode");
TableRuleConfig tableRule = null;
if (tableElement.hasAttribute("rule")) {
String ruleName = tableElement.getAttribute("rule");
tableRule = tableRules.get(ruleName);
if (tableRule == null) {
throw new ConfigException("rule " + ruleName + " is not found!");
}
}
boolean ruleRequired = false;
//记录是否绑定有分片规则
if (tableElement.hasAttribute("ruleRequired")) {
ruleRequired = Boolean.parseBoolean(tableElement.getAttribute("ruleRequired"));
}
if (tableNames == null) {
throw new ConfigException("table name is not found!");
}
//distribute函数,重新编排dataNode
String distPrex = "distribute(";
boolean distTableDns = dataNode.startsWith(distPrex);
if (distTableDns) {
dataNode = dataNode.substring(distPrex.length(), dataNode.length() - 1);
}
//分表功能
String subTables = tableElement.getAttribute("subTables");
for (int j = 0; j < tableNames.length; j++) {
String tableName = tableNames[j];
TableRuleConfig tableRuleConfig = tableRule;
if (tableRuleConfig != null) {
//对于实现TableRuleAware的function进行特殊处理 根据每个表新建个实例
RuleConfig rule = tableRuleConfig.getRule();
if (rule.getRuleAlgorithm() instanceof TableRuleAware) {
tableRuleConfig = (TableRuleConfig) ObjectUtil.copyObject(tableRuleConfig);
tableRules.remove(tableRuleConfig.getName());
String newRuleName = tableRuleConfig.getName() + "_" + tableName;
tableRuleConfig.setName(newRuleName);
TableRuleAware tableRuleAware = (TableRuleAware) tableRuleConfig.getRule().getRuleAlgorithm();
tableRuleAware.setRuleName(newRuleName);
tableRuleAware.setTableName(tableName);
tableRuleConfig.getRule().getRuleAlgorithm().init();
tableRules.put(newRuleName, tableRuleConfig);
}
}
TableConfig table = new TableConfig(tableName, primaryKey, autoIncrement, needAddLimit, tableType, dataNode, getDbType(dataNode), (tableRuleConfig != null) ? tableRuleConfig.getRule() : null, ruleRequired, null, false, null, null, subTables);
checkDataNodeExists(table.getDataNodes());
// 检查分片表分片规则配置是否合法
if (table.getRule() != null) {
checkRuleSuitTable(table);
}
if (distTableDns) {
distributeDataNodes(table.getDataNodes());
}
//检查去重
if (tables.containsKey(table.getName())) {
throw new ConfigException("table " + tableName + " duplicated!");
}
//放入map
tables.put(table.getName(), table);
}
//只有tableName配置的是单个表(没有逗号)的时候才能有子表
if (tableNames.length == 1) {
TableConfig table = tables.get(tableNames[0]);
// process child tables
processChildTables(tables, table, dataNode, tableElement);
}
}
return tables;
}
use of io.mycat.config.model.rule.RuleConfig in project Mycat-Server by MyCATApache.
the class XMLRuleLoader method loadRule.
private RuleConfig loadRule(Element element) throws SQLSyntaxErrorException {
//读取columns
Element columnsEle = ConfigUtil.loadElement(element, "columns");
String column = columnsEle.getTextContent();
String[] columns = SplitUtil.split(column, ',', true);
if (columns.length > 1) {
throw new ConfigException("table rule coulmns has multi values:" + columnsEle.getTextContent());
}
//读取algorithm
Element algorithmEle = ConfigUtil.loadElement(element, "algorithm");
String algorithm = algorithmEle.getTextContent();
return new RuleConfig(column.toUpperCase(), algorithm);
}
use of io.mycat.config.model.rule.RuleConfig in project Mycat-Server by MyCATApache.
the class SwitchCommitListener method modifyRuleData.
private CuratorTransactionFinal modifyRuleData(CuratorTransactionFinal transactionFinal, List<MigrateTask> allTaskList, TableConfig tableConfig, List<String> allNewDataNodes) throws Exception {
InterProcessMutex ruleDataLock = null;
try {
String path = ZKUtils.getZKBasePath() + "lock/ruledata.lock";
ruleDataLock = new InterProcessMutex(ZKUtils.getConnection(), path);
ruleDataLock.acquire(30, TimeUnit.SECONDS);
RuleConfig ruleConfig = tableConfig.getRule();
String ruleName = ((TableRuleAware) ruleConfig.getRuleAlgorithm()).getRuleName() + ".properties";
String rulePath = ZKUtils.getZKBasePath() + "ruledata/" + ruleName;
CuratorFramework zk = ZKUtils.getConnection();
byte[] ruleData = zk.getData().forPath(rulePath);
Properties prop = new Properties();
prop.load(new ByteArrayInputStream(ruleData));
for (MigrateTask migrateTask : allTaskList) {
modifyRuleData(prop, migrateTask, allNewDataNodes);
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
prop.store(out, "WARNING !!!Please do not modify or delete this file!!!");
if (transactionFinal == null) {
transactionFinal = ZKUtils.getConnection().inTransaction().setData().forPath(rulePath, out.toByteArray()).and();
} else {
transactionFinal.setData().forPath(rulePath, out.toByteArray());
}
} finally {
try {
if (ruleDataLock != null)
ruleDataLock.release();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return transactionFinal;
}
use of io.mycat.config.model.rule.RuleConfig in project Mycat-Server by MyCATApache.
the class DruidMycatRouteStrategy method routeNormalSqlWithAST.
@Override
public RouteResultset routeNormalSqlWithAST(SchemaConfig schema, String stmt, RouteResultset rrs, String charset, LayerCachePool cachePool) throws SQLNonTransientException {
/**
* 只有mysql时只支持mysql语法
*/
SQLStatementParser parser = null;
if (schema.isNeedSupportMultiDBType()) {
parser = new MycatStatementParser(stmt);
} else {
parser = new MySqlStatementParser(stmt);
}
MycatSchemaStatVisitor visitor = null;
SQLStatement statement;
/**
* 解析出现问题统一抛SQL语法错误
*/
try {
statement = parser.parseStatement();
visitor = new MycatSchemaStatVisitor();
} catch (Exception t) {
LOGGER.error("DruidMycatRouteStrategyError", t);
throw new SQLSyntaxErrorException(t);
}
/**
* 检验unsupported statement
*/
checkUnSupportedStatement(statement);
DruidParser druidParser = DruidParserFactory.create(schema, statement, visitor);
druidParser.parser(schema, rrs, statement, stmt, cachePool, visitor);
DruidShardingParseInfo ctx = druidParser.getCtx();
rrs.setTables(ctx.getTables());
/**
* DruidParser 解析过程中已完成了路由的直接返回
*/
if (rrs.isFinishedRoute()) {
return rrs;
}
/**
* 没有from的select语句或其他
*/
if ((ctx.getTables() == null || ctx.getTables().size() == 0) && (ctx.getTableAliasMap() == null || ctx.getTableAliasMap().isEmpty())) {
return RouterUtil.routeToSingleNode(rrs, schema.getRandomDataNode(), druidParser.getCtx().getSql());
}
if (druidParser.getCtx().getRouteCalculateUnits().size() == 0) {
RouteCalculateUnit routeCalculateUnit = new RouteCalculateUnit();
druidParser.getCtx().addRouteCalculateUnit(routeCalculateUnit);
}
SortedSet<RouteResultsetNode> nodeSet = new TreeSet<RouteResultsetNode>();
for (RouteCalculateUnit unit : druidParser.getCtx().getRouteCalculateUnits()) {
RouteResultset rrsTmp = RouterUtil.tryRouteForTables(schema, druidParser.getCtx(), unit, rrs, isSelect(statement), cachePool);
if (rrsTmp != null) {
for (RouteResultsetNode node : rrsTmp.getNodes()) {
nodeSet.add(node);
}
}
}
RouteResultsetNode[] nodes = new RouteResultsetNode[nodeSet.size()];
int i = 0;
for (RouteResultsetNode aNodeSet : nodeSet) {
nodes[i] = aNodeSet;
if (statement instanceof MySqlInsertStatement && ctx.getTables().size() == 1 && schema.getTables().containsKey(ctx.getTables().get(0))) {
RuleConfig rule = schema.getTables().get(ctx.getTables().get(0)).getRule();
if (rule != null && rule.getRuleAlgorithm() instanceof SlotFunction) {
aNodeSet.setStatement(ParseUtil.changeInsertAddSlot(aNodeSet.getStatement(), aNodeSet.getSlot()));
}
}
i++;
}
rrs.setNodes(nodes);
/**
* subTables="t_order$1-2,t_order3"
*目前分表 1.6 开始支持 幵丏 dataNode 在分表条件下只能配置一个,分表条件下不支持join。
*/
if (rrs.isDistTable()) {
return this.routeDisTable(statement, rrs);
}
return rrs;
}
use of io.mycat.config.model.rule.RuleConfig in project Mycat-Server by MyCATApache.
the class ConfigComparer method loadMigratorTable.
private void loadMigratorTable(TableConfig oldTable, TableConfig newTable, String schemaName, String tableName) {
//禁止配置非拆分表
if (oldTable == null || newTable == null) {
throw new ConfigException("please check tableFile.properties,make sure " + schemaName + ":" + tableName + " is sharding table ");
}
//忽略全局表
if (oldTable.isGlobalTable() || newTable.isGlobalTable()) {
String message = "global table: " + schemaName + ":" + tableName + " is ignore!";
System.out.println("Warn: " + message);
LOGGER.warn(message);
} else {
List<DataNode> oldDN = getDataNodes(oldTable, oldDataNodes, oldDataHosts);
List<DataNode> newDN = getDataNodes(newTable, newDataNodes, newDataHosts);
//忽略数据节点分布没有发生变化的表
if (isNeedMigrate(oldDN, newDN)) {
checkRuleConfig(oldTable.getRule(), newTable.getRule(), schemaName, tableName);
RuleConfig newRC = newTable.getRule();
TableMigrateInfo tmi = new TableMigrateInfo(schemaName, tableName, oldDN, newDN, newRC.getRuleAlgorithm(), newRC.getColumn());
migratorTables.add(tmi);
} else {
String message = schemaName + ":" + tableName + " is ignore,no need to migrate!";
LOGGER.warn(message);
System.out.println("Warn: " + message);
}
}
}
Aggregations