use of io.mycat.backend.mysql.nio.MySQLConnection 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);
}
use of io.mycat.backend.mysql.nio.MySQLConnection in project Mycat-Server by MyCATApache.
the class MultiNodeCoordinator method okResponse.
@Override
public void okResponse(byte[] ok, BackendConnection conn) {
//process the XA Transatcion 2pc commit
if (conn instanceof MySQLConnection) {
MySQLConnection mysqlCon = (MySQLConnection) conn;
switch(mysqlCon.getXaStatus()) {
case TxState.TX_STARTED_STATE:
//should be wait all nodes ready ,then send xa commit to all nodes.
if (mysqlCon.batchCmdFinished()) {
String xaTxId = session.getXaTXID();
String cmd = "XA COMMIT " + xaTxId;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Start execute the cmd :" + cmd + ",current host:" + mysqlCon.getHost() + ":" + mysqlCon.getPort());
}
//recovery log
CoordinatorLogEntry coordinatorLogEntry = inMemoryRepository.get(xaTxId);
for (int i = 0; i < coordinatorLogEntry.participants.length; i++) {
LOGGER.debug("[In Memory CoordinatorLogEntry]" + coordinatorLogEntry.participants[i]);
if (coordinatorLogEntry.participants[i].resourceName.equals(conn.getSchema())) {
coordinatorLogEntry.participants[i].txState = TxState.TX_PREPARED_STATE;
}
}
inMemoryRepository.put(session.getXaTXID(), coordinatorLogEntry);
fileRepository.writeCheckpoint(inMemoryRepository.getAllCoordinatorLogEntries());
//send commit
mysqlCon.setXaStatus(TxState.TX_PREPARED_STATE);
mysqlCon.execCmd(cmd);
}
return;
case TxState.TX_PREPARED_STATE:
{
//recovery log
String xaTxId = session.getXaTXID();
CoordinatorLogEntry coordinatorLogEntry = inMemoryRepository.get(xaTxId);
for (int i = 0; i < coordinatorLogEntry.participants.length; i++) {
if (coordinatorLogEntry.participants[i].resourceName.equals(conn.getSchema())) {
coordinatorLogEntry.participants[i].txState = TxState.TX_COMMITED_STATE;
}
}
inMemoryRepository.put(session.getXaTXID(), coordinatorLogEntry);
fileRepository.writeCheckpoint(inMemoryRepository.getAllCoordinatorLogEntries());
//XA reset status now
mysqlCon.setXaStatus(TxState.TX_INITIALIZE_STATE);
break;
}
default:
}
}
if (this.cmdHandler.relaseConOnOK()) {
session.releaseConnection(conn);
} else {
session.releaseConnectionIfSafe(conn, LOGGER.isDebugEnabled(), false);
}
if (this.finished()) {
cmdHandler.okResponse(session, ok);
if (cmdHandler.isAutoClearSessionCons()) {
session.clearResources(false);
}
}
}
use of io.mycat.backend.mysql.nio.MySQLConnection in project Mycat-Server by MyCATApache.
the class RollbackNodeHandler method rollback.
public void rollback() {
final int initCount = session.getTargetCount();
lock.lock();
try {
reset(initCount);
} finally {
lock.unlock();
}
if (session.closed()) {
decrementCountToZero();
return;
}
// 执行
int started = 0;
for (final RouteResultsetNode node : session.getTargetKeys()) {
if (node == null) {
LOGGER.error("null is contained in RoutResultsetNodes, source = " + session.getSource());
continue;
}
final BackendConnection conn = session.getTarget(node);
if (conn != null) {
boolean isClosed = conn.isClosedOrQuit();
if (isClosed) {
session.getSource().writeErrMessage(ErrorCode.ER_UNKNOWN_ERROR, "receive rollback,but find backend con is closed or quit");
LOGGER.error(conn + "receive rollback,but fond backend con is closed or quit");
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("rollback job run for " + conn);
}
if (clearIfSessionClosed(session)) {
return;
}
conn.setResponseHandler(RollbackNodeHandler.this);
//support the XA rollback
if (session.getXaTXID() != null && conn instanceof MySQLConnection) {
MySQLConnection mysqlCon = (MySQLConnection) conn;
String xaTxId = session.getXaTXID();
//exeBatch cmd issue : the 2nd package can not receive the response
mysqlCon.execCmd("XA END " + xaTxId + ";");
mysqlCon.execCmd("XA ROLLBACK " + xaTxId + ";");
} else {
conn.rollback();
}
++started;
}
}
if (started < initCount && decrementCountBy(initCount - started)) {
/**
* assumption: only caused by front-end connection close. <br/>
* Otherwise, packet must be returned to front-end
*/
session.clearResources(true);
}
}
use of io.mycat.backend.mysql.nio.MySQLConnection in project Mycat-Server by MyCATApache.
the class ReloadConfig method reload_all.
public static boolean reload_all() {
/**
* 1、载入新的配置
* 1.1、ConfigInitializer 初始化,基本自检
* 1.2、DataNode/DataHost 实际链路检测
*/
ConfigInitializer loader = new ConfigInitializer(true);
Map<String, UserConfig> newUsers = loader.getUsers();
Map<String, SchemaConfig> newSchemas = loader.getSchemas();
Map<String, PhysicalDBNode> newDataNodes = loader.getDataNodes();
Map<String, PhysicalDBPool> newDataHosts = loader.getDataHosts();
MycatCluster newCluster = loader.getCluster();
FirewallConfig newFirewall = loader.getFirewall();
/**
* 1.2、实际链路检测
*/
loader.testConnection();
/**
* 2、承接
* 2.1、老的 dataSource 继续承接新建请求
* 2.2、新的 dataSource 开始初始化, 完毕后交由 2.3
* 2.3、新的 dataSource 开始承接新建请求
* 2.4、老的 dataSource 内部的事务执行完毕, 相继关闭
* 2.5、老的 dataSource 超过阀值的,强制关闭
*/
MycatConfig config = MycatServer.getInstance().getConfig();
/**
* 2.1 、老的 dataSource 继续承接新建请求, 此处什么也不需要做
*/
boolean isReloadStatusOK = true;
/**
* 2.2、新的 dataHosts 初始化
*/
for (PhysicalDBPool dbPool : newDataHosts.values()) {
String hostName = dbPool.getHostName();
// 设置 schemas
ArrayList<String> dnSchemas = new ArrayList<String>(30);
for (PhysicalDBNode dn : newDataNodes.values()) {
if (dn.getDbPool().getHostName().equals(hostName)) {
dnSchemas.add(dn.getDatabase());
}
}
dbPool.setSchemas(dnSchemas.toArray(new String[dnSchemas.size()]));
// 获取 data host
String dnIndex = DnPropertyUtil.loadDnIndexProps().getProperty(dbPool.getHostName(), "0");
if (!"0".equals(dnIndex)) {
LOGGER.info("init datahost: " + dbPool.getHostName() + " to use datasource index:" + dnIndex);
}
dbPool.init(Integer.valueOf(dnIndex));
if (!dbPool.isInitSuccess()) {
isReloadStatusOK = false;
break;
}
}
/**
* TODO: 确认初始化情况
*
* 新的 dataHosts 是否初始化成功
*/
if (isReloadStatusOK) {
/**
* 2.3、 在老的配置上,应用新的配置,开始准备承接任务
*/
config.reload(newUsers, newSchemas, newDataNodes, newDataHosts, newCluster, newFirewall, true);
/**
* 2.4、 处理旧的资源
*/
LOGGER.warn("1、clear old backend connection(size): " + NIOProcessor.backends_old.size());
// 清除前一次 reload 转移出去的 old Cons
Iterator<BackendConnection> iter = NIOProcessor.backends_old.iterator();
while (iter.hasNext()) {
BackendConnection con = iter.next();
con.close("clear old datasources");
iter.remove();
}
Map<String, PhysicalDBPool> oldDataHosts = config.getBackupDataHosts();
for (PhysicalDBPool dbPool : oldDataHosts.values()) {
dbPool.stopHeartbeat();
// 提取数据源下的所有连接
for (PhysicalDatasource ds : dbPool.getAllDataSources()) {
//
for (NIOProcessor processor : MycatServer.getInstance().getProcessors()) {
for (BackendConnection con : processor.getBackends().values()) {
if (con instanceof MySQLConnection) {
MySQLConnection mysqlCon = (MySQLConnection) con;
if (mysqlCon.getPool() == ds) {
NIOProcessor.backends_old.add(con);
}
} else if (con instanceof JDBCConnection) {
JDBCConnection jdbcCon = (JDBCConnection) con;
if (jdbcCon.getPool() == ds) {
NIOProcessor.backends_old.add(con);
}
}
}
}
}
}
LOGGER.warn("2、to be recycled old backend connection(size): " + NIOProcessor.backends_old.size());
//清理缓存
MycatServer.getInstance().getCacheService().clearCache();
MycatServer.getInstance().initRuleData();
return true;
} else {
// 如果重载不成功,则清理已初始化的资源。
LOGGER.warn("reload failed, clear previously created datasources ");
for (PhysicalDBPool dbPool : newDataHosts.values()) {
dbPool.clearDataSources("reload config");
dbPool.stopHeartbeat();
}
return false;
}
}
use of io.mycat.backend.mysql.nio.MySQLConnection in project Mycat-Server by MyCATApache.
the class ShowBackendOld method getRow.
private static RowDataPacket getRow(BackendConnection c, String charset) {
RowDataPacket row = new RowDataPacket(FIELD_COUNT);
row.add(LongUtil.toBytes(c.getId()));
long threadId = 0;
if (c instanceof MySQLConnection) {
threadId = ((MySQLConnection) c).getThreadId();
}
row.add(LongUtil.toBytes(threadId));
row.add(StringUtil.encode(c.getHost(), charset));
row.add(IntegerUtil.toBytes(c.getPort()));
row.add(IntegerUtil.toBytes(c.getLocalPort()));
row.add(LongUtil.toBytes(c.getNetInBytes()));
row.add(LongUtil.toBytes(c.getNetOutBytes()));
row.add(LongUtil.toBytes((TimeUtil.currentTimeMillis() - c.getStartupTime()) / 1000L));
row.add(LongUtil.toBytes(c.getLastTime()));
boolean isBorrowed = c.isBorrowed();
row.add(isBorrowed ? "true".getBytes() : "false".getBytes());
return row;
}
Aggregations