Search in sources :

Example 1 with TableConfig

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();
            }
        }
    }
}
Also used : OneRawSQLQueryResultHandler(io.mycat.sqlengine.OneRawSQLQueryResultHandler) PhysicalDBNode(io.mycat.backend.datasource.PhysicalDBNode) SchemaConfig(io.mycat.config.model.SchemaConfig) SQLJob(io.mycat.sqlengine.SQLJob) TableConfig(io.mycat.config.model.TableConfig) List(java.util.List) LinkedList(java.util.LinkedList) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 2 with TableConfig

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) {
            }
        }
    }
}
Also used : ClusterInfo(io.mycat.config.loader.zkprocess.zookeeper.ClusterInfo) SchemaConfig(io.mycat.config.model.SchemaConfig) CuratorTransactionFinal(org.apache.curator.framework.api.transaction.CuratorTransactionFinal) TableConfig(io.mycat.config.model.TableConfig) InterProcessMutex(org.apache.curator.framework.recipes.locks.InterProcessMutex) SQLException(java.sql.SQLException) IOException(java.io.IOException)

Example 3 with TableConfig

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);
}
Also used : SystemConfig(io.mycat.config.model.SystemConfig) SchemaConfig(io.mycat.config.model.SchemaConfig) ArrayList(java.util.ArrayList) TableConfig(io.mycat.config.model.TableConfig) RouteService(io.mycat.route.RouteService) CacheService(io.mycat.cache.CacheService) RouteResultset(io.mycat.route.RouteResultset) Test(org.junit.Test)

Example 4 with TableConfig

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);
}
Also used : TableConfig(io.mycat.config.model.TableConfig) RuleConfig(io.mycat.config.model.rule.RuleConfig) Test(org.junit.Test)

Example 5 with TableConfig

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;
}
Also used : NodeList(org.w3c.dom.NodeList) Element(org.w3c.dom.Element) TableRuleAware(io.mycat.route.function.TableRuleAware) ConfigException(io.mycat.config.util.ConfigException) TableConfigMap(io.mycat.config.model.TableConfigMap) TableRuleConfig(io.mycat.config.model.rule.TableRuleConfig) TableConfig(io.mycat.config.model.TableConfig) TableRuleConfig(io.mycat.config.model.rule.TableRuleConfig) RuleConfig(io.mycat.config.model.rule.RuleConfig)

Aggregations

TableConfig (io.mycat.config.model.TableConfig)84 SchemaConfig (io.mycat.config.model.SchemaConfig)26 SQLNonTransientException (java.sql.SQLNonTransientException)26 Test (org.junit.Test)18 RuleConfig (io.mycat.config.model.rule.RuleConfig)16 RouteResultset (io.mycat.route.RouteResultset)14 AbstractPartitionAlgorithm (io.mycat.route.function.AbstractPartitionAlgorithm)14 HashMap (java.util.HashMap)14 MySqlStatementParser (com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser)12 SlotFunction (io.mycat.route.function.SlotFunction)12 ArrayList (java.util.ArrayList)12 SQLStatement (com.alibaba.druid.sql.ast.SQLStatement)10 MySqlInsertStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement)8 PhysicalDBNode (io.mycat.backend.datasource.PhysicalDBNode)8 ConfigException (io.mycat.config.util.ConfigException)8 RouteResultsetNode (io.mycat.route.RouteResultsetNode)8 HashSet (java.util.HashSet)8 SQLCharExpr (com.alibaba.druid.sql.ast.expr.SQLCharExpr)6 SQLIdentifierExpr (com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr)6 CacheService (io.mycat.cache.CacheService)6