-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Closed
Milestone
Description
前提:使用PeriodMixedMetaManager.java作为metaManager
问题描述:
在CanalServerWithEmbedded.java的subscribe()方法中存在这样一段代码:
Position position = canalInstance.getMetaManager().getCursor(clientIdentity);
if (position == null) {
position = canalInstance.getEventStore().getFirstPosition();// 获取一下store中的第一条
if (position != null) {
canalInstance.getMetaManager().updateCursor(clientIdentity, position); // 更新一下cursor
}
logger.info("subscribe successfully, {} with first position:{} ", clientIdentity, position);
根据上下文,当内存中的position为null时,这段代码会先取出eventStore中的position,再根据此position更新zk中的cursor位置。但是在PeriodMixedMetaManager中更新方法的代码如下:
public void updateCursor(ClientIdentity clientIdentity, Position position) throws CanalMetaManagerException {
updateCursorTasks.add(clientIdentity);// 添加到任务队列中进行触发
super.updateCursor(clientIdentity, position);
}
此方法会先将调度任务加入任务队列,然后再更新内存中的position。而调度线程则会先去取内存中的position,再更新zookeeper中的cursor。两个线程处于并发竞争态,可能会发生读后写情况。
问题解决办法(建议):
如果您认可这里的确可能有风险,把updateCursor里的两句话调换一下位置
问题背景:
在切换canal时发生了cursor定位错误(从0开始)的情况。我抱着“有问题”的心态来找问题,初步将问题定位在这里。如果存在风险更大的地方,请作者指点一二
Reactions are currently unavailable