社区版OceanBase4.2.2.1中 主键表出现 当前自增序列的值比表里最大的值还小

【 使用环境 】生产环境 or 测试环境
【 OB or 其他组件 】社区版OceanBase4.2.2.1
【 使用版本 】4.2.2.1
【问题描述】一张主键表,auto_increment设置的是 1005748。select max(id) 查看 当前表的最大值竟然是 1005752,这是什么情况,会造成主键冲突吗。
【复现路径】问题出现前后相关操作
【附件及日志】推荐使用OceanBase敏捷诊断工具obdiag收集诊断信息,详情参见链接(右键跳转查看):

【SOP系列 22 】——故障诊断第一步(自助诊断和诊断信息收集)

【备注】基于 LLM 和开源文档 RAG 的论坛小助手已开放测试,在发帖时输入 [@论坛小助手] 即可召唤小助手,欢迎试用!

2 个赞

在您的问题中提到的情况,即主键表的当前自增序列值大于表中最大值,通常不会直接导致主键冲突。这是因为自增列的设计是为了确保每次插入新记录时都能生成一个新的唯一值。然而,如果自增序列值被手动设置或由于某些异常情况(如您提到的“跳变”现象)导致超过了表中的最大值,后续的插入操作可能会因为尝试插入已存在的主键值而失败,从而引发主键冲突。

为了更好地诊断这个问题,我建议您使用 obdiag 工具来收集相关日志,以便我们能够更准确地定位问题的原因。

日志采集场景: 集群基础信息
日志采集命令: obdiag gather scene run --scene=observer.base

此外,为了进一步了解您的问题,请您提供以下信息:

  1. 您是否手动调整过自增列的值?
  2. 表结构定义是什么样的?特别是关于主键和自增列的部分。
  3. 您是否有遇到具体的错误信息或错误代码?
  4. 您是否观察到了自增列值的“跳变”现象?如果有,请描述一下具体情况。
  5. 您是否进行了可能导致自增列值“跳变”的操作,例如切主、合并等?

通过上述信息,我们可以更准确地分析问题并提供解决方案。

详情请参考:

  1. 主键表和无主键表
  2. OBKV-Table Java 客户端支持的接口
  3. Schema 规范

附上敏捷诊断工具 obdiag 使用帮助链接

2 个赞

auto_increment这个值 是你设置的么?你是通过show create table table_name 查看的auto_increment的值么?

2 个赞

建表的时候初始值是1,昨天跳变了

2 个赞

有什么其他操作么?
1、SELECT * FROM oceanbase.DBA_OB_TABLE_LOCATIONS t WHERE t.TABLE_NAME = ‘’;
2、show create table table_name
3、SELECT * FROM oceanbase.DBA_OB_TABLE_LOCATIONS t WHERE t.TABLE_NAME = ‘’;
–根据table_id查询和列名
SELECT * FROM oceanbase.__all_column WHERE table_id = 518990 AND COLUMN_NAME = ‘’;
–根据上面查询的COLUMN_ID查询auto_increment_cache_size
select * from oceanbase.DBA_OB_AUTO_INCREMENT where COLUMN_ID=’’

2 个赞

根据您提供的信息,您的表在创建时自增列的初始值为 1,但在昨天出现了“跳变”现象。这种“跳变”现象在 OceanBase 数据库中是正常的,尤其是在分布式环境中。 [4]

自增列“跳变”现象的原因

  1. 多机多分区生成自增值

    • 在分布式环境中,不同的 OBServer 节点会独立地从内部表申请自增区间。例如,假设 auto_increment_cache_size 的值为 100,当不同节点分别接收到 INSERT 请求时,它们会各自申请不同的自增区间。这会导致自增值在不同节点之间跳跃。 [4]
  2. 主动插入一个大自增值

    • 如果您显式地向自增列插入一个较大的值,系统会放弃当前的缓存区间,并从新的区间开始生成自增值。这会导致自增值跳变。 [4]
  3. 机器重启或宕机

    • 自增列的缓存是一个内存结构,如果 OBServer 节点发生重启或宕机,未使用完的缓存区间不会写回内部表,这会导致未使用的区间不再被使用,从而引起自增值跳变。 [4]

解决方案

  1. 检查自增列的当前值

    • 您可以通过以下 SQL 语句查看自增列的当前值:
      SHOW TABLE STATUS LIKE 'your_table_name';
      
    • 这将显示表的详细信息,包括自增列的当前值。
  2. 手动调整自增列的值

    • 如果您确定当前的自增列值已经出现问题,可以手动调整自增列的值。例如,如果您希望将自增列的值设置为 1005753(即表中最大值加 1),可以执行以下 SQL 语句:
      ALTER TABLE your_table_name AUTO_INCREMENT = 1005753;
      
  3. 监控和日志

    • 使用 obdiag 工具收集相关日志,以便进一步分析问题。您可以使用以下命令:
      obdiag gather scene run --scene=observer.base
      

预防措施

  1. 定期检查自增列的值

    • 定期检查自增列的值,确保其在预期范围内。
  2. 避免手动插入大自增值

    • 尽量避免手动插入大自增值,除非确实需要这样做。
  3. 监控 OBServer 节点的状态

    • 监控 OBServer 节点的状态,确保节点不会频繁重启或宕机。

通过以上方法,您可以更好地管理和预防自增列的“跳变”现象,确保系统的稳定性和数据的一致性。如果您还有其他问题或需要进一步的帮助,请随时联系 OceanBase 的技术支持团队。

检索到的文档如下:

  1. UPDATE
  2. 创建表时表已存在,错误代码 ERROR 1050
  3. 定义列的约束类型
  4. Schema 规范
  5. CREATE TABLE
  6. 用户自定义变量
  7. 插入数据时数据被截断,错误代码 ERROR 1265
  8. 定义自增列
  9. DEFAULT
  10. ALTER DATABASE

(小助手的答复已结束,如未能解决您的问题,请继续提问并等待其他同学的回复,谢谢!)

1 个赞

没有其它操作

1 个赞

这个看一下是什么情况,会不会影响主键冲突

1 个赞

1、SELECT * FROM oceanbase.DBA_OB_TABLE_LOCATIONS t WHERE t.TABLE_NAME = ‘’;
–根据table_id查询和列名
SELECT * FROM oceanbase.__all_column WHERE table_id =’’ AND COLUMN_NAME = ‘’;
–根据上面查询的COLUMN_ID查询auto_increment_cache_size
select * from oceanbase.DBA_OB_AUTO_INCREMENT where COLUMN_ID=’’

–根据上面的信息 查询一下 看看auto_increment_cache_size这个在内存的值是多少 判断一下是否影响
–自增序列突变有多种因素

好的,都是默认值的·,研发人员没有改动,想问一下 当前自增序列的值比表里最大的值还小 这种现象是正常现象吗 ,会不会引起什么问题,不会导致主键冲突。

如果是默认的初始值是这个 那是没有问题的 你可以查看一下 内存的auto_increment_cache_size这个值是多少

楼上让你看看这个auto_increment_cache_size的值 麻烦你查一下

有一千多条记录截取一部分,表里没有auto_increment_cache_size这个字段值,这个不是参数吗



不好意思 稍了一个条件 auto_increment_key和table_id的值一样 你在多加一个条件查一下
麻烦再查一下 下面的两个信息
select * from oceanbase.DBA_OB_AUTO_INCREMENT where auto_increment_key=’’ and COLUMN_ID=’’

show table status like ‘%pri_test1%’;

这个值AUTO_INCREMENT_VALUE包含了auto_increment_cache_size的值


你在同一时间查看这两个信息 show create table的结果和select max(id) from table;

目前开发把auto_increment调整了

好的 后面再看看吧 以show create table的auto_increment这个值为准 如果比max(id)小了 会有问题的

后期如果再出现这个类的问题 你可以开新帖 到时候我们在交流 看看是什么问题导致的

嗯嗯,后续开发要反映这个情况再一起看下,这个现象不解决预生产没法上线