Search in sources :

Example 6 with ServerConnection

use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.

the class RollbackExecutor method _rollback.

private void _rollback(MySQLChannel mc, BlockingSession session) {
    final ServerConnection source = session.getSource();
    if (isFail.get() || source.isClosed()) {
        mc.setRunning(false);
        try {
            throw new Exception("other task fails, rollback failed channel");
        } catch (Exception e) {
            handleException(mc, session, e);
        }
        return;
    }
    try {
        BinaryPacket bin = mc.rollback();
        switch(bin.data[0]) {
            case OkPacket.FIELD_COUNT:
                mc.setRunning(false);
                if (decrementCountBy(1)) {
                    try {
                        if (isFail.get()) {
                            // some other tasks failed
                            session.clear();
                            source.writeErrMessage(ErrorCode.ER_YES, "rollback error!");
                        } else {
                            // all tasks are successful
                            session.release();
                            ByteBuffer buffer = source.allocate();
                            source.write(bin.write(buffer, source));
                        }
                    } catch (Exception e) {
                        LOGGER.warn("exception happens in success notification: " + source, e);
                    }
                }
                break;
            case ErrorPacket.FIELD_COUNT:
                isFail.set(true);
                if (decrementCountBy(1)) {
                    try {
                        session.clear();
                        LOGGER.warn(mc.getErrLog("rollback", mc.getErrMessage(bin), source));
                        ByteBuffer buffer = source.allocate();
                        source.write(bin.write(buffer, source));
                    } catch (Exception e) {
                        LOGGER.warn("exception happens in failure notification: " + source, e);
                    }
                }
                break;
            default:
                throw new UnknownPacketException(bin.toString());
        }
    } catch (IOException e) {
        mc.close();
        handleException(mc, session, e);
    } catch (RuntimeException e) {
        mc.close();
        handleException(mc, session, e);
    }
}
Also used : UnknownPacketException(com.alibaba.cobar.exception.UnknownPacketException) ServerConnection(com.alibaba.cobar.server.ServerConnection) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) IOException(java.io.IOException) UnknownPacketException(com.alibaba.cobar.exception.UnknownPacketException) BinaryPacket(com.alibaba.cobar.net.mysql.BinaryPacket)

Example 7 with ServerConnection

use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.

the class RollbackExecutor method rollback.

/**
 * 事务回滚
 */
public void rollback(final BlockingSession session) {
    final ServerConnection source = session.getSource();
    final ConcurrentMap<RouteResultsetNode, Channel> target = session.getTarget();
    final int initNodeCount = target.size();
    if (initNodeCount <= 0) {
        ByteBuffer buffer = source.allocate();
        source.write(source.writeToBuffer(OkPacket.OK, buffer));
        return;
    }
    // 初始化
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        this.isFail.set(false);
        this.nodeCount = initNodeCount;
    } finally {
        lock.unlock();
    }
    if (source.isClosed()) {
        decrementCountToZero();
        return;
    }
    // 执行
    Executor committer = source.getProcessor().getCommitter();
    int started = 0;
    for (RouteResultsetNode rrn : target.keySet()) {
        final MySQLChannel mc = (MySQLChannel) target.get(rrn);
        if (mc != null) {
            mc.setRunning(true);
            committer.execute(new Runnable() {

                @Override
                public void run() {
                    _rollback(mc, session);
                }
            });
            ++started;
        }
    }
    if (started < initNodeCount) {
        decrementCountBy(initNodeCount - started);
    }
}
Also used : ReentrantLock(java.util.concurrent.locks.ReentrantLock) Executor(java.util.concurrent.Executor) RouteResultsetNode(com.alibaba.cobar.route.RouteResultsetNode) MySQLChannel(com.alibaba.cobar.mysql.bio.MySQLChannel) Channel(com.alibaba.cobar.mysql.bio.Channel) ServerConnection(com.alibaba.cobar.server.ServerConnection) MySQLChannel(com.alibaba.cobar.mysql.bio.MySQLChannel) ByteBuffer(java.nio.ByteBuffer)

Example 8 with ServerConnection

use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.

the class SingleNodeExecutor method newExecute.

/**
 * 新数据通道的执行
 */
private void newExecute(final RouteResultsetNode rrn, final BlockingSession ss, final int flag) {
    final ServerConnection sc = ss.getSource();
    // 检查数据节点是否存在
    CobarConfig conf = CobarServer.getInstance().getConfig();
    final MySQLDataNode dn = conf.getDataNodes().get(rrn.getName());
    if (dn == null) {
        LOGGER.warn(new StringBuilder().append(sc).append(rrn).toString(), new UnknownDataNodeException());
        handleError(ErrorCode.ER_BAD_DB_ERROR, "Unknown dataNode '" + rrn.getName() + "'", ss);
        return;
    }
    // 提交执行任务
    sc.getProcessor().getExecutor().execute(new Runnable() {

        @Override
        public void run() {
            // 取得数据通道
            int i = rrn.getReplicaIndex();
            Channel c = null;
            try {
                c = (i == DEFAULT_REPLICA_INDEX) ? dn.getChannel() : dn.getChannel(i);
            } catch (Exception e) {
                LOGGER.warn(new StringBuilder().append(sc).append(rrn).toString(), e);
                String msg = e.getMessage();
                handleError(ErrorCode.ER_BAD_DB_ERROR, msg == null ? e.getClass().getSimpleName() : msg, ss);
                return;
            }
            // 检查连接是否已关闭。
            if (sc.isClosed()) {
                c.release();
                endRunning();
                return;
            }
            // 绑定数据通道
            c.setRunning(true);
            Channel old = ss.getTarget().put(rrn, c);
            if (old != null && old != c) {
                old.close();
            }
            // 执行
            execute0(rrn, ss, c, flag);
        }
    });
}
Also used : MySQLDataNode(com.alibaba.cobar.mysql.MySQLDataNode) UnknownDataNodeException(com.alibaba.cobar.exception.UnknownDataNodeException) MySQLChannel(com.alibaba.cobar.mysql.bio.MySQLChannel) Channel(com.alibaba.cobar.mysql.bio.Channel) ServerConnection(com.alibaba.cobar.server.ServerConnection) CobarConfig(com.alibaba.cobar.CobarConfig) UnknownDataNodeException(com.alibaba.cobar.exception.UnknownDataNodeException) IOException(java.io.IOException)

Example 9 with ServerConnection

use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.

the class SingleNodeExecutor method handleNext.

/**
 * 下一个数据接收任务
 */
private void handleNext(final RouteResultsetNode rrn, final BlockingSession ss, final MySQLChannel mc, final ByteBuffer bb, final byte id) {
    final ServerConnection sc = ss.getSource();
    sc.getProcessor().getExecutor().execute(new Runnable() {

        @Override
        public void run() {
            try {
                handleRowData(rrn, ss, mc, bb, id);
            } catch (IOException e) {
                LOGGER.warn(new StringBuilder().append(sc).append(rrn).toString(), e);
                mc.close();
                String msg = e.getMessage();
                handleError(ErrorCode.ER_YES, msg == null ? e.getClass().getSimpleName() : msg, ss);
            } catch (RuntimeException e) {
                LOGGER.warn(new StringBuilder().append(sc).append(rrn).toString(), e);
                mc.close();
                String msg = e.getMessage();
                handleError(ErrorCode.ER_YES, msg == null ? e.getClass().getSimpleName() : msg, ss);
            }
        }
    });
}
Also used : ServerConnection(com.alibaba.cobar.server.ServerConnection) IOException(java.io.IOException)

Example 10 with ServerConnection

use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.

the class SingleNodeExecutor method handleResultSet.

/**
 * 处理结果集数据
 */
private void handleResultSet(RouteResultsetNode rrn, BlockingSession ss, MySQLChannel mc, BinaryPacket bin, int flag) throws IOException {
    final ServerConnection sc = ss.getSource();
    // HEADER
    bin.packetId = ++packetId;
    List<MySQLPacket> headerList = new LinkedList<MySQLPacket>();
    headerList.add(bin);
    for (; ; ) {
        bin = mc.receive();
        switch(bin.data[0]) {
            case ErrorPacket.FIELD_COUNT:
                {
                    LOGGER.warn(mc.getErrLog(rrn.getStatement(), mc.getErrMessage(bin), sc));
                    mc.setRunning(false);
                    if (mc.isAutocommit()) {
                        ss.clear();
                    }
                    endRunning();
                    // ERROR_PACKET
                    bin.packetId = ++packetId;
                    sc.write(bin.write(sc.allocate(), sc));
                    return;
                }
            case EOFPacket.FIELD_COUNT:
                {
                    // FIELD_EOF
                    bin.packetId = ++packetId;
                    ByteBuffer bb = sc.allocate();
                    for (MySQLPacket packet : headerList) {
                        bb = packet.write(bb, sc);
                    }
                    bb = bin.write(bb, sc);
                    headerList = null;
                    handleRowData(rrn, ss, mc, bb, packetId);
                    return;
                }
            default:
                // FIELDS
                bin.packetId = ++packetId;
                switch(flag) {
                    case RouteResultset.REWRITE_FIELD:
                        StringBuilder fieldName = new StringBuilder();
                        fieldName.append("Tables_in_").append(ss.getSource().getSchema());
                        FieldPacket field = PacketUtil.getField(bin, fieldName.toString());
                        headerList.add(field);
                        break;
                    default:
                        headerList.add(bin);
                }
        }
    }
}
Also used : MySQLPacket(com.alibaba.cobar.net.mysql.MySQLPacket) ServerConnection(com.alibaba.cobar.server.ServerConnection) ByteBuffer(java.nio.ByteBuffer) FieldPacket(com.alibaba.cobar.net.mysql.FieldPacket) LinkedList(java.util.LinkedList)

Aggregations

ServerConnection (com.alibaba.cobar.server.ServerConnection)29 IOException (java.io.IOException)16 BinaryPacket (com.alibaba.cobar.net.mysql.BinaryPacket)6 UnknownDataNodeException (com.alibaba.cobar.exception.UnknownDataNodeException)5 MySQLChannel (com.alibaba.cobar.mysql.bio.MySQLChannel)5 ByteBuffer (java.nio.ByteBuffer)5 UnknownPacketException (com.alibaba.cobar.exception.UnknownPacketException)4 ErrorPacket (com.alibaba.cobar.net.mysql.ErrorPacket)4 Channel (com.alibaba.cobar.mysql.bio.Channel)3 OkPacket (com.alibaba.cobar.net.mysql.OkPacket)3 RouteResultsetNode (com.alibaba.cobar.route.RouteResultsetNode)3 UnsupportedEncodingException (java.io.UnsupportedEncodingException)3 ReentrantLock (java.util.concurrent.locks.ReentrantLock)3 CobarConfig (com.alibaba.cobar.CobarConfig)2 MySQLDataNode (com.alibaba.cobar.mysql.MySQLDataNode)2 FieldPacket (com.alibaba.cobar.net.mysql.FieldPacket)2 MySQLPacket (com.alibaba.cobar.net.mysql.MySQLPacket)2 LinkedList (java.util.LinkedList)2 FrontendConnection (com.alibaba.cobar.net.FrontendConnection)1 NIOProcessor (com.alibaba.cobar.net.NIOProcessor)1