use of io.mycat.config.model.TableConfig in project Mycat_plus by coderczp.
the class MySQLTableStructureDetector method run.
@Override
public void run() {
for (SchemaConfig schema : MycatServer.getInstance().getConfig().getSchemas().values()) {
for (TableConfig table : schema.getTables().values()) {
for (String dataNode : table.getDataNodes()) {
try {
table.getReentrantReadWriteLock().writeLock().lock();
ConcurrentHashMap<String, List<String>> map = new ConcurrentHashMap<>();
table.setDataNodeTableStructureSQLMap(map);
} finally {
table.getReentrantReadWriteLock().writeLock().unlock();
}
OneRawSQLQueryResultHandler resultHandler = new OneRawSQLQueryResultHandler(MYSQL_SHOW_CREATE_TABLE_COLMS, new MySQLTableStructureListener(dataNode, table));
resultHandler.setMark("Table Structure");
PhysicalDBNode dn = MycatServer.getInstance().getConfig().getDataNodes().get(dataNode);
SQLJob sqlJob = new SQLJob(sqlPrefix + table.getName(), dn.getDatabase(), resultHandler, dn.getDbPool().getSource());
sqlJob.run();
}
}
}
}
use of io.mycat.config.model.TableConfig in project Mycat_plus by coderczp.
the class SwitchCommitListener method checkCommit.
private void checkCommit(PathChildrenCacheEvent event) {
InterProcessMutex taskLock = null;
try {
String path = event.getData().getPath();
String taskPath = path.substring(0, path.lastIndexOf("/_commit/"));
String taskID = taskPath.substring(taskPath.lastIndexOf('/') + 1, taskPath.length());
String lockPath = ZKUtils.getZKBasePath() + "lock/" + taskID + ".lock";
List<String> sucessDataHost = ZKUtils.getConnection().getChildren().forPath(path.substring(0, path.lastIndexOf('/')));
String custerName = ZkConfig.getInstance().getValue(ZkParamCfg.ZK_CFG_CLUSTERID);
ClusterInfo clusterInfo = JSON.parseObject(ZKUtils.getConnection().getData().forPath("/mycat/" + custerName), ClusterInfo.class);
List<String> clusterNodeList = Splitter.on(',').omitEmptyStrings().splitToList(clusterInfo.getClusterNodes());
if (sucessDataHost.size() == clusterNodeList.size()) {
List<String> taskDataHost = ZKUtils.getConnection().getChildren().forPath(taskPath);
List<MigrateTask> allTaskList = MigrateUtils.queryAllTask(taskPath, taskDataHost);
taskLock = new InterProcessMutex(ZKUtils.getConnection(), lockPath);
taskLock.acquire(120, TimeUnit.SECONDS);
TaskNode taskNode = JSON.parseObject(ZKUtils.getConnection().getData().forPath(taskPath), TaskNode.class);
if (taskNode.getStatus() == 2) {
taskNode.setStatus(3);
// 开始切换 且个节点已经禁止写入并且无原有写入在执行
try {
CuratorTransactionFinal transactionFinal = null;
check(taskID, allTaskList);
SchemaConfig schemaConfig = MycatServer.getInstance().getConfig().getSchemas().get(taskNode.getSchema());
TableConfig tableConfig = schemaConfig.getTables().get(taskNode.getTable().toUpperCase());
List<String> newDataNodes = Splitter.on(",").omitEmptyStrings().trimResults().splitToList(taskNode.getAdd());
List<String> allNewDataNodes = tableConfig.getDataNodes();
allNewDataNodes.addAll(newDataNodes);
// 先修改rule config
InterProcessMutex ruleLock = new InterProcessMutex(ZKUtils.getConnection(), ZKUtils.getZKBasePath() + "lock/rules.lock");
;
try {
ruleLock.acquire(30, TimeUnit.SECONDS);
transactionFinal = modifyZkRules(transactionFinal, tableConfig.getRule().getFunctionName(), newDataNodes);
transactionFinal = modifyTableConfigRules(transactionFinal, taskNode.getSchema(), taskNode.getTable(), newDataNodes);
} finally {
ruleLock.release();
}
transactionFinal = modifyRuleData(transactionFinal, allTaskList, tableConfig, allNewDataNodes);
transactionFinal.setData().forPath(taskPath, JSON.toJSONBytes(taskNode));
clean(taskID, allTaskList);
transactionFinal.commit();
forceTableRuleToLocal();
pushACKToClean(taskPath);
} catch (Exception e) {
// todo 异常to Zk
LOGGER.error("error:", e);
}
// todo 清理规则 顺利拉下ruledata保证一定更新到本地
} else if (taskNode.getStatus() == 3) {
forceTableRuleToLocal();
pushACKToClean(taskPath);
}
}
} catch (Exception e) {
LOGGER.error("error:", e);
} finally {
if (taskLock != null) {
try {
taskLock.release();
} catch (Exception ignored) {
}
}
}
}
use of io.mycat.config.model.TableConfig in project Mycat_plus by coderczp.
the class DDLRouteTest method testSpecialCharDDL.
@Test
public void testSpecialCharDDL() throws Exception {
SchemaConfig schema = schemaMap.get("TESTDB");
CacheService cacheService = new CacheService();
RouteService routerService = new RouteService(cacheService);
// alter table test
String sql = " ALTER TABLE COMPANY\r\nADD COLUMN TEST VARCHAR(255) NULL AFTER CREATE_DATE,\r\n CHARACTER SET = UTF8";
sql = RouterUtil.getFixedSql(sql);
List<String> dataNodes = new ArrayList<>();
String tablename = RouterUtil.getTableName(sql, RouterUtil.getAlterTablePos(sql, 0));
Map<String, TableConfig> tables = schema.getTables();
TableConfig tc;
if (tables != null && (tc = tables.get(tablename)) != null) {
dataNodes = tc.getDataNodes();
}
int nodeSize = dataNodes.size();
int rs = ServerParse.parse(sql);
int sqlType = rs & 0xff;
RouteResultset rrs = routerService.route(new SystemConfig(), schema, sqlType, sql, "UTF-8", null);
Assert.assertTrue("COMPANY".equals(tablename));
Assert.assertTrue(rrs.getNodes().length == nodeSize);
}
use of io.mycat.config.model.TableConfig in project Mycat_plus by coderczp.
the class RuleFunctionSuitTableTest method testPartitionByRangeMod.
@Test
public void testPartitionByRangeMod() {
PartitionByRangeMod partition = new PartitionByRangeMod();
partition.setMapFile("partition-range-mod.txt");
partition.init();
// partition = 20
Assert.assertEquals(20, partition.getPartitionNum());
RuleConfig rule = new RuleConfig("id", "partition-range-mod");
rule.setRuleAlgorithm(partition);
TableConfig tableConf = new TableConfig("test", "id", true, false, -1, "dn$1-10", null, rule, true, null, false, null, null, null);
int suit1 = partition.suitableFor(tableConf);
Assert.assertEquals(-1, suit1);
tableConf.getDataNodes().clear();
String[] dataNodes = SplitUtil.split("dn$1-20", ',', '$', '-');
tableConf.getDataNodes().addAll(Arrays.asList(dataNodes));
int suit2 = partition.suitableFor(tableConf);
Assert.assertEquals(0, suit2);
tableConf.getDataNodes().clear();
dataNodes = SplitUtil.split("dn$1-30", ',', '$', '-');
tableConf.getDataNodes().addAll(Arrays.asList(dataNodes));
int suit3 = partition.suitableFor(tableConf);
Assert.assertEquals(1, suit3);
}
use of io.mycat.config.model.TableConfig in project Mycat_plus by coderczp.
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;
}
Aggregations