Search in sources :

Example 41 with MySQLMessage

use of io.mycat.backend.mysql.MySQLMessage in project Mycat_plus by coderczp.

the class DataNodeMergeManager method run.

@Override
public void run() {
    if (!running.compareAndSet(false, true)) {
        return;
    }
    boolean nulpack = false;
    try {
        for (; ; ) {
            final PackWraper pack = packs.poll();
            if (pack == null) {
                nulpack = true;
                break;
            }
            if (pack == END_FLAG_PACK) {
                hasEndFlag = true;
                if (packs.peek() != null) {
                    packs.add(pack);
                    continue;
                }
                /**
                 * 最后一个节点datenode发送了row eof packet说明了整个
                 * 分片数据全部接收完成,进而将结果集全部发给你Mycat 客户端
                 */
                final int warningCount = 0;
                final EOFPacket eofp = new EOFPacket();
                final ByteBuffer eof = ByteBuffer.allocate(9);
                BufferUtil.writeUB3(eof, eofp.calcPacketSize());
                eof.put(eofp.packetId);
                eof.put(eofp.fieldCount);
                BufferUtil.writeUB2(eof, warningCount);
                BufferUtil.writeUB2(eof, eofp.status);
                final ServerConnection source = multiQueryHandler.getSession().getSource();
                final byte[] array = eof.array();
                Iterator<UnsafeRow> iters = null;
                if (unsafeRowGrouper != null) {
                    /**
                     * group by里面需要排序情况
                     */
                    if (globalSorter != null) {
                        iters = unsafeRowGrouper.getResult(globalSorter);
                    } else {
                        iters = unsafeRowGrouper.getResult(globalMergeResult);
                    }
                } else if (globalSorter != null) {
                    iters = globalSorter.sort();
                } else if (!isStreamOutputResult) {
                    iters = globalMergeResult.sort();
                }
                if (iters != null) {
                    multiQueryHandler.outputMergeResult(source, array, iters, isMiddleResultDone);
                }
                break;
            }
            unsafeRow = new UnsafeRow(fieldCount);
            bufferHolder = new BufferHolder(unsafeRow, 0);
            unsafeRowWriter = new UnsafeRowWriter(bufferHolder, fieldCount);
            bufferHolder.reset();
            /**
             *构造一行row,将对应的col填充.
             */
            MySQLMessage mm = new MySQLMessage(pack.rowData);
            mm.readUB3();
            mm.read();
            int nullnum = 0;
            for (int i = 0; i < fieldCount; i++) {
                byte[] colValue = mm.readBytesWithLength();
                if (colValue != null)
                    unsafeRowWriter.write(i, colValue);
                else {
                    if (mergeColsIndex != null && mergeColsIndex.length > 0) {
                        if (Arrays.binarySearch(mergeColsIndex, i) < 0) {
                            nullnum++;
                        }
                    }
                    unsafeRow.setNullAt(i);
                }
            }
            if (mergeColsIndex != null && mergeColsIndex.length > 0) {
                if (nullnum == (fieldCount - mergeColsIndex.length)) {
                    if (!hasEndFlag) {
                        packs.add(pack);
                        continue;
                    }
                }
            }
            unsafeRow.setTotalSize(bufferHolder.totalSize());
            if (unsafeRowGrouper != null) {
                unsafeRowGrouper.addRow(unsafeRow);
            } else if (globalSorter != null) {
                globalSorter.insertRow(unsafeRow);
            } else {
                globalMergeResult.insertRow(unsafeRow);
            }
            unsafeRow = null;
            bufferHolder = null;
            unsafeRowWriter = null;
        }
    } catch (final Exception e) {
        e.printStackTrace();
        multiQueryHandler.handleDataProcessException(e);
    } finally {
        running.set(false);
        if (nulpack && !packs.isEmpty()) {
            this.run();
        }
    }
}
Also used : EOFPacket(io.mycat.net.mysql.EOFPacket) ServerConnection(io.mycat.server.ServerConnection) UnsafeRowWriter(io.mycat.memory.unsafe.row.UnsafeRowWriter) ByteBuffer(java.nio.ByteBuffer) UnsafeRow(io.mycat.memory.unsafe.row.UnsafeRow) BufferHolder(io.mycat.memory.unsafe.row.BufferHolder) IOException(java.io.IOException) MySQLMessage(io.mycat.backend.mysql.MySQLMessage)

Example 42 with MySQLMessage

use of io.mycat.backend.mysql.MySQLMessage in project Mycat_plus by coderczp.

the class CompressUtil method decompressMysqlPacket.

/**
 * 解压数据包,同时做分包处理
 *
 * @param data
 * @param decompressUnfinishedDataQueue
 * @return
 */
public static List<byte[]> decompressMysqlPacket(byte[] data, ConcurrentLinkedQueue<byte[]> decompressUnfinishedDataQueue) {
    MySQLMessage msg = new MySQLMessage(data);
    // 包头
    // -----------------------------------------
    // 压缩的包长
    int packetLength = msg.readUB3();
    // 压缩的包号
    byte packetId = msg.read();
    // 压缩前的长度
    int oldLen = msg.readUB3();
    // 未压缩, 直接返回
    if (packetLength == data.length - 4) {
        return Lists.newArrayList(data);
    // 压缩不成功的, 直接返回
    } else if (oldLen == 0) {
        byte[] readBytes = msg.readBytes();
        return splitPack(readBytes, decompressUnfinishedDataQueue);
    // 解压
    } else {
        byte[] de = decompress(data, 7, data.length - 7);
        return splitPack(de, decompressUnfinishedDataQueue);
    }
}
Also used : MySQLMessage(io.mycat.backend.mysql.MySQLMessage)

Example 43 with MySQLMessage

use of io.mycat.backend.mysql.MySQLMessage in project Mycat_plus by coderczp.

the class CompressUtil method compressMysqlPacket.

/**
 * 压缩数据包
 * @param data
 * @param con
 * @param compressUnfinishedDataQueue
 * @return
 */
private static ByteBuffer compressMysqlPacket(byte[] data, AbstractConnection con, ConcurrentLinkedQueue<byte[]> compressUnfinishedDataQueue) {
    ByteBuffer byteBuf = con.allocate();
    // TODO: 数据量大的时候, 此处是是性能的堵点
    byteBuf = con.checkWriteBuffer(byteBuf, data.length, false);
    MySQLMessage msg = new MySQLMessage(data);
    while (msg.hasRemaining()) {
        // 包体的长度
        int packetLength = 0;
        // 可读的长度
        int readLength = msg.length() - msg.position();
        if (readLength > 3) {
            packetLength = msg.readUB3();
            msg.move(-3);
        }
        // 校验数据包完整性
        if (readLength < packetLength + 4) {
            byte[] packet = msg.readBytes(readLength);
            if (packet.length != 0) {
                // 不完整的包
                compressUnfinishedDataQueue.add(packet);
            }
        } else {
            byte[] packet = msg.readBytes(packetLength + 4);
            if (packet.length != 0) {
                if (packet.length <= NO_COMPRESS_PACKET_LENGTH) {
                    // 压缩长度
                    BufferUtil.writeUB3(byteBuf, packet.length);
                    // 压缩序号
                    byteBuf.put(packet[3]);
                    // 压缩前的长度设置为0
                    BufferUtil.writeUB3(byteBuf, 0);
                    // 包体
                    byteBuf.put(packet);
                } else {
                    // 压缩
                    byte[] compress = compress(packet);
                    BufferUtil.writeUB3(byteBuf, compress.length);
                    byteBuf.put(packet[3]);
                    BufferUtil.writeUB3(byteBuf, packet.length);
                    byteBuf.put(compress);
                }
            }
        }
    }
    return byteBuf;
}
Also used : ByteBuffer(java.nio.ByteBuffer) MySQLMessage(io.mycat.backend.mysql.MySQLMessage)

Example 44 with MySQLMessage

use of io.mycat.backend.mysql.MySQLMessage in project Mycat-Server by MyCATApache.

the class CommandPacket method read.

public void read(byte[] data) {
    MySQLMessage mm = new MySQLMessage(data);
    packetLength = mm.readUB3();
    packetId = mm.read();
    command = mm.read();
    arg = mm.readBytes();
}
Also used : MySQLMessage(io.mycat.backend.mysql.MySQLMessage)

Example 45 with MySQLMessage

use of io.mycat.backend.mysql.MySQLMessage in project Mycat-Server by MyCATApache.

the class HandshakePacket method read.

public void read(byte[] data) {
    MySQLMessage mm = new MySQLMessage(data);
    packetLength = mm.readUB3();
    packetId = mm.read();
    protocolVersion = mm.read();
    serverVersion = mm.readBytesWithNull();
    threadId = mm.readUB4();
    seed = mm.readBytesWithNull();
    serverCapabilities = mm.readUB2();
    serverCharsetIndex = mm.read();
    serverStatus = mm.readUB2();
    mm.move(13);
    restOfScrambleBuff = mm.readBytesWithNull();
}
Also used : MySQLMessage(io.mycat.backend.mysql.MySQLMessage)

Aggregations

MySQLMessage (io.mycat.backend.mysql.MySQLMessage)56 Test (org.junit.Test)6 UnsupportedEncodingException (java.io.UnsupportedEncodingException)4 ByteBuffer (java.nio.ByteBuffer)4 BindValue (io.mycat.backend.mysql.BindValue)2 BufferHolder (io.mycat.memory.unsafe.row.BufferHolder)2 UnsafeRow (io.mycat.memory.unsafe.row.UnsafeRow)2 UnsafeRowWriter (io.mycat.memory.unsafe.row.UnsafeRowWriter)2 EOFPacket (io.mycat.net.mysql.EOFPacket)2 ServerConnection (io.mycat.server.ServerConnection)2 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2