MyCATApache/Mycat-Server · error · IllegalStateException

MySQL replication stream is already open

Error message

MySQL replication stream is already open

What it means

BinlogStream.allocateBinaryLogClient is synchronized and throws IllegalStateException("MySQL replication stream is already open") if isConnected() is true when connect() is requested. Each BinlogStream instance manages a single BinaryLogClient, so a second concurrent connect on the same open stream is rejected.

Solutions

  1. Guard calls with binlogStream.isConnected() before connect(), or track connection state in application code.
  2. Close/disconnect the existing BinaryLogClient before reconnecting on the same stream.
  3. Create a new BinlogStream instance for each connection lifecycle instead of reconnecting a shared one.
  4. Serialize connect attempts behind an application-level lock/flag to avoid double-triggered jobs.
  5. Catch IllegalStateException and treat it as a no-op if a connection is already active.

Example fix

// before
binlogStream.connect(); // may be called repeatedly
// after
if (!binlogStream.isConnected()) {
  binlogStream.connect();
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (binlogStream.isConnected()) { return; } // already open, skip connect
binlogStream.connect();

Try / catch

try { binlogStream.connect(); } catch (IllegalStateException e) { if (e.getMessage().contains("already open")) { log.info("binlog stream already connected; ignoring duplicate connect"); } else throw e; }

Prevention

When it happens

Trigger: Calling connect() twice on the same BinlogStream without closing the previous connection, or two threads racing to connect — one enters the synchronized method while the underlying client is already connected.

Common situations: Reconnect logic that does not check isConnected() or close the old client first; application restart/retry logic re-invoking connect after a previous successful open; migration jobs triggered twice (e.g. scheduler overlap) sharing a BinlogStream instance.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/48a2a378ec5414f6. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/migrate/BinlogStream.java:130

    }

    private void initTaskDate() {
        Date curDate = new Date();
        for (MigrateTask migrateTask : migrateTaskList) {
            migrateTask.setLastBinlogDate(curDate);
        }
    }

    public void connect(long timeoutInMilliseconds) throws IOException, TimeoutException {
        initTaskDate();
        scheduler.scheduleAtFixedRate(new BinlogIdleCheck(this), 5, 15, TimeUnit.SECONDS);
        allocateBinaryLogClient().connect(timeoutInMilliseconds);

    }

    private synchronized BinaryLogClient allocateBinaryLogClient() {
        if (isConnected()) {
            throw new IllegalStateException("MySQL replication stream is already open");
        }
        binaryLogClient = new BinaryLogClient(hostname, port, username, password);
        binaryLogClient.setBinlogFilename(getBinglogFile());
        binaryLogClient.setBinlogPosition(getBinlogPos());
        binaryLogClient.setServerId(getSlaveID());
        binaryLogClient.registerEventListener(new DelegatingEventListener());
        return binaryLogClient;
    }


    public synchronized boolean isConnected() {
        return binaryLogClient != null && binaryLogClient.isConnected();
    }


    public synchronized void disconnect() throws IOException {
        if (binaryLogClient != null) {
            binaryLogClient.disconnect();

View on GitHub (pinned to 65f8d8beb7)