自增列多中心间双向同步问题

OB自增列基础

OceanBase的自增列有三个重要属性:自增起始值、自增步长、自增列缓存大小:

+---------------------------+---------+
| Variable_name             | Value   |
+---------------------------+---------+
| auto_increment_cache_size | 1000000 |
| auto_increment_increment  | 1       |
| auto_increment_offset     | 1       |
+---------------------------+---------+
3 rows in set

分区表中的自增列

在使用分区表的情况下,自增列实现的全局单调递增,并不是全局有序递增。
auto_increment_cache_size 的默认值为 1000000,当分区表所在的 OBServer 节点 OBServer1、OBServer2 和 OBServer3 分别按以下顺序先后接收到 insert into values (null) 的请求时,它们内部的处理逻辑如下:

  1. OBServer1 发现自身没有缓存时,向内部表申请一段自增区间 [1,1000000],并且生成一个自增值 1。
  2. OBServer2 发现自身没有缓存时,向内部表申请一段自增区间 [1000001,2000000],并且生成一个自增值 1000001。
  3. OBServer3 发现自身没有缓存时,向内部表申请一段自增区间 [2000001,3000000],并且生成一个自增值 2000001。

多中心多活架构设计下的自增列设置问题

按照以往的使用单机MySQL的经验,在多中心应用多活的架构下,不同中心间维持双向的数据同步,通过设置不同的起始值偏移量可以规避自增列出现重复的情况。

假设现在有一个ABC三中心多活的应用计划将数据库迁移至分布式的OceanBase数据库上,需要如何设置自增列的相关参数?

我们设想的是,将ABC三个中心的auto_increment_offset 分别设置为1,2,3;auto_increment_increment 统一设置为10;

这样在A中心内,所有的自增列都是1结尾的数字,1、11、21、… 1000001、1000011、… 2000001、2000011…
B中心内,所有的自增列都是以2结尾的数字,2、12、22、… 1000002、1000012、… 2000002、2000012…
C中心内,所有的自增列都是3结尾的数字,3、13、23、… 1000003、1000013、… 2000003、2000013…

上述办法是基于不修改数据库和应用代码的情况下简单设想的,不知道在数据量越来越大的情况下会不会出现一些没有考虑到的问题。已经考虑到的问题有集群发生异常重启后,所设置的变量可能丢失的问题。

可行的优化方案

另外基于修改代码逻辑的基础上我们还设想了潜在的两个方案:

  • 应用不使用数据库的自增列,改为使用雪花算法之类的计算得出不重复的标识值

  • 数据库层面通过结合现有自增列的模式,在自动生成的自增列前新增一位标识,区分不同中心间的不同集群

如果应用可以接受的话,方案 1 是可以的,方案 2 是不是每个集群中的表单独有一列设置了不同的默认值,这样只是会多存 1 列的值,专门用来区分集群,也可以

应用肯定希望数据库把所有事情都干了,应用只负责增删改查逻辑。。。

那如果是方案2的话就是 DBA 来维护这个字段了