Search in sources :

Example 6 with ServerConnection

use of io.mycat.server.ServerConnection in project Mycat-Server by MyCATApache.

the class EngineCtx method writeHeader.

public void writeHeader(List<byte[]> afields) {
    if (headerWrited.compareAndSet(false, true)) {
        try {
            writeLock.lock();
            // write new header
            ResultSetHeaderPacket headerPkg = new ResultSetHeaderPacket();
            // -1;
            headerPkg.fieldCount = afields.size();
            headerPkg.packetId = incPackageId();
            LOGGER.debug("packge id " + headerPkg.packetId);
            ServerConnection sc = session.getSource();
            ByteBuffer buf = headerPkg.write(sc.allocate(), sc, true);
            // wirte a fields
            for (byte[] field : afields) {
                field[3] = incPackageId();
                buf = sc.writeToBuffer(field, buf);
            }
            // write field eof
            EOFPacket eofPckg = new EOFPacket();
            eofPckg.packetId = incPackageId();
            buf = eofPckg.write(buf, sc, true);
            sc.write(buf);
        //LOGGER.info("header outputed ,packgId:" + eofPckg.packetId);
        } finally {
            writeLock.unlock();
        }
    }
}
Also used : ResultSetHeaderPacket(io.mycat.net.mysql.ResultSetHeaderPacket) EOFPacket(io.mycat.net.mysql.EOFPacket) ServerConnection(io.mycat.server.ServerConnection) ByteBuffer(java.nio.ByteBuffer)

Example 7 with ServerConnection

use of io.mycat.server.ServerConnection in project Mycat-Server by MyCATApache.

the class CommitNodeHandler method okResponse.

@Override
public void okResponse(byte[] ok, BackendConnection conn) {
    if (conn instanceof MySQLConnection) {
        MySQLConnection mysqlCon = (MySQLConnection) conn;
        switch(mysqlCon.getXaStatus()) {
            case 1:
                if (mysqlCon.batchCmdFinished()) {
                    String xaTxId = session.getXaTXID();
                    mysqlCon.execCmd("XA COMMIT " + xaTxId);
                    mysqlCon.setXaStatus(TxState.TX_PREPARED_STATE);
                }
                return;
            case 2:
                {
                    mysqlCon.setXaStatus(TxState.TX_INITIALIZE_STATE);
                    break;
                }
            default:
        }
    }
    session.clearResources(false);
    ServerConnection source = session.getSource();
    source.write(ok);
}
Also used : ServerConnection(io.mycat.server.ServerConnection) MySQLConnection(io.mycat.backend.mysql.nio.MySQLConnection)

Example 8 with ServerConnection

use of io.mycat.server.ServerConnection in project Mycat-Server by MyCATApache.

the class MultiNodeQueryHandler method rowEofResponse.

@Override
public void rowEofResponse(final byte[] eof, BackendConnection conn) {
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("on row end reseponse " + conn);
    }
    this.netOutBytes += eof.length;
    if (errorRepsponsed.get()) {
        // conn.close(this.error);
        return;
    }
    final ServerConnection source = session.getSource();
    if (!isCallProcedure) {
        if (clearIfSessionClosed(session)) {
            return;
        } else if (canClose(conn, false)) {
            return;
        }
    }
    if (decrementCountBy(1)) {
        if (!rrs.isCallStatement() || (rrs.isCallStatement() && rrs.getProcedure().isResultSimpleValue())) {
            if (this.autocommit && !session.getSource().isLocked()) {
                // clear all connections
                session.releaseConnections(false);
            }
            if (this.isFail() || session.closed()) {
                tryErrorFinished(true);
                return;
            }
        }
        if (dataMergeSvr != null) {
            try {
                dataMergeSvr.outputMergeResult(session, eof);
            } catch (Exception e) {
                handleDataProcessException(e);
            }
        } else {
            try {
                lock.lock();
                eof[3] = ++packetId;
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("last packet id:" + packetId);
                }
                source.write(eof);
            } finally {
                lock.unlock();
            }
        }
    }
    execCount++;
    if (execCount == rrs.getNodes().length) {
        int resultSize = source.getWriteQueue().size() * MycatServer.getInstance().getConfig().getSystem().getBufferPoolPageSize();
        //TODO: add by zhuam
        //查询结果派发
        QueryResult queryResult = new QueryResult(session.getSource().getUser(), rrs.getSqlType(), rrs.getStatement(), selectRows, netInBytes, netOutBytes, startTime, System.currentTimeMillis(), resultSize);
        QueryResultDispatcher.dispatchQuery(queryResult);
    }
}
Also used : QueryResult(io.mycat.statistic.stat.QueryResult) ServerConnection(io.mycat.server.ServerConnection)

Example 9 with ServerConnection

use of io.mycat.server.ServerConnection in project Mycat-Server by MyCATApache.

the class MultiNodeQueryHandler method fieldEofResponse.

@Override
public void fieldEofResponse(byte[] header, List<byte[]> fields, byte[] eof, BackendConnection conn) {
    this.netOutBytes += header.length;
    this.netOutBytes += eof.length;
    for (int i = 0, len = fields.size(); i < len; ++i) {
        byte[] field = fields.get(i);
        this.netOutBytes += field.length;
    }
    ServerConnection source = null;
    if (fieldsReturned) {
        return;
    }
    lock.lock();
    try {
        if (fieldsReturned) {
            return;
        }
        fieldsReturned = true;
        boolean needMerg = (dataMergeSvr != null) && dataMergeSvr.getRrs().needMerge();
        Set<String> shouldRemoveAvgField = new HashSet<>();
        Set<String> shouldRenameAvgField = new HashSet<>();
        if (needMerg) {
            Map<String, Integer> mergeColsMap = dataMergeSvr.getRrs().getMergeCols();
            if (mergeColsMap != null) {
                for (Map.Entry<String, Integer> entry : mergeColsMap.entrySet()) {
                    String key = entry.getKey();
                    int mergeType = entry.getValue();
                    if (MergeCol.MERGE_AVG == mergeType && mergeColsMap.containsKey(key + "SUM")) {
                        shouldRemoveAvgField.add((key + "COUNT").toUpperCase());
                        shouldRenameAvgField.add((key + "SUM").toUpperCase());
                    }
                }
            }
        }
        source = session.getSource();
        ByteBuffer buffer = source.allocate();
        fieldCount = fields.size();
        if (shouldRemoveAvgField.size() > 0) {
            ResultSetHeaderPacket packet = new ResultSetHeaderPacket();
            packet.packetId = ++packetId;
            packet.fieldCount = fieldCount - shouldRemoveAvgField.size();
            buffer = packet.write(buffer, source, true);
        } else {
            header[3] = ++packetId;
            buffer = source.writeToBuffer(header, buffer);
        }
        String primaryKey = null;
        if (rrs.hasPrimaryKeyToCache()) {
            String[] items = rrs.getPrimaryKeyItems();
            priamaryKeyTable = items[0];
            primaryKey = items[1];
        }
        Map<String, ColMeta> columToIndx = new HashMap<String, ColMeta>(fieldCount);
        for (int i = 0, len = fieldCount; i < len; ++i) {
            boolean shouldSkip = false;
            byte[] field = fields.get(i);
            if (needMerg) {
                FieldPacket fieldPkg = new FieldPacket();
                fieldPkg.read(field);
                fieldPackets.add(fieldPkg);
                String fieldName = new String(fieldPkg.name).toUpperCase();
                if (columToIndx != null && !columToIndx.containsKey(fieldName)) {
                    if (shouldRemoveAvgField.contains(fieldName)) {
                        shouldSkip = true;
                        fieldPackets.remove(fieldPackets.size() - 1);
                    }
                    if (shouldRenameAvgField.contains(fieldName)) {
                        String newFieldName = fieldName.substring(0, fieldName.length() - 3);
                        fieldPkg.name = newFieldName.getBytes();
                        fieldPkg.packetId = ++packetId;
                        shouldSkip = true;
                        // 处理AVG字段位数和精度, AVG位数 = SUM位数 - 14
                        fieldPkg.length = fieldPkg.length - 14;
                        // AVG精度 = SUM精度 + 4
                        fieldPkg.decimals = (byte) (fieldPkg.decimals + 4);
                        buffer = fieldPkg.write(buffer, source, false);
                        // 还原精度
                        fieldPkg.decimals = (byte) (fieldPkg.decimals - 4);
                    }
                    ColMeta colMeta = new ColMeta(i, fieldPkg.type);
                    colMeta.decimals = fieldPkg.decimals;
                    columToIndx.put(fieldName, colMeta);
                }
            } else {
                FieldPacket fieldPkg = new FieldPacket();
                fieldPkg.read(field);
                fieldPackets.add(fieldPkg);
                fieldCount = fields.size();
                if (primaryKey != null && primaryKeyIndex == -1) {
                    // find primary key index
                    String fieldName = new String(fieldPkg.name);
                    if (primaryKey.equalsIgnoreCase(fieldName)) {
                        primaryKeyIndex = i;
                    }
                }
            }
            if (!shouldSkip) {
                field[3] = ++packetId;
                buffer = source.writeToBuffer(field, buffer);
            }
        }
        eof[3] = ++packetId;
        buffer = source.writeToBuffer(eof, buffer);
        source.write(buffer);
        if (dataMergeSvr != null) {
            dataMergeSvr.onRowMetaData(columToIndx, fieldCount);
        }
    } catch (Exception e) {
        handleDataProcessException(e);
    } finally {
        lock.unlock();
    }
}
Also used : ServerConnection(io.mycat.server.ServerConnection) ByteBuffer(java.nio.ByteBuffer)

Example 10 with ServerConnection

use of io.mycat.server.ServerConnection in project Mycat-Server by MyCATApache.

the class MultiNodeQueryHandler method okResponse.

@Override
public void okResponse(byte[] data, BackendConnection conn) {
    this.netOutBytes += data.length;
    boolean executeResponse = conn.syncAndExcute();
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("received ok response ,executeResponse:" + executeResponse + " from " + conn);
    }
    if (executeResponse) {
        ServerConnection source = session.getSource();
        OkPacket ok = new OkPacket();
        ok.read(data);
        //存储过程
        boolean isCanClose2Client = (!rrs.isCallStatement()) || (rrs.isCallStatement() && !rrs.getProcedure().isResultSimpleValue());
        ;
        if (!isCallProcedure) {
            if (clearIfSessionClosed(session)) {
                return;
            } else if (canClose(conn, false)) {
                return;
            }
        }
        lock.lock();
        try {
            // 判断是否是全局表,如果是,执行行数不做累加,以最后一次执行的为准。
            if (!rrs.isGlobalTable()) {
                affectedRows += ok.affectedRows;
            } else {
                affectedRows = ok.affectedRows;
            }
            if (ok.insertId > 0) {
                insertId = (insertId == 0) ? ok.insertId : Math.min(insertId, ok.insertId);
            }
        } finally {
            lock.unlock();
        }
        // 对于存储过程,其比较特殊,查询结果返回EndRow报文以后,还会再返回一个OK报文,才算结束
        boolean isEndPacket = isCallProcedure ? decrementOkCountBy(1) : decrementCountBy(1);
        if (isEndPacket && isCanClose2Client) {
            if (this.autocommit && !session.getSource().isLocked()) {
                // clear all connections
                session.releaseConnections(false);
            }
            if (this.isFail() || session.closed()) {
                tryErrorFinished(true);
                return;
            }
            lock.lock();
            try {
                if (rrs.isLoadData()) {
                    byte lastPackId = source.getLoadDataInfileHandler().getLastPackId();
                    // OK_PACKET
                    ok.packetId = ++lastPackId;
                    ok.message = ("Records: " + affectedRows + "  Deleted: 0  Skipped: 0  Warnings: 0").getBytes();
                    source.getLoadDataInfileHandler().clear();
                } else {
                    // OK_PACKET
                    ok.packetId = ++packetId;
                }
                ok.affectedRows = affectedRows;
                ok.serverStatus = source.isAutocommit() ? 2 : 1;
                if (insertId > 0) {
                    ok.insertId = insertId;
                    source.setLastInsertId(insertId);
                }
                ok.write(source);
            } catch (Exception e) {
                handleDataProcessException(e);
            } finally {
                lock.unlock();
            }
        }
        // add by lian
        // 解决sql统计中写操作永远为0
        execCount++;
        if (execCount == rrs.getNodes().length) {
            QueryResult queryResult = new QueryResult(session.getSource().getUser(), rrs.getSqlType(), rrs.getStatement(), selectRows, netInBytes, netOutBytes, startTime, System.currentTimeMillis(), 0);
            QueryResultDispatcher.dispatchQuery(queryResult);
        }
    }
}
Also used : QueryResult(io.mycat.statistic.stat.QueryResult) ServerConnection(io.mycat.server.ServerConnection)

Aggregations

ServerConnection (io.mycat.server.ServerConnection)17 ByteBuffer (java.nio.ByteBuffer)8 EOFPacket (io.mycat.net.mysql.EOFPacket)5 RowDataPacket (io.mycat.net.mysql.RowDataPacket)4 QueryResult (io.mycat.statistic.stat.QueryResult)4 FieldPacket (io.mycat.net.mysql.FieldPacket)2 BackendConnection (io.mycat.backend.BackendConnection)1 PhysicalDBNode (io.mycat.backend.datasource.PhysicalDBNode)1 MySQLMessage (io.mycat.backend.mysql.MySQLMessage)1 MySQLConnection (io.mycat.backend.mysql.nio.MySQLConnection)1 MycatConfig (io.mycat.config.MycatConfig)1 BufferHolder (io.mycat.memory.unsafe.row.BufferHolder)1 UnsafeRow (io.mycat.memory.unsafe.row.UnsafeRow)1 UnsafeRowWriter (io.mycat.memory.unsafe.row.UnsafeRowWriter)1 FrontendConnection (io.mycat.net.FrontendConnection)1 NIOProcessor (io.mycat.net.NIOProcessor)1 BinaryRowDataPacket (io.mycat.net.mysql.BinaryRowDataPacket)1 ErrorPacket (io.mycat.net.mysql.ErrorPacket)1 OkPacket (io.mycat.net.mysql.OkPacket)1 ResultSetHeaderPacket (io.mycat.net.mysql.ResultSetHeaderPacket)1