Search in sources :

Example 11 with TableConfig

use of io.mycat.config.model.TableConfig in project Mycat_plus by coderczp.

the class DruidInsertParser method statementParse.

/**
 * 考虑因素:isChildTable、批量、是否分片
 */
@Override
public void statementParse(SchemaConfig schema, RouteResultset rrs, SQLStatement stmt) throws SQLNonTransientException {
    MySqlInsertStatement insert = (MySqlInsertStatement) stmt;
    String tableName = StringUtil.removeBackquote(insert.getTableName().getSimpleName()).toUpperCase();
    ctx.addTable(tableName);
    if (RouterUtil.isNoSharding(schema, tableName)) {
        // 整个schema都不分库或者该表不拆分
        RouterUtil.routeForTableMeta(rrs, schema, tableName, rrs.getStatement());
        rrs.setFinishedRoute(true);
        return;
    }
    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);
    } else {
        // childTable的insert直接在解析过程中完成路由
        if (tc.isChildTable()) {
            parserChildTable(schema, rrs, tableName, insert);
            return;
        }
        String partitionColumn = tc.getPartitionColumn();
        if (partitionColumn != null) {
            // 拆分表必须给出column list,否则无法寻找分片字段的值
            if (insert.getColumns() == null || insert.getColumns().size() == 0) {
                throw new SQLSyntaxErrorException("partition table, insert must provide ColumnList");
            }
            // 批量insert
            if (isMultiInsert(insert)) {
                // String msg = "multi insert not provided" ;
                // LOGGER.warn(msg);
                // throw new SQLNonTransientException(msg);
                parserBatchInsert(schema, rrs, partitionColumn, tableName, insert);
            } else {
                parserSingleInsert(schema, rrs, partitionColumn, tableName, insert);
            }
        }
    }
}
Also used : SQLNonTransientException(java.sql.SQLNonTransientException) SQLSyntaxErrorException(java.sql.SQLSyntaxErrorException) TableConfig(io.mycat.config.model.TableConfig) MySqlInsertStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement)

Example 12 with TableConfig

use of io.mycat.config.model.TableConfig in project Mycat_plus by coderczp.

the class DruidSelectParser method isNeedCache.

private boolean isNeedCache(SchemaConfig schema, RouteResultset rrs, MySqlSelectQueryBlock mysqlSelectQuery, Map<String, Map<String, Set<ColumnRoutePair>>> allConditions) {
    if (ctx.getTables() == null || ctx.getTables().size() == 0) {
        return false;
    }
    TableConfig tc = schema.getTables().get(ctx.getTables().get(0));
    if (tc == null || (ctx.getTables().size() == 1 && tc.isGlobalTable())) {
        // || (ctx.getTables().size() == 1) && tc.getRule() == null && tc.getDataNodes().size() == 1
        return false;
    } else {
        // 单表主键查询
        if (ctx.getTables().size() == 1) {
            String tableName = ctx.getTables().get(0);
            String primaryKey = schema.getTables().get(tableName).getPrimaryKey();
            // schema.getTables().get(ctx.getTables().get(0)).getParentKey() != null;
            if (ctx.getRouteCalculateUnit().getTablesAndConditions().get(tableName) != null && ctx.getRouteCalculateUnit().getTablesAndConditions().get(tableName).get(primaryKey) != null && tc.getDataNodes().size() > 1) {
                // 有主键条件
                return false;
            }
        // 全局表不缓存
        } else if (RouterUtil.isAllGlobalTable(ctx, schema)) {
            return false;
        }
        return true;
    }
}
Also used : TableConfig(io.mycat.config.model.TableConfig)

Example 13 with TableConfig

use of io.mycat.config.model.TableConfig in project Mycat_plus by coderczp.

the class DruidUpdateParser method statementParse.

@Override
public void statementParse(SchemaConfig schema, RouteResultset rrs, SQLStatement stmt) throws SQLNonTransientException {
    // 这里限制了update分片表的个数只能有一个
    if (ctx.getTables() != null && getUpdateTableCount() > 1 && !schema.isNoSharding()) {
        String msg = "multi table related update not supported,tables:" + ctx.getTables();
        LOGGER.warn(msg);
        throw new SQLNonTransientException(msg);
    }
    MySqlUpdateStatement update = (MySqlUpdateStatement) stmt;
    String tableName = StringUtil.removeBackquote(update.getTableName().getSimpleName().toUpperCase());
    TableConfig tc = schema.getTables().get(tableName);
    if (RouterUtil.isNoSharding(schema, tableName)) {
        // 整个schema都不分库或者该表不拆分
        RouterUtil.routeForTableMeta(rrs, schema, tableName, rrs.getStatement());
        rrs.setFinishedRoute(true);
        return;
    }
    String partitionColumn = tc.getPartitionColumn();
    String joinKey = tc.getJoinKey();
    if (tc.isGlobalTable() || (partitionColumn == null && joinKey == null)) {
        // 修改全局表 update 受影响的行数
        RouterUtil.routeToMultiNode(false, rrs, tc.getDataNodes(), rrs.getStatement(), tc.isGlobalTable());
        rrs.setFinishedRoute(true);
        return;
    }
    confirmShardColumnNotUpdated(update, schema, tableName, partitionColumn, joinKey, rrs);
    if (schema.getTables().get(tableName).isGlobalTable() && ctx.getRouteCalculateUnit().getTablesAndConditions().size() > 1) {
        throw new SQLNonTransientException("global table is not supported in multi table related update " + tableName);
    }
}
Also used : SQLNonTransientException(java.sql.SQLNonTransientException) TableConfig(io.mycat.config.model.TableConfig) MySqlUpdateStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement)

Example 14 with TableConfig

use of io.mycat.config.model.TableConfig in project Mycat_plus by coderczp.

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());
}
Also used : OneRawSQLQueryResultHandler(io.mycat.sqlengine.OneRawSQLQueryResultHandler) PhysicalDBNode(io.mycat.backend.datasource.PhysicalDBNode) SchemaConfig(io.mycat.config.model.SchemaConfig) ParticipantLogEntry(io.mycat.backend.mysql.xa.ParticipantLogEntry) SQLJob(io.mycat.sqlengine.SQLJob) XARollbackCallback(io.mycat.backend.mysql.xa.XARollbackCallback) TableConfig(io.mycat.config.model.TableConfig) CoordinatorLogEntry(io.mycat.backend.mysql.xa.CoordinatorLogEntry)

Example 15 with TableConfig

use of io.mycat.config.model.TableConfig in project Mycat_plus by coderczp.

the class RouterUtil method routeToDDLNode.

/**
 * 修复DDL路由
 *
 * @return RouteResultset
 * @author aStoneGod
 */
public static RouteResultset routeToDDLNode(RouteResultset rrs, int sqlType, String stmt, SchemaConfig schema) throws SQLSyntaxErrorException {
    stmt = getFixedSql(stmt);
    String tablename = "";
    final String upStmt = stmt.toUpperCase();
    if (upStmt.startsWith("CREATE")) {
        if (upStmt.contains("CREATE INDEX ") || upStmt.contains("CREATE UNIQUE INDEX ")) {
            tablename = RouterUtil.getTableName(stmt, RouterUtil.getCreateIndexPos(upStmt, 0));
        } else {
            tablename = RouterUtil.getTableName(stmt, RouterUtil.getCreateTablePos(upStmt, 0));
        }
    } else if (upStmt.startsWith("DROP")) {
        if (upStmt.contains("DROP INDEX ")) {
            tablename = RouterUtil.getTableName(stmt, RouterUtil.getDropIndexPos(upStmt, 0));
        } else {
            tablename = RouterUtil.getTableName(stmt, RouterUtil.getDropTablePos(upStmt, 0));
        }
    } else if (upStmt.startsWith("ALTER")) {
        tablename = RouterUtil.getTableName(stmt, RouterUtil.getAlterTablePos(upStmt, 0));
    } else if (upStmt.startsWith("TRUNCATE")) {
        tablename = RouterUtil.getTableName(stmt, RouterUtil.getTruncateTablePos(upStmt, 0));
    }
    tablename = tablename.toUpperCase();
    if (schema.getTables().containsKey(tablename)) {
        if (ServerParse.DDL == sqlType) {
            List<String> dataNodes = new ArrayList<>();
            Map<String, TableConfig> tables = schema.getTables();
            TableConfig tc = tables.get(tablename);
            if (tables != null && (tc != null)) {
                dataNodes = tc.getDataNodes();
            }
            boolean isSlotFunction = tc.getRule() != null && tc.getRule().getRuleAlgorithm() instanceof SlotFunction;
            Iterator<String> iterator1 = dataNodes.iterator();
            int nodeSize = dataNodes.size();
            RouteResultsetNode[] nodes = new RouteResultsetNode[nodeSize];
            if (isSlotFunction) {
                stmt = changeCreateTable(schema, tablename, stmt);
            }
            for (int i = 0; i < nodeSize; i++) {
                String name = iterator1.next();
                nodes[i] = new RouteResultsetNode(name, sqlType, stmt);
                nodes[i].setSource(rrs);
                if (rrs.getDataNodeSlotMap().containsKey(name)) {
                    nodes[i].setSlot(rrs.getDataNodeSlotMap().get(name));
                } else if (isSlotFunction) {
                    nodes[i].setSlot(-1);
                }
            }
            rrs.setNodes(nodes);
        }
        return rrs;
    } else if (schema.getDataNode() != null) {
        // 默认节点ddl
        RouteResultsetNode[] nodes = new RouteResultsetNode[1];
        nodes[0] = new RouteResultsetNode(schema.getDataNode(), sqlType, stmt);
        nodes[0].setSource(rrs);
        rrs.setNodes(nodes);
        return rrs;
    }
    // both tablename and defaultnode null
    LOGGER.error("table not in schema----" + tablename);
    throw new SQLSyntaxErrorException("op table not in schema----" + tablename);
}
Also used : RouteResultsetNode(io.mycat.route.RouteResultsetNode) ArrayList(java.util.ArrayList) SQLSyntaxErrorException(java.sql.SQLSyntaxErrorException) TableConfig(io.mycat.config.model.TableConfig) SlotFunction(io.mycat.route.function.SlotFunction)

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