October 7, 2013

MySQL5.7 简述新的复制模式LOGICAL_CLOCK

我们知道,在MySQL5.6中引入了并行复制模式,当实例上有多个库的时候,可以在备库上对这几个库进行并发操作;这在基于分库的应用场景下,可以显著提升备库的复制效率,但对于我们以分表为主的场景,则效果甚微。 MySQL5.7.2是最新的开发版本release,在该版本中可以看到对复制部分做了非常大的改动,例如半同步复制的after sync, 使用Performance Schema表来监控复制线程,实验室版本的多主复制,以及本文要提到的新的多线程复制模式,MySQL里用一个新的参数来控制:slave_parallel_type,默认值为DATABASE,表示默认行为;另外一个值为LOGICAL_CLOCK,即为新增的模式 1.基本思路 由于MySQL存储引擎层已经保证了同时能够进入事务prepare/commit阶段的事务是没有冲突的(例如Innodb的行锁机制来保证事务的调度),那么可以认为在同时进入Prepare阶段的事务是可以在备库并发执行的,因为他们互相没有冲突; LOGICAL_CLOCK是一个全局递增的64位长整型数字,主要通过它来判断哪些事务能够并发; a.分配 在二阶段提交的binlog prepare阶段进行分配    binlog_cache_mngr *const cache_mngr= thd_get_cache_mngr(thd); cache= cache_mngr->get_binlog_cache_log(all); if (cache->commit_seq_no == SEQ_UNINIT) cache->commit_seq_no= mysql_bin_log.commit_clock.get_timestamp(); }   在之前版本中binlog_prepare函数都是空函数 b.写入 LOGICAL_CLOCK只有记录到binlog中,才能为备库所用,在将每个线程cache的binlog写入时,调用函数write_commit_seq_no,每组事务的第一个事件才记录LOGICAL_CLOCK 具体的存储位置,可以阅读函数Gtid_log_event::Gtid_log_event() c.递增 MySQL的group commit有三个阶段,FLUSH_STAGE, SYNC_STAGE, 以及COMMIT_STAGE,递增LOGICAL_CLOCK发生在第二阶段结束之后,第三阶段开始之前,这时候SYNC阶段的leader还没有释放LOCK_SYNC。 7300   mysql_bin_log.commit_clock.step(); 7301   if (opt_binlog_order_commits) 7302   { 7303     if (change_stage(thd, Stage_manager::COMMIT_STAGE, 7304   这里并不是严格要求所有同时进入Prepare阶段的事务都在备库并发执行,因此一组提交的事务中可能存在不同的seq no 备库根据主库上记录的seq no来决定哪些事务是可以并行的,因此主库上并发线程数越多,复制效果越好,目前代码还处于开发阶段,在试玩时,发现打开gtid时,无法使用该特性,bug链接:http://bugs.mysql.com/bug.php?id=70536  包含具体的代码分析 更具体的可以阅读如下链接: 想知道具体的代码怎么实现的可以看看这个:http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/6256 […]