Firebird 2.5“DEFINE GENERATOR failed”似乎是由于达到数据库生成器限制,但实际数量远未达到该限制

Firebird 2.5 ‘DEFINE GENERATOR failed’ seemingly due to reaching database generator limit, but actual amount nowhere near that limit

昨天我使用带有 FlameRobin 的 Firebird 2.5 和 运行 解决了一个 st运行ge 问题,当时我使用以下 SQL 创建一个简单的序列/生成器:

CREATE GENERATOR MY_GEN_NAME_HERE;

这给出了以下错误消息:

Error: *** IBPP::SQLException ***
Context: Statement::Execute( CREATE GENERATOR MY_GEN_NAME_HERE)
Message: isc_dsql_execute2 failed

SQL Message : -607
This operation is not defined for system tables.

Engine Code    : 335544351
Engine Message :
unsuccessful metadata update
DEFINE GENERATOR failed
arithmetic exception, numeric overflow, or string truncation
numeric value is out of range
At trigger 'RDB$TRIGGER_6'

根据 Firebird FAQ this means that the maximum number of generators in the database has been reached. The database only contains ~250 actual generators however, and according to the manual 应该有 32767 个可用。

常见问题解答建议备份和恢复可以解决问题,这确实有效,但理想情况下,我想了解发生这种情况的原因,以便下次我可以防止它发生。

我知道即使生成器创建失败也会增加计数器,所以我相信这一定是问题所在。极不可能是“手动”生成器创建语句失败,因为数据库尚未投入生产使用,而且只有我们两个人使用它进行开发。因此,我认为它一定是试图以编程方式创建生成器,尽管据我所知,我们编写的任何内容都不应该这样做。我不能排除我们正在使用数据库的行业 ERP 系统,我们已经向供应商提出了这个问题,但如果是那样的话我会感到非常惊讶。

有没有人运行以前遇到过这个问题,还有什么可以影响发电机计数器的吗?

序列(生成器)在生成器数据页上有一个 'slot' 存储其当前值。这个插槽编号 (RDB$GENERATOR_ID) 在创建生成器时分配(使用内部序列)。

当您删除一个序列时,插槽编号只会增加,直到分配了最大数量的插槽(并且可能删除)。

在 Firebird 2.1 及更早版本中,这将是结束:创建(和删除)32757 个序列意味着您无法再创建序列。因此,如果您的应用程序正在创建(和丢弃)大量序列,即使您只有 250 个 'live' 个序列,您最终也会 运行 超出插槽。

回收这些插槽的唯一方法是备份和恢复数据库。在恢复期间,将重新创建序列(使用备份中的起始值)并分配一个新槽。这些插槽将连续分配,因此之前存在的间隙消失,然后您将有可用的未分配插槽。

但是,Firebird 2.5 已将此更改为 CORE-1544,Firebird 现在将自动回收未使用的插槽。此更改仅适用于 ODS 11.2 或更高版本的数据库(ODS = On-Disk Structure)。 ODS 11.2 是使用 Firebird 2.5 创建的数据库的磁盘结构。

如果您遇到此错误,那么您的数据库可能(曾经)仍然是 ODS 11.1(Firebird 2.1 磁盘结构)或更早版本。 Firebird 2.5 可以读取早期的磁盘结构。升级数据库的ODS就是备份和恢复数据库。鉴于你已经这样做了,我假设你的数据库现在是 ODS 11.2,并且错误应该不再发生(除非你的数据库中实际上有 32767 个序列)。