mysql-binlog-connector-java icon indicating copy to clipboard operation
mysql-binlog-connector-java copied to clipboard

How to know if binlog file and position info is too old?

Open ngocdaothanh opened this issue 9 years ago • 14 comments

In the MySQL to MongoDB replication tool Mydit, I continuously save binlog position to MongoDB.

When the replication tool starts, I use BinaryLogClient#setBinlogFilename and BinaryLogClient#setBinlogPosition` to load the last binlog position (saved in MongoDB from the last run).

If binlog file and position info is too old (the user stops the replication tool, then start it again much later), it seems that BinaryLogClient#connect doesn't successfully connect to MySQL. It just reconnects periodically, helplessly.

In this case, the replication tool user must manually fix the problem (updating data and updating/reseting binlog info manually). The problem is that BinaryLogClient doesn't log anything so that the user knows that the binlog file and position info is too old, so he doesn't know that there's problem that he should fix manually.

Is there a method, callback, result code, log etc. to tell if the binlog file and position info is too old?

ngocdaothanh avatar Apr 02 '15 02:04 ngocdaothanh

ngocdaothanh, My solution was to turn off turn off automatic reconnect, and detect the situation using a LifecycleListener:

public class ConnectionLifecycleListener implements LifecycleListener {
    public enum Reason {
        BINLOG_NOT_AVAILABLE
    }

    @Override
    public void onCommunicationFailure(BinaryLogClient client, Exception ex) {
        if (ex.getMessage()
                .equals("1236 - Could not find first log file name in binary log index file")) {
            // The binary log has been rotated out from the master, so we can't
            // reconnect to it. Shutdown the listener, and tell the operator
            // that we need to rebootstrap.
            System.out.println(String.format("Binlog %s/%d is no longer available on the master. Need to re-bootstrap.",
                    client.getBinlogFilename(), client.getBinlogPosition()));
            this.failureReason = Reason.BINLOG_NOT_AVAILABLE;
        } else {
            throw new RuntimeException(ex);
        }
    }
}

and then in my main class:

        client.setKeepAlive(false);
        ConnectionLifecycleListener lifecycleListener = new ConnectionLifecycleListener();
        client.registerLifecycleListener(lifecycleListener);

        while (true) {
            client.connect();
            if (lifecycleListener.getFailureReason() == ConnectionLifecycleListener.Reason.BINLOG_NOT_AVAILABLE) {
                break;
            }
        }

wushujames avatar Apr 02 '15 03:04 wushujames

Thanks a lot @wushujames :+1: Maybe this should be built into mysql-binlog-connector-java?

ngocdaothanh avatar Apr 02 '15 03:04 ngocdaothanh

Thanks @wushujames. I would enclose client.connect() into a try/catch block though (as it may throw IOException). Anyway, I think it makes sense to introduce designated exceptions (so to speak) for easier error handling. I'll look into it. Thanks guys.

shyiko avatar Apr 02 '15 10:04 shyiko

Please read this before upgrading.

shyiko avatar May 01 '15 13:05 shyiko

Hello @shyiko,

Sorry for "hi-jacking" this old issue, but I still found it suitable.

I am running the latest version (0.2.4 at the time) and I believe that the error message, when trying to connect to a missing binlog file, is misleading. I end up with INFO: Trying to restore lost connection to localhost:3306, I would expect it to tell me something about the file not being there anymore.

I guess that https://github.com/shyiko/mysql-binlog-connector-java/blob/7e30439ea14e39d4a78d6d3673369b1dfb7e3ad0/src/main/java/com/github/shyiko/mysql/binlog/BinaryLogClient.java#L513-L528 was overlooked when 1817d0ff709c65c31af9236dcc4e50cc3ad1023b was introduced?

Otherwise, thanks for a great library and keep up the good work!

walro avatar Nov 24 '15 16:11 walro

@walro thank you for reporting! It's definitely worth the look. Reopening the issue.

shyiko avatar Nov 24 '15 16:11 shyiko

@walro try registering lifecycleListener on BinaryLogClient (LifecycleListener::onCommunicationFailure(this, exception) will be called in case of an error).

shyiko avatar Nov 24 '15 17:11 shyiko

Thanks, will give it a try tomorrow!

walro avatar Nov 24 '15 17:11 walro

@walro try registering lifecycleListener on BinaryLogClient (LifecycleListener::onCommunicationFailure(this, exception) will be called in case of an error).

Yes, that works fine. I can work with this, thanks for your help!

walro avatar Nov 25 '15 15:11 walro

Well, why can't I restore from an old position info, a callback to notify seems not to satisfy my need.

tramchamploo avatar Dec 14 '15 08:12 tramchamploo

@tramchamploo what do you mean? If you are trying to reconnect at binary log position which doesn't exists you gonna get an error. What do you expect?

shyiko avatar Dec 14 '15 17:12 shyiko

I mean I resume from an existed file and position and it just reconnects over and over again.

tramchamploo avatar Dec 15 '15 02:12 tramchamploo

Oh, yeah, right now it's far from being ideal. Even though LifecycleListener::onCommunicationFailure works is obviously a workaround. Built-in bail out is coming in 1.0.0. I'm planning to get back to it on December 24ish.

shyiko avatar Dec 15 '15 03:12 shyiko

Great news, I'm working on a fork of mypipe. Adding ha feature based on mysql heartbeat, this would be a great help.

tramchamploo avatar Dec 15 '15 03:12 tramchamploo