此页面为机器翻译。请阅读英文原文。 English

IBSurgeon 文库

所有 Firebird 和 InterBase 的磁盘结构(ODS)版本

作者:Dmitry Kuzmenko,2016年5月24日

什么是磁盘结构(ODS)编号

简单来说,ODS(On-Disk Structure,磁盘结构)是特定 Firebird 或 InterBase RDBMS 版本的数据库文件格式编号。

几乎所有版本都使用所谓的“Y-valve”来同时支持当前 ODS 和一些旧 ODS。这允许服务器处理来自先前版本的数据库文件,并简化从旧服务器到新服务器的过渡。但存在一些限制,将在后文描述。

你可以通过运行以下命令来查看数据库的 ODS

Code
gstat -h database_file_name

此处不需要用户名和密码,因为带 -h 选项的 gstat 只读取数据库的物理部分(头部页,编号 0)。

如果 gstat 无法理解读取到的信息,它会显示相应的消息——即它期望什么,以及它发现了什么。

例如,如果我们用 InterBase 4 的 gstat 打开一个 Firebird 2 的数据库,它会显示

Code
Wrong ODS version, expected 8, encountered 32779?

这里,你看到 ODS 编号 32779——这是编码后的 11,自 Firebird 2.0 起加上了高位(十六进制为 800B,其中 B = 11),以避免 InterBase 和 Firebird 数据库之间的混淆,因为从某个时候起它们具有相同的 ODS 编号,但数据库格式却非常不同。无法获得可理解消息的例外情况是 gstat 找不到 firebird.msg 或 interbase.msg。它会显示类似

Code
can't format message 21:3 -- message file ...msg not found

所以,这意味着你的 Firebird 或 InterBase 安装不正确,需要修复。

几个示例:

Wrong ODS version, expected 8, encountered 32779? - InterBase 4.x 尝试打开 Firebird 2.x 数据库

Wrong ODS version, expected 8, encountered 13? - InterBase 4.x 尝试打开 InterBase 2009 数据库

Wrong ODS version, expected 15, encountered 32779 - InterBase XE/XE3 尝试打开 Firebird 2.x 数据库

Wrong ODS version, expected 11, encountered 11 - Firebird 2.x 尝试打开 InterBase 7.x 数据库

Wrong ODS version, expected 11, encountered 15- Firebird 2.x 尝试打开 InterBase XE/XE3 数据库

有时你会收到另一种消息,来自服务器(而非 gstat),但含义相同。

例如,当 Firebird 1.5 服务器尝试打开 Firebird 2.x 数据库时:

Code
unsupported on-disk structure for file ...; found 32779, support 10

这里你可以看到自 InterBase 4.0(1994 年)以来的 ODS 版本表。

服务器版本 主 ODS 编号 可处理的 ODS 备注
InterBase 4.0/4.1 8.0
InterBase 4.2 8.2 8.2 InterBase 4.2 强制将 ODS 8.0 升级到 8.2
InterBase 5.0/5.1 9.0 8.2 InterBase 5.x 强制将 ODS 8.0 升级到 8.2
InterBase 5.5/5.6 9.1 8.2
InterBase 6.0
Firebird 1.0
Yaffil 1.0
10.0 9.0/9.1 使用 ODS 9.x 是危险的,因为新的 InterBase 和 Firebird 使用新的元数据格式,InterBase 5.x 无法识别
Firebird 1.5 10.1 9.0/9.1/10.0 64 位 Firebird 1.5 的 ODS 10.1 与 32 位 ODS 10.1 不兼容。这是已知的唯一一个 32/64 位版本之间数据库格式不兼容的情况。
InterBase 7.0 11.0 10.0 与 Firebird 2.x 的 ODS 11 不兼容
InterBase 7.1 11.1 10.0 InterBase 7.5 会将 InterBase ODS 11.0/11.1 升级到 11.2,这对先前版本(7.0/7.1)不兼容
InterBase 7.5 11.2 10.0
Firebird 2.0 11.0 10.x Firebird 2.0 的 ODS 11 与 InterBase 7.x 不兼容
Firebird 2.1 11.1 10.x/11.0 Firebird 2.0 的 ODS 11 与 InterBase 7.x 不兼容
Firebird 2.5 11.2 10.x/11.x ODS 11.2 与 Firebird 2.0/2.1 不兼容。
Firebird 3.0 12.0 不支持先前的 ODS,仅支持 12.0
Firebird 4.0 13.0 13.0
Firebird 5.0 13.1 13.0, 13.1 数据库可以从 13.0 升级到 13.1,使用 13.0 的 gfix -upgrade,或通过备份/恢复
InterBase 2007 12.0 11.x
InterBase 2009 13.1 12.0
InterBase XE, XE3 15.0 13.1 ODS 14 在哪里?
InterBase XE7 16.0 15, 13 可以在 IBCONFIG 中设置“当前”ODS。这样 XE7 将默认使用指定的 ODS(13、15、16)创建数据库(包括恢复)。

ODS 升级

每个版本的服务器(InterBase XE7 除外)在创建或恢复数据库时总是使用其主 ODS 编号。如果数据库的 ODS 小于服务器的主 ODS,服务器可以在支持该 ODS 的情况下处理该数据库。

有时服务器可能会在不通知的情况下将旧 ODS 升级到某个较新的 ODS。这可能导致无法回退到先前的版本。例如,如果你用 InterBase 4.2 打开一个 ODS 8.0 的数据库,它会将 ODS 升级到 8.2,而 InterBase 4.0/4.1 无法理解该版本。因此,ODS 的次要升级会导致同一主服务器版本内的数据库不兼容。这对 Firebird 2.5 和 InterBase 7.5 同样适用。

为避免回退版本时出现问题,我们建议即使在服务器版本次要升级之前,也在当前服务器版本上进行备份。

ODS(主要或次要)之间的差异可能很大,也可能很小。如果你足够好奇,可以打开 jrd\ods.h(Firebird 开源)并找出 ODS 之间的差异。例如,与 8.x 相比,ODS 9.0 具有声明式引用完整性、SQL 角色、索引中的垃圾回收。但 ODS 9.1 与 9.0 的区别仅在于某个系统表中添加了一个索引。

请注意,主要 ODS 版本无法即时升级。你只能通过备份/恢复来升级它。

在 InterBase 和 Firebird 之间迁移

最新版本的 Firebird(3.0)和 InterBase(XE7)在功能和 ODS 上都非常不同。如前所述,最后一个共同的 ODS 是 10,自此之后(Firebird 2.0 和 InterBase 7.0)数据库格式便不兼容。

因此,如果你没有使用 InterBase 7.x 或 Firebird 1.5 之后的功能,迁移会更容易。如果是,迁移的复杂性将取决于你在数据库或管理过程中使用了多少功能。

目前,经过 Firebird 和 InterBase 多年的发展,在这些服务器最新版本之间进行迁移是困难的。

无论如何,如果你尝试这样做,你需要从数据库中提取元数据脚本,然后尝试使用相同的服务器从该脚本创建新数据库。

Code
isql -x db.gdb …
isql -i script.ddl …

这样做是为了检查你的数据库中是否存在不良的旧元数据,或者你所使用的服务器中脚本提取是否存在缺陷。InterBase 和 Firebird 以编译形式(BLR - 二进制语言表示)存储存储过程、触发器、视图(以及其他一些对象),在备份/恢复期间元数据不会被重新编译(从 SQL 到 BLR)。

在这种情况下,如果数据库是很久以前创建的并且不断被修改,某些对象可能存在不正确的(旧的)BLR。这些对象仍然可以工作,但尝试重新创建它们(ALTER)可能会引发语法(或其他)错误。

然后你可以尝试在新服务器上从修正后的脚本创建数据库。在修复此脚本中的所有不兼容性后,你可以将数据从旧数据库泵送到新数据库。

即使你尝试在旧服务器上备份并在新服务器上恢复,并且成功了——也永远不要相信这一点。如果你的数据库包含大量对象,你无法在新服务器上一次性检查所有对象,因此错误会在稍后出现。

如何回退到先前版本的 Firebird 或 InterBase

有时,你可能需要执行降级并从新服务器回退。原因可能各不相同——服务器突然出现 bug、性能问题等等。

如果你在服务器升级之前做了备份,回退不会有问题。但如果没有,你将面临从新 ODS 回退到旧 ODS 的问题。

要做到这一点,你需要两台计算机,分别装有新服务器和旧服务器。如果你没有使用服务器 X(InterBase 或 Firebird 的版本)的任何新功能,那么你可以按照以下步骤回退到 X-1:

  1. 从服务器 X-1 获取 gbak 实用程序,并在服务器 X 上使用它进行备份
  2. 将备份传输到 X-1 服务器,并进行还原

如果在第 1 步遇到问题,您可以尝试

  1. 在服务器 X 上使用其 gbak 进行备份
  2. 将 gbak 实用程序从 X 复制到 X-1
  3. 在 X-1 上使用来自 X 的 gbak 还原备份

请注意,服务器 X 和 X-1 之间的本地协议可能不兼容,因此最好指定服务器名称:

Code
gbak -b localhost:c:\dir\data.gdb

只有在自 X-1 升级以来您未更改服务器 X 上任何数据库对象的条件下,结果才会成功。

以下是一些示例:

  • 从 5.x 到 4.2 - 不得使用角色和新的声明式引用完整性
  • 从 6.x 到 5.x - 无元数据更改,因为 6.x 使用新的 BLR 格式
  • 从 InterBase 7.x 到 Firebird - 不得有布尔列和超过 31 个字符的对象名称。
  • 从 Firebird 1.5 到 InterBase - 不得有 BIGINT 列以及触发器和存储过程中的新 SQL 扩展
  • 从 Firebird 2.0 到 Firebird 1.5 - 不得使用任何新的 Firebird 2.0 功能。
  • 以此类推

如果仍然存在无法修复的错误,唯一的方法是在 X-1 服务器上从 SQL 脚本创建数据库并导入数据。

Firebird 迁移服务

迁移通常是一项复杂的任务,尤其是对于被原始开发者放弃的遗留 Firebird 数据库。我们公司为复杂的 Firebird 数据库提供全面的迁移服务。常规费用为 2900 美元。

例如,我们曾在不到 3 个月的时间内完成了一个数据库的迁移,其 SQL 脚本为 55 兆字节,包含 5000 多个存储过程、1000 张表以及数千条临时 SQL 查询。

如果您有任何问题,请联系我们 [email protected]