Search in sources :

Example 1 with ParticipantLogEntry

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

the class MultiNodeCoordinator method executeBatchNodeCmd.

/** Multi-nodes 1pc Commit Handle **/
public void executeBatchNodeCmd(SQLCtrlCommand cmdHandler) {
    this.cmdHandler = cmdHandler;
    final int initCount = session.getTargetCount();
    runningCount.set(initCount);
    nodeCount = initCount;
    failed.set(false);
    faileCount.set(0);
    //recovery nodes log
    ParticipantLogEntry[] participantLogEntry = new ParticipantLogEntry[initCount];
    // 执行
    int started = 0;
    for (RouteResultsetNode rrn : session.getTargetKeys()) {
        if (rrn == null) {
            LOGGER.error("null is contained in RoutResultsetNodes, source = " + session.getSource());
            continue;
        }
        final BackendConnection conn = session.getTarget(rrn);
        if (conn != null) {
            conn.setResponseHandler(this);
            //process the XA_END XA_PREPARE Command
            MySQLConnection mysqlCon = (MySQLConnection) conn;
            String xaTxId = session.getXaTXID();
            if (mysqlCon.getXaStatus() == TxState.TX_STARTED_STATE) {
                //recovery Log
                participantLogEntry[started] = new ParticipantLogEntry(xaTxId, conn.getHost(), 0, conn.getSchema(), ((MySQLConnection) conn).getXaStatus());
                String[] cmds = new String[] { "XA END " + xaTxId, "XA PREPARE " + xaTxId };
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("Start execute the batch cmd : " + cmds[0] + ";" + cmds[1] + "," + "current connection:" + conn.getHost() + ":" + conn.getPort());
                }
                mysqlCon.execBatchCmd(cmds);
            } else {
                //recovery Log
                participantLogEntry[started] = new ParticipantLogEntry(xaTxId, conn.getHost(), 0, conn.getSchema(), ((MySQLConnection) conn).getXaStatus());
                cmdHandler.sendCommand(session, conn);
            }
            ++started;
        }
    }
    //xa recovery log
    if (session.getXaTXID() != null) {
        CoordinatorLogEntry coordinatorLogEntry = new CoordinatorLogEntry(session.getXaTXID(), false, participantLogEntry);
        inMemoryRepository.put(session.getXaTXID(), coordinatorLogEntry);
        fileRepository.writeCheckpoint(inMemoryRepository.getAllCoordinatorLogEntries());
    }
    if (started < nodeCount) {
        runningCount.set(started);
        LOGGER.warn("some connection failed to execute " + (nodeCount - started));
        /**
			 * assumption: only caused by front-end connection close. <br/>
			 * Otherwise, packet must be returned to front-end
			 */
        failed.set(true);
    }
}
Also used : BackendConnection(io.mycat.backend.BackendConnection) ParticipantLogEntry(io.mycat.backend.mysql.xa.ParticipantLogEntry) RouteResultsetNode(io.mycat.route.RouteResultsetNode) MySQLConnection(io.mycat.backend.mysql.nio.MySQLConnection) CoordinatorLogEntry(io.mycat.backend.mysql.xa.CoordinatorLogEntry)

Example 2 with ParticipantLogEntry

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

the class MycatServer method performXARecoveryLog.

//XA recovery log check
private void performXARecoveryLog() {
    //fetch the recovery log
    CoordinatorLogEntry[] coordinatorLogEntries = getCoordinatorLogEntries();
    for (int i = 0; i < coordinatorLogEntries.length; i++) {
        CoordinatorLogEntry coordinatorLogEntry = coordinatorLogEntries[i];
        boolean needRollback = false;
        for (int j = 0; j < coordinatorLogEntry.participants.length; j++) {
            ParticipantLogEntry participantLogEntry = coordinatorLogEntry.participants[j];
            if (participantLogEntry.txState == TxState.TX_PREPARED_STATE) {
                needRollback = true;
                break;
            }
        }
        if (needRollback) {
            for (int j = 0; j < coordinatorLogEntry.participants.length; j++) {
                ParticipantLogEntry participantLogEntry = coordinatorLogEntry.participants[j];
                //XA rollback
                String xacmd = "XA ROLLBACK " + coordinatorLogEntry.id + ';';
                OneRawSQLQueryResultHandler resultHandler = new OneRawSQLQueryResultHandler(new String[0], new XARollbackCallback());
                outloop: for (SchemaConfig schema : MycatServer.getInstance().getConfig().getSchemas().values()) {
                    for (TableConfig table : schema.getTables().values()) {
                        for (String dataNode : table.getDataNodes()) {
                            PhysicalDBNode dn = MycatServer.getInstance().getConfig().getDataNodes().get(dataNode);
                            if (dn.getDbPool().getSource().getConfig().getIp().equals(participantLogEntry.uri) && dn.getDatabase().equals(participantLogEntry.resourceName)) {
                                //XA STATE ROLLBACK
                                participantLogEntry.txState = TxState.TX_ROLLBACKED_STATE;
                                SQLJob sqlJob = new SQLJob(xacmd, dn.getDatabase(), resultHandler, dn.getDbPool().getSource());
                                sqlJob.run();
                                LOGGER.debug(String.format("[XA ROLLBACK] [%s] Host:[%s] schema:[%s]", xacmd, dn.getName(), dn.getDatabase()));
                                break outloop;
                            }
                        }
                    }
                }
            }
        }
    }
    //init into in memory cached
    for (int i = 0; i < coordinatorLogEntries.length; i++) {
        MultiNodeCoordinator.inMemoryRepository.put(coordinatorLogEntries[i].id, coordinatorLogEntries[i]);
    }
    //discard the recovery log
    MultiNodeCoordinator.fileRepository.writeCheckpoint(MultiNodeCoordinator.inMemoryRepository.getAllCoordinatorLogEntries());
}
Also used : OneRawSQLQueryResultHandler(io.mycat.sqlengine.OneRawSQLQueryResultHandler) PhysicalDBNode(io.mycat.backend.datasource.PhysicalDBNode) SchemaConfig(io.mycat.config.model.SchemaConfig) ParticipantLogEntry(io.mycat.backend.mysql.xa.ParticipantLogEntry) SQLJob(io.mycat.sqlengine.SQLJob) XARollbackCallback(io.mycat.backend.mysql.xa.XARollbackCallback) TableConfig(io.mycat.config.model.TableConfig) CoordinatorLogEntry(io.mycat.backend.mysql.xa.CoordinatorLogEntry)

Aggregations

CoordinatorLogEntry (io.mycat.backend.mysql.xa.CoordinatorLogEntry)2 ParticipantLogEntry (io.mycat.backend.mysql.xa.ParticipantLogEntry)2 BackendConnection (io.mycat.backend.BackendConnection)1 PhysicalDBNode (io.mycat.backend.datasource.PhysicalDBNode)1 MySQLConnection (io.mycat.backend.mysql.nio.MySQLConnection)1 XARollbackCallback (io.mycat.backend.mysql.xa.XARollbackCallback)1 SchemaConfig (io.mycat.config.model.SchemaConfig)1 TableConfig (io.mycat.config.model.TableConfig)1 RouteResultsetNode (io.mycat.route.RouteResultsetNode)1 OneRawSQLQueryResultHandler (io.mycat.sqlengine.OneRawSQLQueryResultHandler)1 SQLJob (io.mycat.sqlengine.SQLJob)1