Search in sources :

Example 11 with JdbcConnectionManager

use of io.mycat.datasource.jdbc.datasource.JdbcConnectionManager in project Mycat2 by MyCATApache.

the class TransactionSessionTemplate method callBackConnections.

protected Map<String, MycatConnection> callBackConnections(Set<String> jdbcDataSources, boolean autocommit, int transactionIsolation, boolean readOnly) {
    if (jdbcDataSources.isEmpty())
        return Collections.emptyMap();
    HashMap<String, MycatConnection> res = new HashMap<>();
    JdbcConnectionManager jdbcConnectionManager = MetaClusterCurrent.wrapper(JdbcConnectionManager.class);
    synchronized (jdbcConnectionManager) {
        for (String jdbcDataSource : jdbcDataSources) {
            DefaultConnection defaultConnection1 = updateConnectionMap.computeIfAbsent(jdbcDataSource, s -> jdbcConnectionManager.getConnection(jdbcDataSource, autocommit, transactionIsolation));
            res.put(jdbcDataSource, defaultConnection1);
        }
    }
    return res;
}
Also used : DefaultConnection(io.mycat.datasource.jdbc.datasource.DefaultConnection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) JdbcConnectionManager(io.mycat.datasource.jdbc.datasource.JdbcConnectionManager)

Example 12 with JdbcConnectionManager

use of io.mycat.datasource.jdbc.datasource.JdbcConnectionManager in project Mycat2 by MyCATApache.

the class ShardingTable method createPhysicalTables.

@Override
public void createPhysicalTables() {
    JdbcConnectionManager jdbcConnectionManager = MetaClusterCurrent.wrapper(JdbcConnectionManager.class);
    List<Partition> partitions = (List) ImmutableList.builder().addAll(getBackends()).build();
    partitions.stream().parallel().forEach(node -> CreateTableUtils.createPhysicalTable(jdbcConnectionManager, node, getCreateTableSQL()));
    for (ShardingIndexTable indexTable : getIndexTables()) {
        indexTable.createPhysicalTables();
    }
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) JdbcConnectionManager(io.mycat.datasource.jdbc.datasource.JdbcConnectionManager)

Example 13 with JdbcConnectionManager

use of io.mycat.datasource.jdbc.datasource.JdbcConnectionManager in project Mycat2 by MyCATApache.

the class ShardingTable method dropPhysicalTables.

@Override
public void dropPhysicalTables() {
    JdbcConnectionManager jdbcConnectionManager = MetaClusterCurrent.wrapper(JdbcConnectionManager.class);
    getBackends().stream().parallel().forEach(c -> {
        try (DefaultConnection connection = jdbcConnectionManager.getConnection(c.getTargetName())) {
            connection.deleteTable(c.getSchema(), c.getTable());
        }
    });
}
Also used : DefaultConnection(io.mycat.datasource.jdbc.datasource.DefaultConnection) JdbcConnectionManager(io.mycat.datasource.jdbc.datasource.JdbcConnectionManager)

Example 14 with JdbcConnectionManager

use of io.mycat.datasource.jdbc.datasource.JdbcConnectionManager in project Mycat2 by MyCATApache.

the class BinlogUtil method observe.

public static Flowable<ParamSQL> observe(String targetName, List<Partition> partitions) {
    JdbcConnectionManager jdbcConnectionManager = MetaClusterCurrent.wrapper(JdbcConnectionManager.class);
    DatasourceConfig datasourceConfig = jdbcConnectionManager.getConfigAsMap().get(targetName);
    ConnectionUrlParser connectionUrlParser = ConnectionUrlParser.parseConnectionString(datasourceConfig.getUrl());
    HostInfo hostInfo = connectionUrlParser.getHosts().get(0);
    int port = hostInfo.getPort();
    String host = hostInfo.getHost();
    String username = datasourceConfig.getUser();
    String password = datasourceConfig.getPassword();
    BinaryLogClient client = new BinaryLogClient(datasourceConfig.getUrl(), port, username, password);
    NameMap<NameMap<Boolean>> filterMap = new NameMap<>();
    for (Partition partition : partitions) {
        String schema = partition.getSchema();
        String table = partition.getTable();
        NameMap<Boolean> map = filterMap.computeIfAbsent(SQLUtils.normalize(schema), s -> new NameMap<>());
        map.put(table, Boolean.TRUE);
    }
    return Flowable.create(new FlowableOnSubscribe<ParamSQL>() {

        @Override
        public void subscribe(@NonNull FlowableEmitter<ParamSQL> emitter) throws Throwable {
            client.registerEventListener(new BinaryLogClient.EventListener() {

                private final Map<Long, TableMapEventData> tablesById = new HashMap<Long, TableMapEventData>();

                private final Map<String, Map<Integer, Map<String, Object>>> tablesColumnMap = new HashMap<>();

                private String binlogFilename;

                private Charset charset = StandardCharsets.UTF_8;

                private Map<Integer, Map<String, Object>> loadColumn(String database, String table) {
                    Map<Integer, Map<String, Object>> res = new HashMap<>();
                    try (DefaultConnection defaultConnection = jdbcConnectionManager.getConnection(targetName)) {
                        List<Map<String, Object>> list = JdbcUtils.executeQuery(defaultConnection.getRawConnection(), "select  COLUMN_NAME, ORDINAL_POSITION, DATA_TYPE, CHARACTER_SET_NAME from INFORMATION_SCHEMA.COLUMNS where table_name='" + table + "' and TABLE_SCHEMA='" + database + "'", Collections.emptyList());
                        for (Map<String, Object> stringObjectMap : list) {
                            Number pos = (Number) stringObjectMap.get("ORDINAL_POSITION");
                            res.put(pos.intValue(), stringObjectMap);
                        }
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    return res;
                }

                @Override
                public void onEvent(Event event) {
                    try {
                        EventHeader header = event.getHeader();
                        switch(header.getEventType()) {
                            case UNKNOWN:
                                break;
                            case START_V3:
                                break;
                            case QUERY:
                                QueryEventData queryEventData = event.getData();
                                String query = queryEventData.getSql();
                                if (!query.startsWith("S")) {
                                    handleDDL(queryEventData);
                                }
                                break;
                            case STOP:
                                emitter.onComplete();
                                break;
                            case ROTATE:
                                {
                                    RotateEventData data = event.getData();
                                    this.binlogFilename = data.getBinlogFilename();
                                    break;
                                }
                            case INTVAR:
                                break;
                            case LOAD:
                                break;
                            case SLAVE:
                                break;
                            case CREATE_FILE:
                                break;
                            case APPEND_BLOCK:
                                break;
                            case EXEC_LOAD:
                                break;
                            case DELETE_FILE:
                                break;
                            case NEW_LOAD:
                                break;
                            case RAND:
                                break;
                            case USER_VAR:
                                break;
                            case FORMAT_DESCRIPTION:
                                break;
                            case XID:
                                break;
                            case BEGIN_LOAD_QUERY:
                                break;
                            case EXECUTE_LOAD_QUERY:
                                break;
                            case TABLE_MAP:
                                {
                                    handleTableMap(event);
                                    break;
                                }
                            case PRE_GA_WRITE_ROWS:
                            case WRITE_ROWS:
                            case EXT_WRITE_ROWS:
                                handleWriteRowsEvent(event);
                                break;
                            case EXT_UPDATE_ROWS:
                            case PRE_GA_UPDATE_ROWS:
                            case UPDATE_ROWS:
                                handleUpdateRowsEvent(event);
                                break;
                            case PRE_GA_DELETE_ROWS:
                            case EXT_DELETE_ROWS:
                            case DELETE_ROWS:
                                handleDeleteRowsEvent(event);
                                break;
                            case INCIDENT:
                                break;
                            case HEARTBEAT:
                                break;
                            case IGNORABLE:
                                break;
                            case ROWS_QUERY:
                                break;
                            case GTID:
                                break;
                            case ANONYMOUS_GTID:
                                break;
                            case PREVIOUS_GTIDS:
                                break;
                            case TRANSACTION_CONTEXT:
                                break;
                            case VIEW_CHANGE:
                                break;
                            case XA_PREPARE:
                                break;
                        }
                    } catch (Exception e) {
                        emitter.tryOnError(e);
                    }
                }

                private void handleDDL(QueryEventData event) {
                    String sql = event.getSql();
                    String database = event.getDatabase();
                    SQLStatement sqlStatement = SQLUtils.parseSingleMysqlStatement(sql);
                    if (sqlStatement instanceof SQLDDLStatement) {
                        SQLDDLStatement sqlDdlStatement = (SQLDDLStatement) sqlStatement;
                        MySqlSchemaStatVisitor mySqlSchemaStatVisitor = new MySqlSchemaStatVisitor();
                        sqlDdlStatement.accept(mySqlSchemaStatVisitor);
                        Map<TableStat.Name, TableStat> tables = mySqlSchemaStatVisitor.getTables();
                        boolean meet = tables.keySet().stream().allMatch(i -> filter(database, i.getName()));
                    }
                }

                private void handleUpdateRowsEvent(Event event) {
                    UpdateRowsEventData eventData = event.getData();
                    BitSet includedColumnsBeforeUpdate = eventData.getIncludedColumnsBeforeUpdate();
                    BitSet includedColumns = eventData.getIncludedColumns();
                    List<Map.Entry<Serializable[], Serializable[]>> rows = eventData.getRows();
                    TableMapEventData tableMapEvent = tablesById.get(eventData.getTableId());
                    if (!filter(tableMapEvent.getDatabase(), tableMapEvent.getTable()))
                        return;
                    MySqlUpdateStatement mySqlUpdateStatement = new MySqlUpdateStatement();
                    SQLExprTableSource sqlTableSource = new SQLExprTableSource();
                    sqlTableSource.setExpr("`" + tableMapEvent.getTable() + "`");
                    sqlTableSource.setSchema("`" + tableMapEvent.getDatabase() + "`");
                    mySqlUpdateStatement.setTableSource(sqlTableSource);
                    Map<Integer, Map<String, Object>> xxx = tablesColumnMap.get(tableMapEvent.getDatabase() + "." + tableMapEvent.getTable());
                    SQLBinaryOpExprGroup sqlBinaryOpExprGroup = getCondition(includedColumnsBeforeUpdate, xxx);
                    for (int i = 0; i < includedColumns.length(); i++) {
                        int column = includedColumns.nextSetBit(i);
                        Map<String, Object> coumnMap = xxx.get(column + 1);
                        Object column_name = coumnMap.get("COLUMN_NAME");
                        SQLUpdateSetItem sqlUpdateSetItem = new SQLUpdateSetItem();
                        sqlUpdateSetItem.setColumn(new SQLIdentifierExpr("`" + column_name + "`"));
                        sqlUpdateSetItem.setValue(new SQLVariantRefExpr("?"));
                        mySqlUpdateStatement.getItems().add(sqlUpdateSetItem);
                    }
                    mySqlUpdateStatement.setWhere(sqlBinaryOpExprGroup);
                    mySqlUpdateStatement.setLimit(new SQLLimit(1));
                    sqlUpdate(mySqlUpdateStatement.toString(), rows);
                }

                private SQLBinaryOpExprGroup getCondition(BitSet includedColumnsBeforeUpdate, Map<Integer, Map<String, Object>> xxx) {
                    SQLBinaryOpExprGroup sqlBinaryOpExprGroup = new SQLBinaryOpExprGroup(SQLBinaryOperator.BooleanAnd);
                    for (int i = 0; i < includedColumnsBeforeUpdate.length(); i++) {
                        int column = includedColumnsBeforeUpdate.nextSetBit(i);
                        Map<String, Object> coumnMap = xxx.get(column + 1);
                        Object column_name = coumnMap.get("COLUMN_NAME");
                        SQLExpr sqlExpr = SQLUtils.toSQLExpr("`" + column_name + "` <=> ?");
                        sqlBinaryOpExprGroup.add(sqlExpr);
                    }
                    return sqlBinaryOpExprGroup;
                }

                private void sqlUpdate(String toString, List<Map.Entry<Serializable[], Serializable[]>> rows) {
                    for (Map.Entry<Serializable[], Serializable[]> row : rows) {
                        Serializable[] key = row.getKey();
                        Serializable[] value = row.getValue();
                        Object[] objects = new Object[key.length + value.length];
                        System.arraycopy(key, 0, objects, 0, key.length);
                        System.arraycopy(value, 0, objects, key.length, key.length + value.length);
                        emitter.onNext(ParamSQL.of(toString, objects));
                    }
                }

                private boolean filter(String database, String table) {
                    if (Strings.isNullOrEmpty(database)) {
                        return false;
                    }
                    if (Strings.isNullOrEmpty(table)) {
                        return false;
                    }
                    NameMap<Boolean> tableMap = filterMap.get(SQLUtils.normalize(database), false);
                    if (tableMap != null && !tableMap.map().isEmpty()) {
                        return Boolean.TRUE.equals(tableMap.get(SQLUtils.normalize(table)));
                    }
                    return false;
                }

                private void handleTableMap(Event event) {
                    TableMapEventData tableMapEventData = event.getData();
                    tablesById.put(tableMapEventData.getTableId(), tableMapEventData);
                    String tableName = tableMapEventData.getDatabase() + "." + tableMapEventData.getTable();
                    if (!tablesColumnMap.containsKey(tableName)) {
                        tablesColumnMap.put(tableName, loadColumn(tableMapEventData.getDatabase(), tableMapEventData.getTable()));
                    }
                }

                private void handleWriteRowsEvent(Event event) {
                    WriteRowsEventData eventData = event.getData();
                    TableMapEventData tableMapEvent = tablesById.get(eventData.getTableId());
                    if (!filter(tableMapEvent.getDatabase(), tableMapEvent.getTable()))
                        return;
                    Map<Integer, Map<String, Object>> xxx = tablesColumnMap.get(tableMapEvent.getDatabase() + "." + tableMapEvent.getTable());
                    BitSet inculudeColumn = eventData.getIncludedColumns();
                    MySqlInsertStatement mySqlInsertStatement = new MySqlInsertStatement();
                    mySqlInsertStatement.setTableName(new SQLIdentifierExpr("`" + tableMapEvent.getTable() + "`"));
                    mySqlInsertStatement.getTableSource().setSchema("`" + tableMapEvent.getDatabase() + "`");
                    SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
                    mySqlInsertStatement.setValues(values);
                    int size = inculudeColumn.length();
                    List<Serializable[]> rows = eventData.getRows();
                    for (int i = 0; i < size; i++) {
                        int column = inculudeColumn.nextSetBit(i);
                        Map<String, Object> coumnMap = xxx.get(column + 1);
                        Object column_name = coumnMap.get("COLUMN_NAME");
                        mySqlInsertStatement.addColumn(new SQLIdentifierExpr("`" + column_name + "`"));
                        values.addValue(new SQLVariantRefExpr("?"));
                    }
                    sqlInsert(mySqlInsertStatement.toString(), rows);
                }

                private void sqlInsert(String sql, List<Serializable[]> rows) {
                    for (Serializable[] row : rows) {
                        Object[] objects = new Object[row.length];
                        System.arraycopy(row, 0, objects, 0, row.length);
                        emitter.onNext(ParamSQL.of(sql, objects));
                    }
                }

                private void handleDeleteRowsEvent(Event event) {
                    DeleteRowsEventData eventData = event.getData();
                    EventHeader header = event.getHeader();
                    TableMapEventData tableMapEvent = tablesById.get(eventData.getTableId());
                    if (!filter(tableMapEvent.getDatabase(), tableMapEvent.getTable()))
                        return;
                    Map<Integer, Map<String, Object>> xxx = tablesColumnMap.get(tableMapEvent.getDatabase() + "." + tableMapEvent.getTable());
                    BitSet inculudeColumn = eventData.getIncludedColumns();
                    SQLBinaryOpExprGroup condition = getCondition(inculudeColumn, xxx);
                    int size = inculudeColumn.length();
                    List<Serializable[]> rows = eventData.getRows();
                    MySqlDeleteStatement mySqlDeleteStatement = new MySqlDeleteStatement();
                    mySqlDeleteStatement.setLimit(new SQLLimit(1));
                    SQLExprTableSource sqlExprTableSource = new SQLExprTableSource();
                    sqlExprTableSource.setExpr("`" + tableMapEvent.getTable() + "`");
                    sqlExprTableSource.setSchema("`" + tableMapEvent.getDatabase() + "`");
                    mySqlDeleteStatement.setTableSource(sqlExprTableSource);
                    mySqlDeleteStatement.addWhere(condition);
                    sqlDelete(mySqlDeleteStatement.toString(), rows);
                }

                private void sqlDelete(String mySqlDeleteStatement, List<Serializable[]> rows) {
                    for (Serializable[] row : rows) {
                        Object[] objects = new Object[row.length];
                        System.arraycopy(row, 0, objects, 0, row.length);
                        emitter.onNext(ParamSQL.of(mySqlDeleteStatement, objects));
                    }
                }
            });
            client.connect();
        }
    }, BackpressureStrategy.BUFFER);
}
Also used : Serializable(java.io.Serializable) ToString(groovy.transform.ToString) SQLStatement(com.alibaba.druid.sql.ast.SQLStatement) DatasourceConfig(io.mycat.config.DatasourceConfig) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) SQLDDLStatement(com.alibaba.druid.sql.ast.statement.SQLDDLStatement) SQLUpdateSetItem(com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem) MySqlSchemaStatVisitor(com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor) MySqlDeleteStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement) SQLVariantRefExpr(com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr) NameMap(io.mycat.util.NameMap) SQLException(java.sql.SQLException) SQLLimit(com.alibaba.druid.sql.ast.SQLLimit) TableStat(com.alibaba.druid.stat.TableStat) BinaryLogClient(com.github.shyiko.mysql.binlog.BinaryLogClient) MySqlUpdateStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement) SQLInsertStatement(com.alibaba.druid.sql.ast.statement.SQLInsertStatement) SQLBinaryOpExprGroup(com.alibaba.druid.sql.ast.expr.SQLBinaryOpExprGroup) Partition(io.mycat.Partition) Charset(java.nio.charset.Charset) SQLIdentifierExpr(com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr) NameMap(io.mycat.util.NameMap) MySqlInsertStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement) ConnectionUrlParser(com.mysql.cj.conf.ConnectionUrlParser) SQLException(java.sql.SQLException) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr) DefaultConnection(io.mycat.datasource.jdbc.datasource.DefaultConnection) SQLExprTableSource(com.alibaba.druid.sql.ast.statement.SQLExprTableSource) JdbcConnectionManager(io.mycat.datasource.jdbc.datasource.JdbcConnectionManager) HostInfo(com.mysql.cj.conf.HostInfo)

Example 15 with JdbcConnectionManager

use of io.mycat.datasource.jdbc.datasource.JdbcConnectionManager in project Mycat2 by MyCATApache.

the class MySQLLogConsumer method accept.

@Override
@SneakyThrows
public void accept(SqlEntry sqlEntry) {
    if (!init) {
        init = true;
        try {
            init();
        } catch (Exception e) {
            LOGGER.error("", e);
        }
    }
    boolean isInRuntime = MetaClusterCurrent.exist(IOExecutor.class) && MetaClusterCurrent.exist(JdbcConnectionManager.class) && MetaClusterCurrent.exist(IOExecutor.class);
    if (isInRuntime) {
        IOExecutor ioExecutor = MetaClusterCurrent.wrapper(IOExecutor.class);
        JdbcConnectionManager jdbcConnectionManager = MetaClusterCurrent.wrapper(JdbcConnectionManager.class);
        MetadataManager metadataManager = MetaClusterCurrent.wrapper(MetadataManager.class);
        ioExecutor.executeBlocking((Handler<Promise<Void>>) event -> {
            try {
                try (DefaultConnection connection = jdbcConnectionManager.getConnection(metadataManager.getPrototype())) {
                    JdbcUtils.execute(connection.getRawConnection(), "INSERT INTO `mycat`.`sql_log` (" + "`instanceId`," + "user," + "connectionId," + "ip," + "port," + "traceId," + "hash," + "sqlType," + "`sql`," + "transactionId," + "sqlTime," + "responseTime," + "affectRow," + "result," + "externalMessage)" + "values(?,?,?,?,?," + "?,?,?,?,?," + "?,?,?,?,?)", Arrays.asList(sqlEntry.getInstanceId(), sqlEntry.getUser(), sqlEntry.getConnectionId(), sqlEntry.getIp(), sqlEntry.getPort(), sqlEntry.getTraceId(), sqlEntry.getHash(), Objects.toString(sqlEntry.getSqlType()), sqlEntry.getSql(), sqlEntry.getTransactionId(), sqlEntry.getSqlTime(), sqlEntry.getResponseTime(), sqlEntry.getAffectRow(), sqlEntry.isResult(), sqlEntry.getExternalMessage()));
                }
            } catch (Exception e) {
                LOGGER.info(" warning sql:{} , info:{}", sqlEntry.getSql(), sqlEntry);
                LOGGER.error("", e);
            } finally {
                event.tryComplete();
            }
        });
    }
}
Also used : MetadataManager(io.mycat.MetadataManager) SqlEntry(io.mycat.monitor.SqlEntry) java.util(java.util) Logger(org.slf4j.Logger) Connection(java.sql.Connection) MetaClusterCurrent(io.mycat.MetaClusterCurrent) SneakyThrows(lombok.SneakyThrows) Promise(io.vertx.core.Promise) LoggerFactory(org.slf4j.LoggerFactory) DefaultConnection(io.mycat.datasource.jdbc.datasource.DefaultConnection) IOExecutor(io.mycat.IOExecutor) Consumer(java.util.function.Consumer) SQLException(java.sql.SQLException) JdbcConnectionManager(io.mycat.datasource.jdbc.datasource.JdbcConnectionManager) JdbcUtils(com.alibaba.druid.util.JdbcUtils) Handler(io.vertx.core.Handler) Promise(io.vertx.core.Promise) MetadataManager(io.mycat.MetadataManager) DefaultConnection(io.mycat.datasource.jdbc.datasource.DefaultConnection) IOExecutor(io.mycat.IOExecutor) JdbcConnectionManager(io.mycat.datasource.jdbc.datasource.JdbcConnectionManager) SQLException(java.sql.SQLException) SneakyThrows(lombok.SneakyThrows)

Aggregations

JdbcConnectionManager (io.mycat.datasource.jdbc.datasource.JdbcConnectionManager)57 DefaultConnection (io.mycat.datasource.jdbc.datasource.DefaultConnection)38 SneakyThrows (lombok.SneakyThrows)21 Connection (java.sql.Connection)16 ReplicaSelectorManager (io.mycat.replica.ReplicaSelectorManager)8 java.util (java.util)8 NotNull (org.jetbrains.annotations.NotNull)8 SQLExprTableSource (com.alibaba.druid.sql.ast.statement.SQLExprTableSource)7 DatasourceConfig (io.mycat.config.DatasourceConfig)7 JdbcDataSource (io.mycat.datasource.jdbc.datasource.JdbcDataSource)7 Collectors (java.util.stream.Collectors)7 MetadataManager (io.mycat.MetadataManager)6 RowBaseIterator (io.mycat.api.collector.RowBaseIterator)6 NameMap (io.mycat.util.NameMap)6 SQLStatement (com.alibaba.druid.sql.ast.SQLStatement)5 SQLIdentifierExpr (com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr)5 MycatRowMetaData (io.mycat.beans.mycat.MycatRowMetaData)5 SQLException (java.sql.SQLException)5 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)5 Logger (org.slf4j.Logger)5