mysql-binlog-connector-java
mysql-binlog-connector-java copied to clipboard
How to know if binlog file and position info is too old?
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, 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;
}
}
Thanks a lot @wushujames :+1: Maybe this should be built into mysql-binlog-connector-java?
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.
Please read this before upgrading.
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 thank you for reporting! It's definitely worth the look. Reopening the issue.
@walro try registering lifecycleListener on BinaryLogClient (LifecycleListener::onCommunicationFailure(this, exception) will be called in case of an error).
Thanks, will give it a try tomorrow!
@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!
Well, why can't I restore from an old position info, a callback to notify seems not to satisfy my need.
@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?
I mean I resume from an existed file and position and it just reconnects over and over again.
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.
Great news, I'm working on a fork of mypipe. Adding ha feature based on mysql heartbeat, this would be a great help.