数据同步时的并发策略

主备并发同步

版本5.5并发复制策略(个人策略)

按表分发:

  • 每个worker都维护一个hashtable,表示自己正在执行的事务中涉及到哪些表,
  • 如果分发的事务中的表,和在worker中大于1个worker的表有事务冲突(有相同的表在执行),就等待,等到只有一个worker有冲突的时候,就把这个事务丢到这个worker
  • 如果热点表被多次操作,这样子就只有一个worker执行,相当于单线程

按行分发

  • binlog 必须是row,所以必须维护一个hashtable,里面的key为库名+表名+索引a的名称+a的值
  • 表必须有主键,不能有外键,外键连表是不会写到binlog里面的,
  • 问题是:大事务的操作会很消耗内存(数据多),消耗cpu(计算key)

版本5.6的并发策略

支持库粒度的并发,

  • 优势:不要求binlog的格式,而且构造hash值很快,因为不会像row那样数据多
  • 缺点:如果热点表都在一个库里面那就和单线程没啥区别
    MariaDB的策略

组提交的粒度并发

  • 优势:因为使用的是同一组commit的粒度,所以不会有写锁并发的情况(commit之前都被阻塞了),所以同一个commitid的可以分发给不同的worker执行,执行完再取下一批
  • 缺点:同一组里面有一个事务比较大,整个worker group里面会只有一个worker在执行一个事务,变成单线程,这个超大事务结束,才能取下一个事务组

版本5.7的并行策略(使用slave-parallel_type参数指定)

  • 配置为DATABASE,表示使用5.6的策略
  • 配置为LOGICAL_CLOCK,表示使用MariaDB的优化策略,
  • 优化思路:
    • 同时处于prepare状态的事务可以并行(这时候不会有事务的冲突,有的话已经在前面阻塞住了)
    • 处于prepare和处于commit状态的事务可以并行(参考事务组的概念)
    • 所以说:使用binlog_group_commit_sync_delay和binlog_group_commit_sync_delay_count不仅能够提高binlog的io效率,也能提高备库的同步效率
  • 版本5.7.22的策略(参数binlog_transation_dependency_tracking指定)
    配置为COMMIT_ORDER,就是5.7配置为LOGICAL_CLOCK的策略
    配置为WRITESET表示事务涉及的更新的每一行,计算这行的hash值,组成writeset,和按行分发差不多,hash的计算是放在主库那边,节省了备库很多的资源,分发策略也不依赖binlog,所以不需要设置为row
    配置为WRITESET_SESSION,就是比writeset多一个约束,同一个线程执行的两个事务,在备库也要保证先后顺序

数据同步时的并发策略