mysql5.7时允许多线程复制,原理是同时处于prepared的事务都是可以并行执行的,因为能进入prepared阶段的说明已经拿到了锁,既然不同的事务同时拿到了锁,那么就不可能冲突,所以可以同时执行的.
AtomicInteger globalTransactionId;
thread1:{
beginTransaction();
excute("update user set age = 10");
commit();
}
thread2:{
beginTransaction();
excute("update user set age = 9");
commit();
}
thread3:{
beginTransaction();
excute("update book set name = `hello`");
commit();
}
commit(){
prepared();
// 这一步可能多个线程一起进入,拿到相同的值,值相同的话表示该事务可以并行执行
int last_committed = globalTransactionId.get();
// 将last_committed 写入bin-log
...
globalTransactionId.increase();
...
}
mysql配置
主:
sync_binlog=1 // 每执行一次事务就写入磁盘
从:
slave-parallel-type=LOGICAL_CLOCK // 事务组同时提交
slave-parallel-workers=16 // 启动多少个slave_sql_thread线程
relay_log_recovery=ON // 在从库中将relay_log_recovery设置为on,假如果碰到relay_log损坏的情形,从库会自动放弃所有未执行的relay log,重新生成一个relay log,并将从库的io线程的position重新指向新的relay log。并将sql线程的position退回到跟io线程的position保持一致,重新开始同步,这样在从库中事务不会丢失。