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保持一致,重新开始同步,这样在从库中事务不会丢失。