use of io.mycat.server.ServerConnection in project Mycat-Server by MyCATApache.
the class ShowConnectionSQL method execute.
public static void execute(ManagerConnection c) {
ByteBuffer buffer = c.allocate();
// write header
buffer = header.write(buffer, c, true);
// write fields
for (FieldPacket field : fields) {
buffer = field.write(buffer, c, true);
}
// write eof
buffer = eof.write(buffer, c, true);
// write rows
byte packetId = eof.packetId;
String charset = c.getCharset();
for (NIOProcessor p : MycatServer.getInstance().getProcessors()) {
for (FrontendConnection fc : p.getFrontends().values()) {
if (!fc.isClosed()) {
if (fc.getExecuteSql() == null) {
continue;
}
if (fc instanceof ServerConnection) {
RowDataPacket row = getRow(fc, charset);
row.packetId = ++packetId;
buffer = row.write(buffer, c, true);
}
}
}
}
// write last eof
EOFPacket lastEof = new EOFPacket();
lastEof.packetId = ++packetId;
buffer = lastEof.write(buffer, c, true);
// write buffer
c.write(buffer);
}
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 TxState.TX_STARTED_STATE:
if (mysqlCon.batchCmdFinished()) {
String xaTxId = session.getXaTXID() + ",'" + mysqlCon.getSchema() + "'";
mysqlCon.execCmd("XA COMMIT " + xaTxId);
mysqlCon.setXaStatus(TxState.TX_PREPARED_STATE);
}
return;
case TxState.TX_PREPARED_STATE:
{
mysqlCon.setXaStatus(TxState.TX_INITIALIZE_STATE);
break;
}
default:
}
/* 1. 事务提交后,xa 事务结束 */
if (TxState.TX_INITIALIZE_STATE == mysqlCon.getXaStatus()) {
if (session.getXaTXID() != null) {
session.setXATXEnabled(false);
}
}
}
/* 2. preAcStates 为true,事务结束后,需要设置为true。preAcStates 为ac上一个状态 */
if (session.getSource().isPreAcStates() && !session.getSource().isAutocommit()) {
session.getSource().setAutocommit(true);
}
session.clearResources(false);
ServerConnection source = session.getSource();
source.write(ok);
}
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) {
// 完善show @@connection.sql 监控命令.已经执行完的sql 不再显示
source.setExecuteSql(null);
QueryResult queryResult = new QueryResult(session.getSource().getUser(), rrs.getSqlType(), rrs.getStatement(), selectRows, netInBytes, netOutBytes, startTime, System.currentTimeMillis(), 0);
QueryResultDispatcher.dispatchQuery(queryResult);
}
}
}
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;
MiddlerResultHandler middlerResultHandler = session.getMiddlerResultHandler();
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) {
// huangyiming add 数据合并前如果有中间过程则先执行数据合并再执行下一步
if (session.getMiddlerResultHandler() != null) {
isMiddleResultDone.set(true);
}
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);
}
if (middlerResultHandler == null) {
// middlerResultHandler.secondEexcute();
source.write(eof);
}
} finally {
lock.unlock();
}
}
}
execCount++;
if (middlerResultHandler != null) {
if (execCount != rrs.getNodes().length) {
return;
}
/*else{
middlerResultHandler.secondEexcute();
}*/
}
if (execCount == rrs.getNodes().length) {
int resultSize = source.getWriteQueue().size() * MycatServer.getInstance().getConfig().getSystem().getBufferPoolPageSize();
// 完善show @@connection.sql 监控命令.已经执行完的sql 不再显示
source.setExecuteSql(null);
// 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);
// add huangyiming 如果是中间过程,必须等数据合并好了再进行下一步语句的拼装
if (middlerResultHandler != null) {
while (!this.isMiddleResultDone.compareAndSet(false, true)) {
Thread.yield();
}
middlerResultHandler.secondEexcute();
isMiddleResultDone.set(false);
}
}
}
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) {
// huangyiming add
this.header = header;
this.fields = fields;
MiddlerResultHandler middlerResultHandler = session.getMiddlerResultHandler();
/*if(null !=middlerResultHandler ){
return;
}*/
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);
if (null == middlerResultHandler) {
// session.getSource().write(row);
source.write(buffer);
}
if (dataMergeSvr != null) {
dataMergeSvr.onRowMetaData(columToIndx, fieldCount);
}
} catch (Exception e) {
handleDataProcessException(e);
} finally {
lock.unlock();
}
}
Aggregations