数据库中的跳号问题真的需要管理吗?

devtools/2024/9/24 14:21:30/

数据库中,我们经常为对象或记录赋予一个顺序增长的序号作为标记,序列就是实现数据库功能的特性之一。有了顺序号就有了一类烦恼:如何防止跳号?

最近,在Oracle 23ai 版本中测试时,通过一个报错遭遇到Oracle为解决跳号问题引入和内部特性。

outside_default.png

如下,在删除用户时遇到 ORA-01653 错误,不能扩展空间,引发空间扩展的对象是 OBJNUM_REUSE 。这是当删除对象时,数据库在 OBJNUM_REUSE 中增加记录,因空间不足而报错:

SQL> drop user c##eygle cascade;
drop user c##eygle cascade
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-01653: unable to extend table SYS.OBJNUM_REUSE by 128 in tablespace SYSTEM

此时数据库中共记录了15万个可以重用的对象号:

SQL> select count(*) from OBJNUM_REUSE;COUNT(*)
----------154500

问题原因很清楚,就是在删除用户时,触发了数据库的后台内部任务,级联引发空间扩展问题,从而出现了 ORA-01653 错误。

但是 SYS.OBJNUM_REUSE 是一个什么对象呢?

这是从Oracle 19c开始,增加的一个“对象号重用“的新特性,从而引入的数据库对象,objnum_reuse 是一个系统表,包含2个字段(记录了对象号和时间),还伴随创建了2个索引:

create table objnum_reuse (obj# number not null,ins_date date)
/
create unique index i_objnum_reuse1 on objnum_reuse(obj#)
/
create index i_objnum_reuse2 on objnum_reuse(ins_date, obj#)
/

为什么要重用对象号呢?

这是因为在Oracle RDBMS中有一些内部强加的限制,例如对象号在rowid中被引用(对象号占32bit),数据库中的对象号最多可以分配 4G 个。

outside_default.png

此限制会影响可以创建的对象数、可以对这些对象执行的DDL操作数以及可以创建的轻量级作业数。达到这个限制是灾难性的——数据库基本上变得不可用,因为无法创建新对象,无法在对象上运行DDL,也无法运行轻量级作业。如果数据库关闭,则可能无法重新打开。

对于极其繁忙的数据库、经常反复创建对象的数据库,就可能用完对象号。

在大约10年前,我遇到过一个案例,在SAP的系统中,由于大量的临时计算会频繁的创建和删除对象,导致对象号快速增长,在后续的DBMS_STATS任务调度上出现了问题。

outside_default.png

这是一个非常早期的数据库版本,叠加一些内部限制和序号保留,可用的用户对象号达不到理论数量。保留了当时的查询记录:

SQL> select count(0) from dba_objects where object_id > power(2,31);COUNT(0)
----------1174755

手工执行相关操作,都会遇到数值溢出的错误(还可能遇到ORA-600 [kkdlron-max-objid] 或 ORA-600 [15260]错误):

SQL> BEGIN
2  DBMS_AQADM.DROP_QUEUE_TABLE('Q_TABLE');
3  END;
4  /
BEGIN
*
ERROR at line 1:
ORA-01426: numeric overflow
ORA-06512: at "SYS.DBMS_AQADM_SYS", line 4310
ORA-06512: at "SYS.DBMS_AQADM", line 197
ORA-06512: at line 2

为了应对对象号浪费问题,现在Oracle 实现了自动的对象标识符回收方法,将丢弃对象的回收对象编号缓存在新的内部表中。当系统对象标识符达到用尽状态时,数据库会无缝地切换到使用缓存的值。还提供了一个存储过程,用于手动收集废弃的对象号填充内部表。

对象号重用,除了引入了以上描述的表和索引外,还包括:引入初始化隐含参数“_reuse_object_numbers”。

当此参数设置为“0”时,对象标识符回收将关闭。若要激活回收功能,需要将其设置为“5”(不应设置为任何其他值)。此参数在19c中默认为“0”,但在23ai中,它默认为“5”。

一旦激活,任何丢弃的对象(包括在安装和/或激活补丁之前创建的对象)的对象编号都将被回收。请注意,在这种情况下“已删除”意味着标识符已从SYS数据字典中删除,回收站中的项目并非如此(回收站中项目的编号需要Purge后才能回收)。

针对这个特性,还引入了存储过程 OBJNUM_REUSE_HOLES。数据库中增加了一个名为OBJNUM_REUSE_HOLES的新过程。此程序可用于手动填充SYS.OBJNUM_REUSE表,其中包含通过扫描SYS获得的对象标识符。OBJ$表中未使用的标识符或序列中当前未使用的“孔”。

PL/SQL过程已成功完成。
SQL>exec objnum_reuse_holes(100000)

注意,对于23ai之前的版本,必须显式激活特性。在数据库完全用完对象编号之前,可以随时设置“_reuse_object_numbers”参数。

当该特性被激活时,对象标识符重用实际上不会生效,直到常规限制用完为止。但是,一旦设置了“_reuse_object_numbers”=5,就会开始捕获丢弃的对象编号。

当达到对象标识符的最大限制并启用此特性时,系统将自动切换到从SYS表中获取对象标识符。OBJNUM_REUSE无缝连接,不会对应用程序造成任何中断或任何可见差异。

outside_default.png

Oracle的跳号治理,你觉得如何


云和恩墨大讲堂 | 一个分享交流的地方 

长按,识别二维码,加入万人交流社群

请备注:云和恩墨大讲堂

  点个“在看” 

你的喜欢会被看到❤


http://www.ppmy.cn/devtools/96703.html

相关文章

实战OpenCV之图像的属性

基础入门 图像的属性指的是描述图像基本信息的数据,包括但不限于:图像的尺寸、颜色通道数、像素数据类型等。这些属性对于图像处理非常重要,因为它们直接关系到如何正确地读取、处理和存储图像。常见的图像属性包括: 尺寸&#xf…

大语言模型微调框架Unsloth:简化模型微调流程,提升模型性能

Unsloth 将 Llama-3、Mistral、Phi-3 和 Gemma 等大型语言模型的微调速度提高了 2 倍,内存使用量减少了 70%,而且准确性不会降低! 特点 通过手动派生所有计算繁重的数学步骤和手写 GPU 内核,unsloth 可以在不更改任何硬件的情况…

【查看各个组件的版本信】

文章目录 MariaDBElasticsearchHadoopClickhouseKafkaZookeeperRedisLogstashFlinkSparkJDKPythonNacos 查看各个组件的版本信息通常可以通过命令行工具或 Web 界面来实现。以下是查看这些组件版本的常用方法: MariaDB mariadb --version或 mysql --versionElasti…

Echarts tooltip内容自定义背景透明

记录Echarts图表 tooltip内容自定义背景透明色 //提示框tooltip: {axisPointer: {type: "line", // 指示器类型(line 直线指示器;shadow 阴影指示器;none 无指示器;cross 十字准星指示器。)snap: false, // …

clickhouse集群+Zk优化-解决只读模式,主节点磁盘增长快

问题1:数据库进入只读模式 最近在项目中使用clickhouse的时候,遇到了一个批量插入后报错的问题。报错的内容是数据库进入了只读模式,导致数据写不进去。发现有大量的批量写入报错日志信息。(关键异常信息:DB::Exceptio…

Elasticsearch拼音分词器的安装、配置与测试实践

Elasticsearch的分词器对于文本分析至关重要。对于中文等语言,合适的分词器可以显著提高搜索相关性和结果的准确性。拼音分词器不仅支持基于拼音的搜索,还能实现拼音自动补全等功能。本文将介绍如何在Elasticsearch中安装拼音分词器,以及如何…

Flask框架探索:轻量级与灵活性的完美结合

在Web开发领域,框架的选择往往决定了项目的效率与可扩展性。在众多Python Web框架中,Flask以其轻量级和高度可定制性脱颖而出,成为许多开发者的首选。本文将基于《Flask框架》文档,深入解析Flask的特点、优势及其在Web开发中的应用…

复习之 java 锁

裁员在家,没有面试机会,整理整理面试知识点吧! 不得不知道的java 锁 Java 中,提供了两种方式来实现同步互斥访问(也就是锁):synchronized 和 Lock 多线程编程中,有可能会出现多个线…