所有 Firebird 和 InterBase 的磁盘结构(ODS)版本
作者:Dmitry Kuzmenko,2016年5月24日
什么是磁盘结构(ODS)编号
简单来说,ODS(On-Disk Structure,磁盘结构)是特定 Firebird 或 InterBase RDBMS 版本的数据库文件格式编号。
几乎所有版本都使用所谓的“Y-valve”来同时支持当前 ODS 和一些旧 ODS。这允许服务器处理来自先前版本的数据库文件,并简化从旧服务器到新服务器的过渡。但存在一些限制,将在后文描述。
你可以通过运行以下命令来查看数据库的 ODS
gstat -h database_file_name
此处不需要用户名和密码,因为带 -h 选项的 gstat 只读取数据库的物理部分(头部页,编号 0)。
如果 gstat 无法理解读取到的信息,它会显示相应的消息——即它期望什么,以及它发现了什么。
例如,如果我们用 InterBase 4 的 gstat 打开一个 Firebird 2 的数据库,它会显示
Wrong ODS version, expected 8, encountered 32779?
这里,你看到 ODS 编号 32779——这是编码后的 11,自 Firebird 2.0 起加上了高位(十六进制为 800B,其中 B = 11),以避免 InterBase 和 Firebird 数据库之间的混淆,因为从某个时候起它们具有相同的 ODS 编号,但数据库格式却非常不同。无法获得可理解消息的例外情况是 gstat 找不到 firebird.msg 或 interbase.msg。它会显示类似
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 数据库时:
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 多年的发展,在这些服务器最新版本之间进行迁移是困难的。
无论如何,如果你尝试这样做,你需要从数据库中提取元数据脚本,然后尝试使用相同的服务器从该脚本创建新数据库。
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:
- 从服务器 X-1 获取 gbak 实用程序,并在服务器 X 上使用它进行备份
- 将备份传输到 X-1 服务器,并进行还原
如果在第 1 步遇到问题,您可以尝试
- 在服务器 X 上使用其 gbak 进行备份
- 将 gbak 实用程序从 X 复制到 X-1
- 在 X-1 上使用来自 X 的 gbak 还原备份
请注意,服务器 X 和 X-1 之间的本地协议可能不兼容,因此最好指定服务器名称:
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]