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);
}
}
}
}
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;
}
}
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);
}
}
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());
}
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);
}
Aggregations